Next.js App Router Basics

App Router (Next 13+) replaces the old `pages/` directory. Routing + layouts + data fetching all live in `app/` using React Server Components.

1 credit

File conventions (inside app/)

7 items
page.tsx
UI for a route — `/about/page.tsx` → `/about`
layout.tsx
Persistent wrapper for children; nested layouts compose
loading.tsx
React Suspense fallback for the segment
error.tsx
Error boundary (client component)
not-found.tsx
Rendered on `notFound()` or unmatched route
route.ts
API endpoint (GET/POST handlers) — app router's equivalent of `pages/api/*`
[slug]/page.tsx
Dynamic segment — params reach the component via props

Server vs client components

  • Server by default — can `await` DB, read env, use `fs`. Can't use `useState`, events, or browser APIs.
  • Mark client components with `"use client"` at the top — needed for interactivity, hooks, event handlers.
  • Server can import client; client can't import server. Pass data server→client as props.

Data fetching

tsx
// Server component — fetch runs on the server, zero client JS
export default async function Page() {
  const data = await fetch("https://api.example.com", {
    next: { revalidate: 60 },  // ISR: cache 60s
  }).then(r => r.json());
  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

Common snags

  • `NEXT_PUBLIC_*` vars are inlined at build time. Changing them after build = no effect until rebuild.
  • Server components can't use `window` / `document` / hooks. Move interactive bits into a `"use client"` child.
  • Don't `import` from server files into client files — breaks at build with a confusing error.
  • `metadata` export on a page gives you static meta tags; `generateMetadata` for dynamic.

Further reading