Pages and file-based routing
There's no separate routing configuration file to maintain in the App Router — the folder structure inside app/ is the routing table. This part adds the blog's first real route, and covers exactly which folders the router notices and which it ignores.
Folders map directly to URL segments
app/
page.tsx → /
about/
page.tsx → /about
posts/
page.tsx → /posts// app/posts/page.tsx
export default function PostsPage() {
return <h1>All posts</h1>;
}Create app/posts/page.tsx with the component above, and /posts works immediately — no route registration, no import into a central router file. The folder name becomes the URL segment; nesting folders nests URL segments the same way.
Not every folder becomes a route
app/
posts/
page.tsx → /posts (has a page.tsx — routable)
components/
PostCard.tsx → nothing (no page.tsx — not a route)A folder inside app/ only becomes a visitable route if it directly contains a page.tsx. app/components/PostCard.tsx is a completely ordinary React component file, not a route — the presence of page.tsx specifically is what the router actually checks for, not just "is this a folder inside app/." This is what lets components, utilities, and routes live side by side in the same directory tree without colliding.
Linking between pages
// app/page.tsx
import Link from "next/link";
export default function Home() {
return (
<div>
<h1>devnotes</h1>
<Link href="/posts">Read the posts</Link>
</div>
);
}A plain <a href="/posts"> would work too, technically — it would just trigger a full page reload, throwing away everything Next.js does to keep navigation fast. next/link's Link component is the one used throughout this series for any in-app navigation; part 12 covers exactly what it does beyond just rendering an anchor tag.
Naming a route file Page.tsx (capital P) instead of page.tsx. On a case-sensitive filesystem — the default on Linux, and what most production hosting runs — that file is invisible to the router entirely, and the route silently 404s.
FAQ
How does a route with a dynamic segment, like a specific post's URL, get created?
A folder named in square brackets — app/posts/[slug]/page.tsx — matches any value in that URL position (/posts/hello-world, /posts/anything) and passes it to the page as a params prop. This series adds that once individual post pages exist, a few parts ahead.
Can I group routes into folders for organization without affecting the URL?
Yes — a folder name wrapped in parentheses, like (marketing), is a route group: it organizes files in the filesystem (and can hold its own layout) without adding a segment to the actual URL. app/(marketing)/about/page.tsx still serves /about, not /marketing/about.
What if I want a folder's name in the URL but the folder has no page.tsx of its own?
That's normal and expected — a folder like app/posts/ can exist purely to hold nested routes (app/posts/[slug]/page.tsx) without a page.tsx directly inside it, meaning /posts itself 404s while /posts/hello-world works. Adding a page.tsx directly in app/posts/ is what makes /posts itself a valid route, as this part does.
Next: page.tsx files render on the server by default — what that actually means, and when a component needs to opt out of it.