Lesson Static, dynamic, and ISR in plain words introduced three rendering strategies, and one of them is worth restating because it is the trickiest.
ISR, Incremental Static Regeneration, is the strategy that serves prebuilt HTML instantly but refreshes it in the background after a time window. Visitors always get saved HTML immediately, and once the revalidate window passes, Next.js re-renders the page behind the scenes so the next visitor gets a fresher copy.
Styling and assets, the subject of this unit, mostly happen at build time too, which is why they cost so little at request time.
Three sanctioned ways to style
CSS has one famous failure mode at team scale: every class name is global, so a .card written for the checkout page silently restyles a .card on the blog, and nobody dares delete old CSS because anything might depend on it. The approaches below exist to contain that blast radius, and Next.js supports the ones you met in the React course, each with a lane:
- Global CSS. One file, imported once in the root layout. For resets, fonts, and design tokens.
// app/layout.js import "./globals.css";
- CSS Modules. Files named
*.module.css, scoped per component. The practical default for component styles. - Tailwind CSS. Utility classes in JSX. The
create-next-appwizard offers to set it up because so many teams use it.
What to avoid: importing plain global CSS from random components. Next.js only allows global stylesheets in the root layout, precisely so styles stay predictable.
CSS Modules in 20 seconds
/* app/card.module.css */ .card { border: 1px solid #ddd; padding: 1rem; }
// app/card.js import styles from "./card.module.css"; export default function Card({ children }) { return <div className={styles.card}>{children}</div>; }
Decode it:
- Importing the module gives you an object.
styles.cardis a generated unique class name likecard_a1b2c. - Because the name is unique, a
.cardclass in another module can never collide with this one. Scoping by construction, no naming discipline required. - Works identically in server and client components, since it is just class names in HTML.
Two modules, one class name, no collision
Suppose two components each define .title in their own *.module.css files, with different fonts. Nothing collides.
CSS Modules rewrite every class to a unique generated name per file, so .title in header.module.css might become header_title_a1b2c while .title in card.module.css becomes card_title_d4e5f. Identical human-readable names in different modules end up as entirely separate classes in the compiled output.
That isolation is the whole feature. It means you can name a class after what it is, .title, .card, .row, without first checking whether anyone else in the codebase took the name, and deleting a component safely deletes its styles with it.