FE3: Server rendering with Next.js
Routes, layouts, server and client components
🎯You'll be able to
Lay out a Next.js App Router app with routes, layouts, and server and client components in the right places.
🏠The everyday picture
A mall has a fixed structure (entrances, corridors, signs) and individual shops inside it. The structure stays put while you move between shops. Layouts in a framework do the same for pages.
📘What it really is
- In Next.js's App Router, folders become routes:
app/store/[storeId]/page.tsxserves/store/kothrud. - Layouts (
layout.tsx) wrap pages and stay mounted while you move between them: headers, navigation, a cart badge. - Special files:
loading.tsx(shown while a page loads),error.tsx(shown if it fails),not-found.tsx. -
Server components (the default) run only on the server. They can read data directly and send no JavaScript for themselves to the browser.
-
Client components start with
'use client'. They run in the browser too and can use state, effects and event handlers. -
A good pattern: keep pages and layouts as server components, and make only the interactive leaves client components (an "Add to cart" button, a quantity picker).
-
Server components can pass data to client components as props, but only data that can be sent over the network (no functions or secret values).
📝A worked example
Kirana Express product page structure:
app/
layout.tsx (server: header, footer)
store/[storeId]/
layout.tsx (server: store name, opening hours)
product/[productId]/
page.tsx (server: reads product and price)
AddToCartButton.tsx ('use client': updates the cart store)
loading.tsx (skeleton while loading)
Only AddToCartButton and the cart badge ship component JavaScript to the browser. The product page's JavaScript dropped by about
60% compared with the old all-client version.
🌍Where it's used
- Large content sites that want small JavaScript bundles.
- Apps with shared shells: dashboards with a sidebar layout.
- Teams moving from a single-page app to a framework, page by page.
📝Case scenario
A developer adds 'use client' to the top-level layout so a theme toggle works. Now everything inside it is a client component, and
the bundle grows back to its old size. You move the toggle into its own small client component and keep the layout on the server.
🖱️Try it
Create the folder structure above in a new Next.js project. Make the product page a server component that reads from a local JSON
file, and add a client AddToCartButton. Check the browser's Network tab to see which JavaScript loads.
⚠️Common mistakes
- Marking everything 'use client'. Sign: big bundles and no server benefits. Fix: keep pages as server components and make only interactive parts client components.
- Using browser-only APIs in a server component. Sign: build errors about
windoworlocalStorage. Fix: move that code into a client component.
🛠️For your project
The starter's layout is a server component with one small client part (the cart link). Follow the same pattern in your pages.
✅Quick check
What can a client component do that a server component can't?
Show the answer
Use state, effects and event handlers that respond to the user in the browser.
Why keep 'use client' low in the tree?
Show the answer
So only the interactive parts send JavaScript to the browser, keeping pages light.
