# Routing

> How vagejs turns files into URLs, how trailing slashes and the 404 page work, and how to redirect old URLs.

## Files become URLs

| File | URL |
| --- | --- |
| `src/pages/index.md` | `/` |
| `src/pages/about.md` | `/about/` |
| `src/pages/blog/index.md` | `/blog/` |
| `src/pages/blog/launch.md` | `/blog/launch/` |
| `src/pages/404.md` | the not-found page (`dist/404.html`) |

-   Files and folders starting with `_` are ignored, which is handy for notes and partial drafts.
-   Two files that would produce the same URL stop the build.
-   Every URL ends with a slash. Link to `/about/`, not `/about`; `vage check` warns about links that would redirect.

## The 404 page

`src/pages/404.md` becomes `404.html`. It's never indexed. GitHub Pages and Cloudflare Pages serve it automatically. On Cloudflare Workers, vagejs's generated config serves it for you; if you write your own `wrangler.jsonc`, add `"not_found_handling": "404-page"` under `assets`.

## Redirects

When you move or rename a page, keep the old URL working:

```ts
// vage.config.ts
redirects: { "/old-page/": "/new-page/" },
```

On Cloudflare these become real 301 redirects. On other hosts, vagejs writes a small page that sends visitors and search engines to the new address. `vage check` fails if a redirect points to a page that doesn't exist.

## Lists and navigation

Pages don't need to be registered anywhere. To list them, for a blog index, a sidebar or "related pages", use `collection()` in a layout. See [templates and layouts](https://vagejs.com/docs/templates-and-layouts/).
