Data fetching & action typing
Fetch data on the server with typed JSON, control caching/revalidation, and create typed Server Actions for forms and mutations.
Data fetching & action typing is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Intro
Goal: Fetch data in server components with typed JSON, configure cache/revalidate, and build typed Server Actions for mutations.
- Typed fetch helpers
- Cache: revalidate vs no-store
- Server Actions with forms
Typed fetch helper
Create a small json<T> helper to decode responses and throw on non-200. Use revalidate for ISR-like caching.
// app/lib/http.ts
export async function json<T>(res: Response): Promise<T> {
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return (await res.json()) as T
}
// app/page.tsx (server)
export type Post = { id: number; title: string }
export default async function Page() {
const res = await fetch("https://example.com/api/posts", { next: { revalidate: 60 } })
const posts = await json<Post[]>(res)
return (
<main style={{ display: "grid", gap: 8 }}>
<h1>Posts</h1>
<ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
</main>
)
}Cache controls
Use cache: "no-store" for fully dynamic requests; or next.revalidate to regenerate after N seconds.
// app/page.tsx (server)
export default async function Page() {
const res = await fetch("https://example.com/api/now", { cache: "no-store" })
const data = await res.json() as { now: string }
return <pre>{JSON.stringify(data, null, 2)}</pre>
}
// Alternative: revalidate per request
// fetch(url, { next: { revalidate: 5 } })Server Action module
Add "use server" in the module (or inside the function). Server Actions run on the server and can call server-only APIs, then revalidatePath.
// app/actions.ts
"use server"
import { revalidatePath } from "next/cache"
export async function createPost(form: FormData): Promise<{ id: string }> {
const title = String(form.get("title") || "")
if (!title) throw new Error("title required")
// pretend DB insert
const id = Math.random().toString(36).slice(2)
revalidatePath("/")
return { id }
}Client form using action
Bind the Server Action to a form action. Use useTransition to show pending UI. Types flow from the action signature.
"use client"
import { useTransition } from "react"
import { createPost } from "../actions"
export default function NewPost() {
const [pending, start] = useTransition()
const onSubmit = async (formData: FormData) => {
await createPost(formData)
}
return (
<form action={(fd) => start(() => onSubmit(fd))} style={{ display: "grid", gap: 8 }}>
<input name="title" placeholder="Title" />
<button disabled={pending}>{pending ? "Creating…" : "Create"}</button>
</form>
)
}Tips & safety
Tips:
- Prefer server fetching for secrets; pass results as props.
- Throw typed Errors from actions; handle in UI with boundaries.
- Revalidate affected paths after mutations.
Server Action typing check
Quick check: How do you mark a function as a Server Action and keep types?
Recap
Recap: Decode JSON with a typed helper, choose no-store or revalidate wisely, and use typed Server Actions to mutate and revalidate safely.
Frequently asked questions
Is the “Data fetching & action typing” lesson free?
Yes — the full text of “Data fetching & action typing” is free to read here on the web, and the TypeScript Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Data fetching & action typing”?
Fetch data on the server with typed JSON, control caching/revalidation, and create typed Server Actions for forms and mutations. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Data fetching & action typing” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- App Router types; server vs client components
- Data fetching & action typing
- Env typing and config