Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Part 5: Next.js (20 min)

Goal

Take the same React app and put it in Next.js. Understand what Next adds: file-based routing, layouts, and server components.

What's here

  • package.json — depends on next instead of just vite
  • app/layout.jsx — wraps every page (nav bar lives here)
  • app/globals.css — global styles
  • app/page.jsx — the home route (/), a client component with the task tracker
  • app/TaskItem.jsx — child component
  • app/about/page.jsx — the /about route, a server component

Run it

cd 05-nextjs
npm install
npm run dev   # starts on port 3000

File-based routing

Next.js App Router uses folder structure for routing:

app/
├── layout.jsx        # wraps all pages
├── page.jsx          # / (home)
└── about/
    └── page.jsx      # /about

Add a folder with a page.jsx inside and you have a new route. No router config, no <Route path="..."> declarations.

Click between Home and About in the nav. Notice the page transitions instantly without a full reload — Next intercepts the navigation and only swaps the page content.

Layouts

app/layout.jsx wraps every page. The nav is defined there, so it appears on every route. You can nest layouts too — app/about/layout.jsx would wrap only /about and its children.

Server components vs client components — the key concept

By default in App Router, every component is a server component. It runs on the server, renders to HTML, and ships to the browser as plain HTML — no React JS runtime needed for that component.

Server components:

  • ✅ Can fetch data directly (const data = await fetch(...))
  • ✅ Can use server-only secrets (API keys, DB connections)
  • ✅ Ship zero JavaScript to the browser
  • ❌ Cannot use useState, useEffect, or any browser APIs
  • ❌ Cannot handle events (onClick etc.)

To opt into a client component, add 'use client' at the top of the file. Then it behaves like the React component you wrote in Part 4.

Look at the two pages:

  • app/page.jsx has 'use client' at the top — it needs state, events, localStorage
  • app/about/page.jsx has no directive — pure static content, runs on the server, ships as HTML

Open browser devtools → Network tab → reload the About page. The HTML arrives pre-rendered. Now reload the Home page — same, but plus the JS bundle needed for interactivity.

Why this matters

For real apps, you want server components by default (small bundles, fast loads, direct DB access) and client components only where you need interactivity (forms, animations, stateful widgets).

If you eventually wire a Next frontend to your codeminer.api Plumber backend, the natural pattern is:

  • Server component fetches the codelist on the server (no API call from browser, no loading spinner)
  • Client component handles the query builder UI (needs state)

Comparison

Part 4 (Vite + React) Part 5 (Next.js)
Routing None — single page File-based
Components All client Server by default, opt-in client
Data fetching Browser-side (useEffect) Server-side (async server components)
Build output Static SPA SPA + SSR + API routes
Use when Internal tools, simple apps Public sites, content-heavy apps, anything with auth

Try this

  1. Add a /settings route. Create app/settings/page.jsx as a server component with some static content. Add a link in the nav.
  2. Change app/about/page.jsx — add 'use client' and a useState button. It now works as a client component.
  3. Remove 'use client' from app/page.jsx and reload. Read the error message — it tells you exactly why server components can't use state.
  4. Look at the <head> of the rendered HTML in devtools. Next has set the <title> from the metadata export in layout.jsx.

Next

You've now built the same task tracker four different ways. The progression shows what each layer adds:

  • HTML — structure
  • CSS — presentation
  • JS — interactivity (manually)
  • React — interactivity (declaratively, with components)
  • Next.js — React + routing + server rendering + a build pipeline

From here, the natural next steps depend on what you want to build. Some directions:

  • Tailwind CSS for utility-first styling (much faster than handwritten CSS)
  • TanStack Query for fetching data from APIs (relevant for a CodeMiner frontend)
  • TypeScript for type safety (worth it as projects grow)
  • Shadcn/ui for accessible, composable components
  • Server Actions in Next.js for form submissions and mutations without writing API routes

→ Back to main README