import { createFileRoute, useRouter } from "@tanstack/react-router"; import { createServerFn } from "@tanstack/react-start"; import { env } from "cloudflare:workers"; import { useCallback, useState } from "react"; const key = "todos.json"; async function readTodos(): Promise<{ id: number; name: string }[]> { const todos = await env.R2.get(key); return ( (await todos?.json()) ?? [ { id: 1, name: "Get groceries" }, { id: 2, name: "Buy a new phone" }, ] ); } const getTodos = createServerFn({ method: "GET", }).handler(async () => await readTodos()); const addTodo = createServerFn({ method: "POST" }) .inputValidator((d: string) => d) .handler(async ({ data }) => { const todos = await readTodos(); todos.push({ id: todos.length + 1, name: data }); await env.R2.put(key, JSON.stringify(todos, null, 2)); return todos; }); export const Route = createFileRoute("/demo/start/server-funcs")({ component: Home, loader: async () => await getTodos(), }); function Home() { const router = useRouter(); let todos = Route.useLoaderData(); const [todo, setTodo] = useState(""); const submitTodo = useCallback(async () => { todos = await addTodo({ data: todo }); setTodo(""); router.invalidate(); }, [addTodo, todo]); return (

Start Server Functions - Todo Example

setTodo(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") { submitTodo(); } }} placeholder="Enter a new todo..." className="w-full px-4 py-3 rounded-lg border border-white/20 bg-white/10 backdrop-blur-sm text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" />
); }