@@ -8,15 +8,15 @@ title: Server Functions
88Server functions let you define server-only logic that can be called from anywhere in your application - loaders, components, hooks, or other server functions. They run on the server but can be invoked from client code seamlessly.
99
1010``` tsx
11- import { createServerFn } from " @tanstack/react-start" ;
11+ import { createServerFn } from ' @tanstack/react-start'
1212
1313export const getServerTime = createServerFn ().handler (async () => {
1414 // This runs only on the server
15- return new Date ().toISOString ();
16- });
15+ return new Date ().toISOString ()
16+ })
1717
1818// Call from anywhere - components, loaders, hooks, etc.
19- const time = await getServerTime ();
19+ const time = await getServerTime ()
2020```
2121
2222Server functions provide server capabilities (database access, environment variables, file system) while maintaining type safety across the network boundary.
@@ -26,18 +26,18 @@ Server functions provide server capabilities (database access, environment varia
2626Server functions are created with ` createServerFn() ` and can specify HTTP method:
2727
2828``` tsx
29- import { createServerFn } from " @tanstack/react-start" ;
29+ import { createServerFn } from ' @tanstack/react-start'
3030
3131// GET request (default)
3232export const getData = createServerFn ().handler (async () => {
33- return { message: " Hello from server!" };
34- });
33+ return { message: ' Hello from server!' }
34+ })
3535
3636// POST request
37- export const saveData = createServerFn ({ method: " POST" }).handler (async () => {
37+ export const saveData = createServerFn ({ method: ' POST' }).handler (async () => {
3838 // Server-only logic
39- return { success: true };
40- });
39+ return { success: true }
40+ })
4141```
4242
4343## Where to Call Server Functions
@@ -51,18 +51,18 @@ Call server functions from:
5151
5252``` tsx
5353// In a route loader
54- export const Route = createFileRoute (" /posts" )({
54+ export const Route = createFileRoute (' /posts' )({
5555 loader : () => getPosts (),
56- });
56+ })
5757
5858// In a component
5959function PostList() {
60- const getPosts = useServerFn (getServerPosts );
60+ const getPosts = useServerFn (getServerPosts )
6161
6262 const { data } = useQuery ({
63- queryKey: [" posts" ],
63+ queryKey: [' posts' ],
6464 queryFn : () => getPosts (),
65- });
65+ })
6666}
6767```
6868
@@ -73,58 +73,58 @@ Server functions accept a single `data` parameter. Since they cross the network
7373### Basic Parameters
7474
7575``` tsx
76- import { createServerFn } from " @tanstack/react-start" ;
76+ import { createServerFn } from ' @tanstack/react-start'
7777
78- export const greetUser = createServerFn ({ method: " GET" })
78+ export const greetUser = createServerFn ({ method: ' GET' })
7979 .inputValidator ((data : { name: string }) => data )
8080 .handler (async ({ data }) => {
81- return ` Hello, ${data .name }! ` ;
82- });
81+ return ` Hello, ${data .name }! `
82+ })
8383
84- await greetUser ({ data: { name: " John" } });
84+ await greetUser ({ data: { name: ' John' } })
8585```
8686
8787### Validation with Zod
8888
8989For robust validation, use schema libraries like Zod:
9090
9191``` tsx
92- import { createServerFn } from " @tanstack/react-start" ;
93- import { z } from " zod" ;
92+ import { createServerFn } from ' @tanstack/react-start'
93+ import { z } from ' zod'
9494
9595const UserSchema = z .object ({
9696 name: z .string ().min (1 ),
9797 age: z .number ().min (0 ),
98- });
98+ })
9999
100- export const createUser = createServerFn ({ method: " POST" })
100+ export const createUser = createServerFn ({ method: ' POST' })
101101 .inputValidator (UserSchema )
102102 .handler (async ({ data }) => {
103103 // data is fully typed and validated
104- return ` Created user: ${data .name }, age ${data .age } ` ;
105- });
104+ return ` Created user: ${data .name }, age ${data .age } `
105+ })
106106```
107107
108108### Form Data
109109
110110Handle form submissions with FormData:
111111
112112``` tsx
113- export const submitForm = createServerFn ({ method: " POST" })
113+ export const submitForm = createServerFn ({ method: ' POST' })
114114 .inputValidator ((data ) => {
115115 if (! (data instanceof FormData )) {
116- throw new Error (" Expected FormData" );
116+ throw new Error (' Expected FormData' )
117117 }
118118
119119 return {
120- name: data .get (" name" )?.toString () || " " ,
121- email: data .get (" email" )?.toString () || " " ,
122- };
120+ name: data .get (' name' )?.toString () || ' ' ,
121+ email: data .get (' email' )?.toString () || ' ' ,
122+ }
123123 })
124124 .handler (async ({ data }) => {
125125 // Process form data
126- return { success: true };
127- });
126+ return { success: true }
127+ })
128128```
129129
130130## Error Handling & Redirects
@@ -134,20 +134,20 @@ Server functions can throw errors, redirects, and not-found responses that are h
134134### Basic Errors
135135
136136``` tsx
137- import { createServerFn } from " @tanstack/react-start" ;
137+ import { createServerFn } from ' @tanstack/react-start'
138138
139139export const riskyFunction = createServerFn ().handler (async () => {
140140 if (Math .random () > 0.5 ) {
141- throw new Error (" Something went wrong!" );
141+ throw new Error (' Something went wrong!' )
142142 }
143- return { success: true };
144- });
143+ return { success: true }
144+ })
145145
146146// Errors are serialized to the client
147147try {
148- await riskyFunction ();
148+ await riskyFunction ()
149149} catch (error ) {
150- console .log (error .message ); // "Something went wrong!"
150+ console .log (error .message ) // "Something went wrong!"
151151}
152152```
153153
@@ -156,39 +156,39 @@ try {
156156Use redirects for authentication, navigation, etc:
157157
158158``` tsx
159- import { createServerFn } from " @tanstack/react-start" ;
160- import { redirect } from " @tanstack/react-router" ;
159+ import { createServerFn } from ' @tanstack/react-start'
160+ import { redirect } from ' @tanstack/react-router'
161161
162162export const requireAuth = createServerFn ().handler (async () => {
163- const user = await getCurrentUser ();
163+ const user = await getCurrentUser ()
164164
165165 if (! user ) {
166- throw redirect ({ to: " /login" });
166+ throw redirect ({ to: ' /login' })
167167 }
168168
169- return user ;
170- });
169+ return user
170+ })
171171```
172172
173173### Not Found
174174
175175Throw not-found errors for missing resources:
176176
177177``` tsx
178- import { createServerFn } from " @tanstack/react-start" ;
179- import { notFound } from " @tanstack/react-router" ;
178+ import { createServerFn } from ' @tanstack/react-start'
179+ import { notFound } from ' @tanstack/react-router'
180180
181181export const getPost = createServerFn ()
182182 .inputValidator ((data : { id: string }) => data )
183183 .handler (async ({ data }) => {
184- const post = await db .findPost (data .id );
184+ const post = await db .findPost (data .id )
185185
186186 if (! post ) {
187- throw notFound ();
187+ throw notFound ()
188188 }
189189
190- return post ;
191- });
190+ return post
191+ })
192192```
193193
194194## Advanced Topics
0 commit comments