File-Based Routing & Dynamic Routes
Chapter 1 briefly showed a plain static file in src/pages/ becoming a real route. This chapter covers the rest of the picture: dynamic segments, catch-all routes for arbitrary-depth paths, and the one real constraint every dynamic route runs into by default — getStaticPaths().
Static Routes, Recapped
src/pages/index.astro→/src/pages/about.astro→/aboutsrc/pages/blog/index.astro→/blog
Folders nest naturally into path segments — no route configuration file exists anywhere in an Astro project.
Dynamic Single-Segment Routes
[slug].astro matches any single path segment at that position — /blog/first-post, /blog/second-post — captured into Astro.params.slug.
getStaticPaths() is exactly that declaration. Visit a URL whose value wasn't returned by getStaticPaths(), and there's simply no pre-built file for it — a real 404, not a route that resolves lazily. Chapter 10's server output mode removes this constraint entirely, resolving dynamic routes per-request instead.
Catch-All Routes: Arbitrary-Depth Paths
[...path].astro is Astro's own catch-all segment — the three dots match zero or more path segments, slashes included, all captured into a single string on Astro.params.path. Same requirement applies: every real deep path this route should serve has to appear in getStaticPaths()'s own returned list.
[...path] folder convention, Django's <path:full_path> converter, Laravel's {path?} plus a regex constraint, and Rails' own *path glob. Astro's [...path].astro is this course's own version of the identical idea — the piece a future Website Rebuild with Astro course would build directly on.
No Client-Side Router by Default
Unlike a single-page application framework, Astro doesn't ship a client-side router at all by default — navigating between pages is a genuine full page load, since there's no persistent client-side app to route within. An optional View Transitions API exists for smoother navigation animations, but it's a later, opt-in refinement, not a default routing mechanism the way React Router or Vue Router are.
Coding Challenges
Build a dynamic route at src/pages/products/[id].astro, with getStaticPaths() returning at least 3 hard-coded IDs, rendering the current ID via Astro.params.
📄 View solutionBuild a catch-all route at src/pages/docs/[...path].astro, with getStaticPaths() covering at least one multi-segment path, rendering the full captured path.
📄 View solutionBuild the site (npm run build) and confirm a URL not covered by getStaticPaths() has no corresponding output file — demonstrating why every real path has to be declared up front in static mode.
📄 View solutionChapter 3 Quick Reference
src/pages/— every file becomes a real route, folders nest into path segments[slug].astro— matches one dynamic path segment, captured viaAstro.params[...path].astro— catch-all, matches an arbitrary-depth path in one segment stringgetStaticPaths()— required in static output mode; every real path must be declared up front, or it's a genuine 404- No client-side router by default — navigation is a real page load unless View Transitions is added
- Next chapter: Layouts, Slots & Component Composition