Routing in Astro
By Syncfusion®, Inc. · Last updated
Pages and page file types, linking, static, index and nested routes, route priority, the underscore prefix, trailing slashes, dynamic routes with getStaticPaths() and props, rest parameters, Astro.params, redirects, rewrites and the custom 404 page.
Routing
- Route = an address on your site, such as
/aboutor/blog/my-first-post. - Routing = deciding which page answers which address.
- Astro uses file-based routing: the path of a file in
src/pagesis the address. - In this lesson, you will learn every kind of route, including pages made from data.
Simple lesson: in Astro, you make an address by making a file.
A Real-World Example
- Asha now has five blog posts.
- She does not want to write five page files that look the same.
- She writes one file,
src/pages/blog/[slug].astro, and a list of her posts. - Astro builds one page per post:
/blog/why-astro,/blog/my-first-componentand so on.
Press ▶ Run. Open a post from the list. Then open the page list in the address bar.
What happened:
[slug]in the file name is a placeholder.getStaticPaths()lists the values for it.- Astro built three pages from one file, at build time.
What You Will Learn
In this lesson, you will learn:
- Which files become pages, and how to link them.
- Static, index and nested routes.
- How Astro picks a route when two could match.
- How to hide a file from routing.
- Dynamic routes with
getStaticPaths(), params and props. - Rest parameters for any depth of path.
- Redirects, rewrites and the 404 page.
Pages
What Pages Are
- Page = a file in
src/pagesthat becomes a route. - Each page builds to one HTML file (or many, for dynamic pages).
Supported Page File Types
.astro= an Astro component. The most common type..md= a Markdown page. You will write these in Markdown and MDX..mdx= Markdown with components. Needs the MDX integration..html= a plain HTML page, used as it is..jsand.tsfiles insrc/pagesare endpoints, not pages. They send data. You meet them in Endpoints and Server Data.
Linking Between Pages
- Use a normal
<a href="/about">tag. Astro needs no special link component. - Start the path with
/so it works from every page. - A browser loads each page as a new page. This is fast, because each page is plain HTML.
Simple lesson: a page is a file in src/pages. Link to it with a plain <a>.
File-Based Routing
Static Routes
- Static route = a fixed file name.
about.astrois always/about.
Index Routes
- Index route = a file named
index. It is the main page of its folder. src/pages/index.astrois/.src/pages/blog/index.astrois/blog.
Nested Routes
- Nested route = a file in a sub-folder. The folders become parts of the address.
src/pages/blog/2026/recap.astrois/blog/2026/recap.
Excluding Files with an Underscore
- A file or folder whose name starts with
_is not a page. - Use it for drafts or helper files that live in
src/pages:_draft.astro,_components/.
Animation: each file in src/pages is matched with its address. The file starting with an underscore gets no address.
File in src/pages Address index.astro about.astro blog/index.astro blog/2026/recap.astro _draft.astro
/ /about /blog /blog/2026/recap
no page
Folders become parts of the address. Files starting with _ are skipped.
Press ▶ Run. Use the address bar to list every page. _draft.astro is not there.
Route Priority
- Sometimes two routes match one address.
blog/new.astroandblog/[slug].astroboth match/blog/new. Astro picks the more specific route:
- a static route beats a dynamic one,
- a named parameter
[slug]beats a rest parameter[...path], - a longer static path beats a shorter one.
- So
/blog/newshowsnew.astro, even if[slug]also listsnew.
Trailing Slashes
- Trailing slash = a
/at the end of an address, as in/about/. The
trailingSlashoption inastro.config.mjsdecides what Astro accepts:"ignore"(the default) = both/aboutand/about/work."always"= only/about/works."never"= only/aboutworks.
- Pick one style and use it in every link.
Changing trailingSlash after your site is live changes many addresses. Old links can break, so add redirects when you change it.
Simple lesson: files map to addresses, index is a folder's main page, _ hides a file, and specific routes win.
Dynamic Routes
Dynamic Parameters
- Dynamic route = a file with
[name]in its path. One file makes many pages. - Parameter = the
[name]part. Its value comes from the address. src/pages/blog/[slug].astromatches/blog/anything.
getStaticPaths()
- In a static site, Astro must know every page at build time.
- So a dynamic page must export a function called
getStaticPaths(). - It returns a list. Each item has
params: the value for each[name]. - One item means one page.
Passing Props Through getStaticPaths()
- Each item can also have
props, such as the post's title and text. - The page reads them with
Astro.props. - This saves looking the data up again.
Reading Astro.params
Astro.paramsholds the values from the address.- In
[slug].astro,Astro.params.slugis the part after/blog/.
Press ▶ Run. Then add a fourth project to the list and run again.
- The preview opens
/projects/todo-app. Click the links, or pick a page from the address bar. map()turns the data list into the list of paths.
[TS] Typing getStaticPaths() Results
- Astro has a helper type so
Astro.paramsandAstro.propsknow their shape:
import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
export const getStaticPaths = (() => {
return [{ params: { id: "todo-app" }, props: { name: "Todo app" } }];
}) satisfies GetStaticPaths;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { name } = Astro.props as Props;
- [JS] You do not need this.
Astro.paramsandAstro.propswork the same way.
getStaticPaths() runs once, at build time, before any page is made. It cannot read the visitor's address or cookies. Pages that need those are built on request. You will learn that in On-Demand and Mixed Rendering.
Simple lesson: [name] in the file name, getStaticPaths() lists the values, Astro.params reads them.
Rest Parameters
- Rest parameter =
[...name]. It matches any number of address parts, including none. src/pages/docs/[...path].astromatches/docs,/docs/installand/docs/guides/deploy/netlify.- Its value is the whole rest of the path as one string, such as
"guides/deploy". - For
/docsitself, returnpath: undefined.
Simple lesson: [...path] catches a path of any length. Split it if you need the parts.
Redirects, Rewrites and the 404 Page
Configuring redirects
- Redirect = send a visitor from an old address to a new one.
- List them in
astro.config.mjsunderredirects:
export default defineConfig({
redirects: {
"/old-blog": "/blog",
"/posts/[slug]": "/blog/[slug]",
},
});
- The second line is a dynamic redirect:
[slug]is copied from the old address to the new one.
Redirect Status Codes
- Status code = a number the server sends with every answer.
301= moved for good. Search engines move the old page's ranking to the new one. This is the default.302= moved for now.- Pick a code:
"/old-blog": { status: 302, destination: "/blog" }.
Rewrites vs Redirects
- A redirect tells the browser "go to another address". The address bar changes.
- A rewrite shows another page's content at the same address. The address bar does not change.
- You rewrite with
return Astro.rewrite("/some-page")in a page's script. - Rewrites are mostly used with on-demand pages, such as showing a "please log in" page at a private address.
The 404 Page
- 404 = the status code for "page not found".
- Make
src/pages/404.astro. Astro shows it for every address that has no page. - A good 404 page links back to the home page.
Press ▶ Run. Click each link. One is redirected. One has no page.
- The terminal shows
301 redirect: /old-blog -> /blog. - On a real host, the redirect is sent as a 301 answer. In a static build, Astro writes a small HTML page that sends the browser on.
When you rename a page, add a redirect from the old address. Old links in search results and on other sites keep working.
Simple lesson: redirects move visitors, rewrites swap content, and 404.astro catches every missing page.
TL;DR
- Route = an address. File-based routing = file path in
src/pagesbecomes the route. - Static
about.astro→/about. Indexblog/index.astro→/blog. Nestedblog/2026/recap.astro→/blog/2026/recap. _prefix = not a page.- Priority = static beats dynamic.
[slug]beats[...path]. Dynamic route =
[slug].astroplusgetStaticPaths():params= the values in the address,props= extra data for the page.
- Astro.params = read the address values.
- Rest parameter =
[...path], any depth.undefinedfor the folder itself. - Redirect =
redirectsin the config.301by default. - Rewrite =
Astro.rewrite(), same address, other content. - 404 page =
src/pages/404.astro.
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
No getStaticPaths() in [slug].astro | Astro finds the values | Export getStaticPaths() | Build error: the function is missing |
| Different names in file and code | params.id works in [slug].astro | Use the name in the brackets: slug | The value is undefined |
Expecting /blog/new from [slug] when new.astro exists | Dynamic routes win | Static routes win | You see the static page |
<a href="about"> | Relative links are fine | Start with /: /about | The link breaks on nested pages |
| Renaming a page with no redirect | Old links update themselves | Add a redirect | Old links show the 404 page |
No 404.astro | The host makes a nice one | Make your own | Visitors see a plain error page |
Check Yourself
Exercises
What to Remember
- The path of a file in
src/pagesis its address. indexfiles are folder main pages._files are not pages.[slug].astroplusgetStaticPaths()builds many pages from one file.Astro.paramsreads address values.propscarry extra data.- Use redirects when pages move, and always make a
404.astro.
Next: Styling, where Asha's pages get their colours and layout.