In Next.js, routing is based on your folder structure instead of a configuration file: every folder inside the app directory becomes part of the URL, a file called page.tsx inside that folder becomes the page visitors see, and a file called layout.tsx wraps pages with shared parts such as a header and footer. You do not install a router or register routes — you simply create folders and files, and Next.js turns them into web addresses.
Routing Without a Router Library
If you have used plain React, this feels pleasantly strange. In a React single-page app you normally install something like React Router and then write route definitions by hand: this path shows this component, that path shows that one. Forget a route, and your page exists but nobody can reach it — a little like building a room and forgetting the door.
Next.js took the opposite approach, called file-system routing. The framework watches your app folder and builds the route table for you. A folder named about containing a page.tsx file automatically becomes the address /about. The official Next.js documentation on layouts and pages calls a page "UI that is rendered on a specific route", and that is the whole mental model: files are routes.
Your First Routes: page.tsx
Here is a tiny site with three pages. Read the folder tree as a map of the website:
app/
page.tsx -> /
about/
page.tsx -> /about
blog/
page.tsx -> /blogEach page.tsx simply exports a React component:
export default function AboutPage() {
return (
<main>
<h1>About us</h1>
<p>We build friendly websites.</p>
</main>
);
}Notice what is missing: there is no route list anywhere. Add a folder, add a page file, and the URL exists. Delete the page file, and the URL politely becomes a 404. Beginners coming from other frameworks often waste an hour hunting for the routing file; in Next.js, the folder tree is the routing file. If the server/client split still feels fuzzy, our guide to Server Components vs Client Components in Next.js explains which of these files run where.
Layouts: The Frame Around Your Pages
Most pages on a site share furniture: a header, a navigation bar, a footer. Copying that furniture into every page works until the day you must change the menu in fourteen files. Next.js solves this with layout.tsx, a component that wraps the pages inside its folder:
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<header>My Site</header>
{children}
<footer>(c) 2026 My Site</footer>
</body>
</html>
);
}The magic word is children: that is where the actual page appears, framed by your header and footer. Layouts can also nest. A layout inside app/blog/ wraps only the blog pages, inside the root layout — frames within frames. Better still, when a visitor moves between two pages that share a layout, Next.js keeps the layout on screen and swaps only the page content, so your header does not flicker or lose its state on every click.
Dynamic Routes: One File, Many Pages
A blog has hundreds of posts but only one post design. Next.js handles this with dynamic segments: wrap a folder name in square brackets, and it becomes a placeholder that matches any value.
app/
blog/
[slug]/
page.tsx -> /blog/my-first-post
/blog/hello-world
/blog/any-slug-at-allexport default async function BlogPost({ params }) {
const { slug } = await params;
return <h1>Post: {slug}</h1>;
}Your component receives the matched value as params.slug and can load the right article from a database or files. One page file now powers every post on the blog — the same trick behind product pages on shops, profiles on social sites, and documentation pages like the ones you are reading about.
Linking Between Pages with next/link
To move between routes, use the Link component from next/link instead of a plain <a> tag:
import Link from "next/link";
export default function Nav() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/blog">Blog</Link>
</nav>
);
}It looks like ordinary HTML, but under the surface Next.js preloads the linked pages when they appear on screen, so clicks feel instant instead of triggering a full page reload. The React documentation's Learn React guide is a good companion here, because every page and layout is still just a React component with the same rules you already know. And if you are still deciding what to learn first, our comparison of React vs Next.js lays out the honest learning order.
Special Files: Loading, Error and Not Found
The App Router has a few more reserved filenames worth knowing, because they handle the moments beginners usually dread. Add a loading.tsx file to a folder and Next.js shows it automatically while that page's data is loading — no manual spinner logic — swapping in the real page the moment it is ready. Add an error.tsx file and it becomes a friendly safety net: if the page throws an error, visitors see your message and a retry option instead of a broken screen. And a not-found.tsx file lets you design your own 404 page in the same style as the rest of the site. Each of these is optional, each lives beside the page it serves, and each follows the same rule as everything else in this article: the filename is the feature.
Route Groups and Private Folders: Organising Without Changing URLs
As a site grows, the app folder can become crowded, and Next.js offers two naming tricks to tidy it. A folder wrapped in parentheses, such as (marketing), is a route group: it organises files and can even carry its own layout, but its name never appears in the URL — so app/(marketing)/about/page.tsx is still simply /about. A folder starting with an underscore, such as _components, is the opposite: it is private, completely opted out of routing, which makes it a safe home for shared components and helpers that should never become pages. Together, these two conventions let a large project stay organised without breaking a single address.
The App Router File Conventions in One Table
| File or folder | What it creates |
|---|---|
page.tsx |
The visible page for that folder's URL |
layout.tsx |
Shared wrapping UI for that folder and everything inside it |
loading.tsx |
Loading UI shown while the page prepares |
error.tsx |
Friendly error UI for that segment |
not-found.tsx |
Your custom 404 page |
[slug] folder |
A dynamic route matching any value in that segment |
(group) folder |
Organisation only — invisible in the URL |
_private folder |
Never routed — a safe place for shared code |
Keep this table nearby for your first project. After a week of building, you will stop consulting it, because the conventions start to feel less like rules to memorise and more like common sense: of course the page file is the page.
Frequently Asked Questions
Do I need React Router in Next.js?
No. Routing is built into Next.js through the file system. Installing React Router as well would duplicate the job and confuse both tools, so let the folders do the work.
What is the difference between page.tsx and layout.tsx?
A page is the unique content for one route. A layout is shared wrapping UI — headers, footers, sidebars — that surrounds pages and stays in place while you navigate between them.
What does [slug] mean in a folder name?
Square brackets mark a dynamic segment. The folder matches any value in that part of the URL, and your page receives the value as a parameter, so one file can serve many addresses.
Why is my new page showing a 404?
Almost always, the folder is in the wrong place or the file is not named exactly page.tsx (or page.jsx). Check that the folder sits inside app and that the file exports a default component.
Conclusion
Next.js routing rewards you for tidy folders: folders become URLs, page.tsx becomes the screen, layout.tsx becomes the frame, brackets become placeholders, and Link makes moving around feel instant. Learn those five ideas and you can build the skeleton of almost any website — no routing configuration required.
Leave a Comment