Pages and routing
Use nested and index pages
Create clean directory routes and choose an index file when the URL should end at a folder.
An index file represents its folder’s URL. When a visitor asks for /blog/, Astro answers with the index file inside the blog folder:
src/pages/blog/index.astro → /blog/
src/pages/blog/archive.astro → /blog/archive/
This is how web servers have worked for decades. Ask for a directory, get its index.html. Astro’s build output makes that literal. With the default static output, src/pages/blog/index.astro becomes dist/blog/index.html, and archive.astro becomes dist/blog/archive/index.html.
Nesting works at any depth:
src/pages/docs/api/index.astro → /docs/api/
Flat file or folder?
Both src/pages/blog.astro and src/pages/blog/index.astro produce /blog/. Pick one form and stick with it.
My advice is to create the folder as soon as a section gets a second page. Then /blog/ and everything under it live in one directory, and the source tree reads like the sitemap.
The URL is part of the interface
Every folder under src/pages/ becomes a visible URL segment. /docs/api/ tells the reader where they are before the page loads.
So use folders when they match how you want the public site organized. Don’t nest files just to tidy up the source, because that tidiness shows up in the URL.
Keep components out of src/pages/
A reusable blog card belongs in src/components/, not next to the page files. If it sits under src/pages/, Astro tries to turn it into a route.
Sometimes a helper really belongs next to the pages that use it. In that case, prefix the name with an underscore, like src/pages/blog/_PostCard.astro. Astro skips underscore-prefixed files when building routes.
The failure to watch for
Moving a page changes its URL, silently. Move about.astro into a folder and /about/ stops existing. The build won’t warn you. Every inbound link to the old address starts returning 404.
Try this on the astro-notes project: move a page into a folder and run npm run build. Look under dist/ and confirm the old path is gone. If that URL was ever public, add a redirect, which we’ll cover in a few lessons.
Lesson completed