Episode 2 — React Frontend Architecture NextJS / 2.18 — Getting Started with NextJS
2.18 — Exercise Questions: Getting Started with Next.js
A. Scaffold & tooling (2.18.c)
- Run
create-next-appwith TypeScript and ESLint; delete demo content; commit a cleanmainwith README describing scripts. - Add
.nvmrc(orenginesinpackage.json) matching your CI Node version. - Add
npm run typecheckif not present (tsc --noEmit) and wire it in CI.
B. Routing (2.18.d)
- Create
app/(site)/page.tsxandapp/(site)/pricing/page.tsx; confirm URLs have no(site)segment. - Add
app/items/[id]/page.tsx; log resolvedid; returnnotFound()whenidfails a Zod UUID parse. - Add
middleware.tsthat redirects/old→/newwith a 307. - Add
app/docs/[[...slug]]/page.tsxand verify both/docsand/docs/a/bresolve; log theslugarray.
C. Layouts & metadata (2.18.e)
- Create
app/dashboard/layout.tsxwith a sidebar; adddashboard/invoices/page.tsxanddashboard/settings/page.tsx; verify sidebar persists on client navigation via<Link>. - Add
app/dashboard/template.tsxwith auseEffectmount logger; compare logs vs layout-only behavior. - Move shared metadata to
app/layout.tsxusingexport const metadata; override title in one child page usingexport const metadataorgenerateMetadata(pick one pattern and justify).
D. Framework vs “why Next” reflection (2.18.a, 2.18.b)
- In five bullet points, explain why a startup might still pick plain Vite + React instead of Next for their first web app.
- Write a one-page ADR: “App Router vs Pages Router for this repo” with decision, consequences, and review date.
Answers & guidance (self-check)
1–3. Scaffold & tooling
- 1: You should have
package.jsonscripts documented (dev,build,start,lint). README states Node version expectations. - 2:
.nvmrc(example content:20) or"engines": { "node": ">=20" }prevents “works on my machine” vs CI drift. - 3:
"typecheck": "tsc --noEmit"catches type errors that ESLint might miss; CI should runlint+typecheck+buildon PRs.
4. Route groups
- Visiting
/and/pricingshould work. The(site)folder is organizational only;next buildoutput should list those routes without(site)in the path.
5. Dynamic [id] + Zod
- Parse with
z.string().uuid(); on failure callnotFound()fromnext/navigationso Next renders thenot-foundboundary instead of throwing an unhandled 500 for bad input.
6. Middleware redirect
NextResponse.redirect(new URL('/new', request.url), 307)preserves method for non-GET flows; use 308 if you require strict permanent semantics per HTTP needs.
7. Optional catch-all
params.slugisundefinedfor/docsand an array for nested paths. Log to verify; handle both branches in UI.
8. Dashboard layout persistence
- Layout state (sidebar open/closed if stored in layout-level client component) persists across child navigations because the layout component identity is stable.
9. Template remount
- You should see mount logs on every navigation between invoices/settings when
template.tsxwraps the segment; with layout-only, child remount behavior differs—templates reset subtree state by design.
10. Metadata
- Root: site-wide defaults. Child: export
metadatawithtitle: { absolute: '...' }or template pattern per docs. UsegenerateMetadatawhen values depend on async data.
11. When Vite + React might win
- Examples: purely static marketing with no SSR requirement; team allergic to server ops; embed/widget; existing design system docs site; edge deployment to static host only; very simple SPA with no SEO needs.
12. ADR
- Same rubric as 2.17: context, decision, alternatives (Pages Router), consequences (migration cost, ecosystem plugins), review date.