Jehlani Luciano Logo

Routing

Guidelines for Astro's file-based routing, dynamic routes, and redirects.

astro
          
            ## Astro Routing Guidelines

1.  Core Concept: File-Based Routing

    - Routes are generated based on the file structure within the `src/pages/` directory.
    - `.astro`, `.md`, and `.mdx` files become pages.
    - `src/pages/index.astro` -> `/`
    - `src/pages/about.astro` -> `/about`
    - `src/pages/blog/post.astro` -> `/blog/post`

2.  Navigation

    - Use standard HTML `<a>` tags for linking between pages. No special framework component is required.
    - `<a href="/about">About</a>`
    - `<a href="/blog/latest-post">Blog Post</a>`

3.  Dynamic Routes

    - Use bracket syntax `[param]` for single path segments or spread syntax `[...slug]` for multiple segments.
    - `src/pages/posts/[id].astro` matches `/posts/1`, `/posts/abc`.
    - `src/pages/files/[...path].astro` matches `/files/a/b`, `/files/document.pdf`.
    - Static (SSG - Default):

      - Export an `async function getStaticPaths()` from the dynamic route file.
      - This function must return an array of objects, each defining the `params` for a specific route and optionally `props` to pass to the page.
      - ```javascript
        // src/pages/posts/[id].astro
        export async function getStaticPaths() {
          // Fetch data...
          const posts = [
            { id: "1", title: "First" },
            { id: "2", title: "Second" },
          ];
          return posts.map((post) => ({
            params: { id: post.id },
            props: { post }, // Pass the whole post object as a prop
          }));
        }
        const { post } = Astro.props; // Access props in the template
        ```

    - Server (SSR):

      - Access dynamic parameters directly using `Astro.params`.
      - `getStaticPaths` is not required to define routes but can be used for _prerendering_ specific paths for performance.
      - ```javascript
        // src/pages/users/[userId].astro
        const { userId } = Astro.params;
        // Fetch user data based on userId...
        ```

4.  Redirects

    - Configuration: Define permanent (301) or temporary (302) redirects in `astro.config.mjs`:
      ```javascript
      // astro.config.mjs
      import { defineConfig } from "astro/config";
      export default defineConfig({
        redirects: {
          "/old": "/new", // 301 default
          "/home": { status: 302, destination: "/" },
          "/users/[id]": "/profile/[id]", // Dynamic redirects
        },
      });
      ```
    - Dynamic (in .astro pages/endpoints): Use `return Astro.redirect('/new-path', status);`
      ```javascript
      // src/pages/admin.astro
      if (!isLoggedIn) {
        return Astro.redirect("/login", 307); // Temporary redirect
      }
      ```

5.  Rewrites (SSR Only)

    - Serve content from a different internal path without changing the URL shown to the user.
    - Use `return await Astro.rewrite('/internal/path');` primarily within Middleware.

6.  Route Priority

    - Static routes > Dynamic routes > Rest (...) routes.
    - More specific routes override less specific ones (e.g., `/posts/create` overrides `/posts/[id]`).
    - Endpoints (`.js`/`.ts` files) take precedence over pages (`.astro`/`.md`).
    - File-based routes > Configured redirects.
    - Reserved routes (`/_astro/`, `/_server_islands/`, `/_actions/`) have the highest priority.
    - Alphabetical order is the final tie-breaker.

7.  Pagination

    - Use a dynamic route parameter like `[page]` (e.g., `src/pages/blog/[page].astro`).
    - In `getStaticPaths`, use the `paginate` function provided as an argument:
      ```javascript
      // src/pages/items/[page].astro
      export async function getStaticPaths({ paginate }) {
        const allItems = await fetchItems();
        return paginate(allItems, { pageSize: 10 });
      }
      const { page } = Astro.props; // Access pagination data
      // page.data, page.currentPage, page.url.prev, page.url.next, etc.
      ```
    - Nested Pagination: Group paginated results (e.g., by tag). `getStaticPaths` should return multiple `paginate()` results, passing the grouping parameter via `params`:
      ```javascript
      // src/pages/[tag]/[page].astro
      export function getStaticPaths({ paginate }) {
        // ... fetch posts and tags ...
        return allTags.flatMap((tag) => {
          const taggedPosts = filterPostsByTag(tag);
          return paginate(taggedPosts, {
            params: { tag }, // Crucial for grouping
            pageSize: 5,
          });
        });
      }
      ```

8.  Excluding Pages
    - Prefix filenames or directory names within `src/pages/` with an underscore (`_`) to prevent them from being built as routes (e.g., `_components/`, `_utils.js`, `_draft-page.astro`).

Reference: [Astro Routing Docs](https://docs.astro.build/en/guides/routing/)