File-based Routing
In Next.js App Router, every page.tsx inside app/ becomes a route. In Astro the same idea applies but the convention is simpler: any .astro file inside src/pages/ maps directly to a URL. The filename is the path segment.
Multi-page routing requires multiple files — open a full Astro project (
npm create astro@latest) to run these examples locally.
File → URL mapping
Section titled “File → URL mapping”The table below shows how file paths inside src/pages/ become URLs. This mirrors Next.js Pages Router conventions exactly — if you know /pages, you already know Astro routing.
| File path | URL |
|---|---|
src/pages/index.astro | / |
src/pages/about.astro | /about |
src/pages/blog/index.astro | /blog |
src/pages/blog/first-post.astro | /blog/first-post |
src/pages/contact.astro | /contact |
Side-by-side comparison
Section titled “Side-by-side comparison”// Next.js App Routerapp/ page.tsx → / about/ page.tsx → /about blog/ page.tsx → /blog first-post/ page.tsx → /blog/first-post
// Next.js Pages Routerpages/ index.tsx → / about.tsx → /about blog/ index.tsx → /blog first-post.tsx → /blog/first-post// Astro src/pages/src/pages/ index.astro → / about.astro → /about blog/ index.astro → /blog first-post.astro → /blog/first-post
// No page.tsx wrapper needed.// The .astro file IS the page.What a page file looks like
Section titled “What a page file looks like”A page .astro file is just a regular .astro component. The difference is location — files in src/pages/ are treated as routes.
// app/about/page.tsx (Next.js App Router)export default function AboutPage() { return ( <main> <h1>About</h1> <p>Welcome to the about page.</p> </main> );}---// src/pages/about.astroimport Layout from '../layouts/Layout.astro';---<Layout title="About"> <main> <h1>About</h1> <p>Welcome to the about page.</p> </main></Layout>Project file tree
Section titled “Project file tree”Here is what a typical Astro project looks like after adding a few routes:
flowchart TD src["src/"] --> layouts["layouts/"] src --> pages["pages/"] layouts --> layoutFile["Layout.astro (shared wrapper)"] pages --> indexFile["index.astro"] pages --> aboutFile["about.astro"] pages --> blog["blog/"] blog --> blogIndex["index.astro"] blog --> firstPost["first-post.astro"] indexFile --> indexURL["/"] aboutFile --> aboutURL["/about"] blogIndex --> blogURL["/blog"] firstPost --> firstPostURL["/blog/first-post"]