astro-sistema-routing

Astro Routing and Pages System

  • 4 min

Now that we know the syntax of a component, the next logical question is: How do I turn that component into a web page accessible via a URL?

This process is what we call Routing

In other frameworks or libraries, configuring routes can be a headache: configuration files, defining paths, assigning components…

In Astro this is much simpler. Astro follows a very current trend, which is simply using a file-based routing system.

What’s that? Simple premise: The file structure in your project disk defines the URL structure of your website.

The src/pages folder

Everything happens inside src/pages/. Astro bases itself on the content of this folder to create your website. If you put a compatible file in there, Astro will automatically generate a route for it.

Astro supports the following formats as pages:

  • .astro (Standard components)
  • .md and .mdx (Markdown for content)
  • .html (Pure HTML)
  • .js / .ts (For API endpoints, we’ll see this later)

This Routing method has the advantage of being very easy for the developer. You can review, copy, paste, rename… What you see as files will later become web pages. It’s that simple.

Basic static routes

Let’s see it with an example. Suppose we have this file structure:

src/pages/ ├── index.astro ├── contacto.astro └── sobre-mi.astro

This will automatically generate the following URLs. It couldn’t be easier!

FileGenerated Route (URL)
src/pages/index.astro/ (Home page)
src/pages/contacto.astro/contacto
src/pages/sobre-mi.astro/sobre-mi

As we can see, index is a reserved word that indicates the root of the current directory.

Subdirectories and nested routes

What if we want to better organize our site? Our structure might not be as simple as a single level.

For example, if we have a blog or a services section. We can create folders inside src/pages/ and Astro will respect them in the URL.

Imagine this structure:

src/pages/ ├── index.astro └── blog/ ├── index.astro ├── noticia-1.md └── noticia-2.md

The result will be:

  • src/pages/index.astro/ (Your website’s home)
  • src/pages/blog/index.astro/blog (The blog’s homepage)
  • src/pages/blog/noticia-1.md/blog/noticia-1
  • src/pages/blog/noticia-2.md/blog/noticia-2

It’s good practice to keep file and folder names in lowercase and use hyphens (kebab-case).

URLs are case-sensitive on many servers, and if you use uppercase or spaces… it’s almost certain to break at some point 😊

Linking pages

Unlike SPAs (Single Page Applications) that require special components like <Link> or <RouterLink> to navigate without reloading the page.

Astro bets on the web standard. To link pages we simply use the HTML <a> tag.

<p>
  Visit my <a href="/blog">Blog</a> or
  <a href="/contacto">contact me</a>.
</p>
Copied!

What about speed?

You might be wondering: “If I use <a>, won’t it reload the whole page and be slow?”

Astro is so lightweight and the HTML it generates is so optimized that navigation feels instant.

Furthermore, later we will see View Transitions, which turn this standard navigation into a smooth SPA-like experience without changing your code.

Custom 404 Page

What happens if a user tries to go to /this-route-does-not-exist? By default, Astro will show a simple generic error page.

Usually this is not what we want. We want our own custom 404 page.

To do this, we only need to create a special file called 404.astro (or 404.md) directly in src/pages/.

---
// src/pages/404.astro
import Layout from '../layouts/Layout.astro';
---

<Layout title="404: Not Found">
  <div class="error-container">
    <h1>Oops!</h1>
    <p>It seems you've gotten lost in space.</p>
    <a href="/">Return to base (Home)</a>
  </div>
</Layout>
Copied!

Astro will detect this file and automatically serve it when it doesn’t find a matching route.

Excluding files

Sometimes we want to have a file inside pages but not have it become a route (for example, a test file or a draft).

To make Astro ignore a file, simply add an underscore _ at the beginning of the name.

  • src/pages/_borrador.astroDoes not generate a route
  • src/pages/blog/_logica.jsDoes not generate a route