Next.js App Router: A Practical Guide for Real Projects
Server components, layouts, loading states and caching explained with the decisions that matter when you ship a real Next.js site.
Tailwind is fast to write, but without rules a project becomes a wall of classes. A small design system fixes that.
Define your colors, fonts, radii and shadows once in the theme. Components then say bg-brand-600, not a random hex value, and a rebrand is a one-file change.
When the same group of classes appears three times, extract a component. In React, a Button component with a variant and size prop beats copying a 200-character class string.
A helper such as class-variance-authority keeps variants readable:
const button = cva('rounded-lg font-medium transition', {
variants: {
variant: { primary: 'bg-brand-600 text-white', ghost: 'hover:bg-slate-100' },
size: { md: 'h-10 px-4', lg: 'h-12 px-6' },
},
});
Pick a small set of spacing steps and type sizes and stick to them. Consistency is what makes an interface look professional.
Write mobile styles first and add sm:, md: and lg: upgrades. Test at 360 px width; if it works there it works everywhere.
Keep visible focus rings, enough contrast, and real buttons and links instead of clickable divs. Bake these into your base components so every screen inherits them.
If you keep writing arbitrary values like w-[347px], your design is missing a token. Add the token instead.
Tokens, components and variants turn Tailwind from a styling shortcut into a maintainable system.
Server components, layouts, loading states and caching explained with the decisions that matter when you ship a real Next.js site.
Stop guessing. Measure first, then apply the React optimizations that move the needle: memoization, code splitting, list rendering and more.
Typing props, hooks, events and API data with TypeScript, plus utility types and patterns that remove whole classes of bugs.