Server Functions

Server functions

Call server-side functions directly from the browser without writing REST endpoints. Server functions live in src/actions/ and are invoked via fetch.

Defining server functions

Create a file in src/actions/ and export named async functions. Each function receives a Request object and any arguments you pass.

src/actions/greet.ts
export async function greet(name: string) {  return `Hello, ${name}! The server time is ${new Date().toISOString()}.`;}export async function sendEmail({ to, subject, body }: {  to: string;  subject: string;  body: string;}) {  // send email logic  return { sent: true, to };}

Calling from the browser

Server functions are called by sending a POST request to /__x/actions/<filename>/<functionName>. The arguments are sent as JSON in the request body.

client component
"use client";import { useState } from "react";export default function GreetForm() {  const [message, setMessage] = useState("");  async function handleSubmit(e: React.FormEvent) {    e.preventDefault();    const form = new FormData(e.target as HTMLFormElement);    const name = form.get("name");    const res = await fetch("/__x/actions/greet/greet", {      method: "POST",      headers: { "Content-Type": "application/json" },      body: JSON.stringify([name]),    });    const data = await res.text();    setMessage(data);  }  return (    <form onSubmit={handleSubmit} className="space-y-4">      <input        name="name"        placeholder="Enter your name"        className="rounded-xl border border-border bg-card px-4 py-2"      /> >      <button type="submit" className="rounded-xl bg-primary px-4 py-2 text-primary-foreground">        Greet me      </button>      {message && <p className="text-muted-foreground">{message}</p>}    </form>  );}

Server functions from loaders

You can also import and call server functions directly in loaders — no HTTP needed since they share the same process.

src/pages/dashboard.tsx
import type { RouteProps, LoaderArgs } from "@thexjs/core";import { getDashboardData } from "../actions/dashboard";export async function loader({ request }: LoaderArgs) {  const data = await getDashboardData();  return { data };}export default function Dashboard({ loaderData }: RouteProps<typeof loader>) {  return <div>...</div>;}

Use cases

Server functions are ideal for form handling, sending emails, database mutations, and any server-side logic that doesn't need a dedicated REST API. They reduce boilerplate and keep your client code simple.