Next.js App Router explained for beginners
The App Router changes how you think about pages, layouts, and data fetching. Here is what you need to know.
What changed with the App Router
Next.js has two routers. The older one is called the Pages Router — files inside a pages/ folder became routes. The newer one, which EmergEdge uses, is called the App Router — files inside an app/ folder become routes.
The difference is not just folder names. The App Router changes how components work at a fundamental level.
Server Components vs Client Components
In the App Router, every component is a Server Component by default. This means it runs on the server, never in the browser. It can read files, query databases, and fetch data directly — without exposing anything to the client.
This is why your blog pages load fast. The Markdown file is read, the HTML is built, and the browser receives a complete page. No JavaScript needed to show the content.
A Client Component is one that runs in the browser. You need it when you want interactivity — a button that does something, a form that responds to input, a dropdown that opens and closes. You mark a file as a Client Component by adding "use client" at the very top.
"use client";
export default function SubscribeForm() {
// This component runs in the browser
}
The rule of thumb: start with a Server Component. Only reach for "use client" when you need the user to interact with something.
Layouts
The layout.tsx file wraps every page inside its folder. Your root layout at src/app/layout.tsx wraps every single page on the site — that is how the Navbar and Footer appear everywhere without you adding them to each page manually.
You can nest layouts. A src/app/blog/layout.tsx would wrap only the blog pages, letting you add a sidebar or different styling just for that section.
Data fetching
In the App Router, data fetching is straightforward. Because components run on the server, you can use async/await directly in the component:
export default async function BlogPage() {
const posts = getAllPosts(); // reads files on the server
return <div>{posts.map(...)}</div>;
}
No useEffect, no loading states, no client-side fetch calls for content that does not change per user. The data is ready before the page is sent to the browser.
What this means for EmergEdge
Every blog post page is a Server Component. It reads the Markdown file on the server and sends finished HTML to the browser. The result is fast page loads, good SEO, and no unnecessary JavaScript.
The subscribe form will be a Client Component because it responds to user input. Supabase authentication will use a combination of both — server-side session checking with client-side interactivity where needed.
Enjoyed this post? Subscribe to get new articles in your inbox.