Why did we pick Next.js?
React is a library, Next.js is a framework. That distinction sounds like a textbook line, but in practice it means something very concrete.
What React does and doesn't do
React has one job: take data, paint an interface, and update that interface when the data changes. It does this very well. But building a website requires answers to questions React never addresses:
- When someone visits
/blog/hello, which component runs? - Is the HTML built in the visitor's browser or on the server?
- How do images get optimised, how do fonts get loaded?
- How does the code get bundled and shipped?
You can solve each of these yourself. Next.js hands them to you already solved, and solved consistently with one another.
File-based routing
To add a page in Next.js you don't edit a config file; you create a folder.
src/app/[locale]/page.tsx -> /en
src/app/[locale]/about/page.tsx -> /en/about
src/app/[locale]/blog/[slug]/page.tsx -> /en/blog/hello
Square brackets mean "this part is a variable". With [slug], every address under /blog/ lands on the same component, and we receive which post was requested as a parameter.
Server components
In the App Router, components run on the server by default. The code that reads posts in this blog looks like this:
const posts = getPosts(locale); // reads from the file system
That line could never run in a browser — a browser has no access to the Markdown files on your disk. Running on the server makes it fine, and more importantly, this code is never shipped to the browser at all. The visitor only receives the result: finished HTML.
When a component genuinely needs to run in the browser (listening to mouse movement, catching clicks), we put "use client" at the top of the file. In this blog the language switcher and the animated components are marked that way.
The rule: server by default, client when there's interaction. The less
"use client", the less JavaScript, the faster the site.
Static generation
The generateStaticParams function tells Next.js "prepare the HTML for these addresses ahead of time". When the build finishes we have a ready HTML file for every post. A visitor arrives, the server does no computation, it just sends a file. Having no database is what keeps this so simple.