# Routing

Routing in Qwik Router is file-system based like [Next.js](https://nextjs.org/docs/routing/introduction), [SvelteKit](https://kit.svelte.dev/docs/routing), [SolidStart](https://start.solidjs.com/core-concepts/routing) or [Remix](https://remix.run/docs/en/main/guides/routing). Files and directories in the `src/routes` have a role in the routing of your application.

- **Directories:** Define the URL segments to match by the router.
- **`index.tsx/mdx` files:** Define a [page](/docs/pages/).
- **`index.ts` file:** Define an [endpoint](/docs/endpoints/).
- **`layout.tsx` files:** Define nested [layout](/docs/layout/) and/or a [middleware](/docs/middleware/).

[Video](https://cdn.builder.io/o/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fabf8f471ba884b938d0863d85ed4c50f%2Fcompressed?apiKey=YJIGb4i01jvw0SRdL5Bt&token=abf8f471ba884b938d0863d85ed4c50f&alt=media&optimized=true)

## Directory-based routing

Only the directory names are used to match the incoming requests to pages/endpoint/middleware.

For example, if you have a file at `src/routes/some/path/index.tsx`, it will be mapped to the URL path `https://example.com/some/path`.

```bash title="Directory layout"
src/
`-- routes/
    |-- contact/
    |   `-- index.mdx         # https://example.com/contact
    |-- about/
    |   `-- index.md          # https://example.com/about
    |-- docs/
    |   `-- [id]/
    |       `-- index.ts      # https://example.com/docs/1234
    |                         # https://example.com/docs/anything
    |-- [...catchall]/
    |   `-- index.tsx         # https://example.com/anything/else/that/didnt/match
    |
    `-- layout.tsx            # This layout is used for all pages
```

- **`[id]`** is a directory that represents a dynamic route segment, in this example `id` is the string parameter accessible by `useLocation().params.id`.
- **`[...catchall]`** is a directory that represents a dynamic catch-all route, in this example `catchall` is the string parameter accessible by `useLocation().params.catchall`.
- **`index.tsx|mdx` files** are the pages/endpoints/middleware.
- **`layout.tsx` files** are the layouts.

### Dynamic route segments

Special named directories with square brackets, such as `[paramName]` and `[...catchAll]` can be used to match route segments which are dynamic:

```bash title="Directory layout"
src/routes/blog/index.tsx → /blog
src/routes/user/[username]/index.tsx → /user/:username (/user/foo)
src/routes/post/[...all]/index.tsx → /post/* (/post/2020/id/title)
```

```bash title="Directory layout"
src/
`-- routes/
    |-- blog/
    |   `-- index.tsx         # https://example.com/blog
    |-- post/
    |   `-- [...all]/
    |       `-- index.tsx     # https://example.com/post/2020/id/title
    `-- user/
        `-- [username]/
            `-- index.tsx     # https://example.com/user/foo
```

The folder `[username]` can be any of the thousands of users that you have in your database. It would be impractical to create a route for each user. Instead, you need to define a Route Parameter (a part of the URL) that will be used to extract the `[username]`.

```tsx title="src/routes/user/[username]/index.tsx"
import { component$ } from '@qwik.dev/core';
import { useLocation } from '@qwik.dev/router';

export default component$(() => {
  const loc = useLocation();
  return <div>Hello {loc.params.username}!</div>;
});
```

## `index` files

Inside the `src/routes` directory, all files named `index` are considered pages/endpoint/middleware, Qwik supports the following extensions: `.ts`, `.tsx`, `.md` and `.mdx`.

Pages/endpoint/middleware are the leaf nodes of the routing tree, i.e., **the modules that will handle the request and return an HTTP response**.

### Page `index.tsx`

When an `index.tsx` or `index.ts` file exports a Qwik component as the default export, Qwik Router will render the component and return an HTML response as a webpage.

```tsx title="src/routes/index.tsx"
import { component$ } from '@qwik.dev/core';

export default component$(() => {
  return <h1>Hello World</h1>;
});
```

### Endpoint `index.ts`

An `index.ts` file can access the HTTP request directly and return a raw HTTP response without involving any Qwik Component. This is done by exporting any of the following methods: `onRequest`, `onGet`, `onPost`, `onPut` or `onDelete` depending on how you want to handle a specific HTTP request.

```tsx title="src/routes/index.ts"
import type { RequestHandler } from '@qwik.dev/router';

export const onGet: RequestHandler = ({ json }) => {
  json(200, { message: 'Hello World' });
};
```

In the last example, there is no default export. This is because you are not rendering a Qwik component, but rather you are handling the request directly and returning a JSON response. This is useful for implementing RESTful APIs or any other type of HTTP endpoint.

### Page + Endpoint

In Qwik Router there is no clear separation between pages and endpoints. An `index.tsx` file handles both and exports a Qwik component or an `onRequest` method. However, it's possible to combine both approaches. For example, you can export an `onRequest` method that will handle the request, and then render a Qwik component.

```tsx title="src/routes/index.tsx"
import { component$ } from '@qwik.dev/core';
import type { RequestHandler } from '@qwik.dev/router';

export const onRequest: RequestHandler = ({ headers, query, json }) => {
  headers.set('Cache-Control', 'private');
  if (query.get('format') === 'json') {
    json(200, { message: 'Hello World' });
  }
};

export default component$(() => {
  return <h1>Hello World</h1>;
});
```

In this example, a request handle will always set the `Cache-Control` header to `private` and the page will be rendered as an HTML page, but if the request contains a `format=json` query param, the endpoint will return a JSON response instead.

## `layout.tsx` files

Layout modules are very similar to `index` files. Both can handle requests and render Qwik components. However, layouts are designed to work like middleware, allowing to **share UI and request handling (middleware)** to a set of routes.

Usually, different pages need some common request handling and share some UI. For example, picture a dashboard site where all the pages are under the `/admin/*` directory:

- **Shared request handling:** The request cookies need to be validated before even rendering the page, otherwise, render a blank 401 page.
- **Shared UI:** All pages share a common header showing the user's name and profile picture.

Instead of repeating the same code in each route, use layouts to automatically reuse common parts. Layouts also support adding middleware to the route.

Take this `src/routes` directory as an example:

```bash title="Directory layout"
src/
`-- routes/
    |-- admin/
    |   |-- layout.tsx  <-- This layout is used for all pages under /admin/*
    |   `-- index.tsx
    |-- layout.tsx      <-- This layout is used for all pages
    `-- index.tsx
```

### Middleware Layouts

Layouts can implement request handling using any of the following methods: `onRequest`, `onGet`, `onPost`, `onPut` or `onDelete`. This means they can be used to implement middleware.  For example, they can be used to validate the request cookies before rendering the page.

For the route `https://example.com/admin`, the `onRequest` methods will be executed in the following order:

1. `src/routes/layout.tsx`'s `onRequest`
2. `src/routes/admin/layout.tsx`'s `onRequest`
3. `src/routes/admin/index.tsx`'s `onRequest`
4. `src/routes/admin/index.tsx`'s component

An `onRequest` handler in `src/routes/index.tsx` doesn't get executed.

### Full Execution order

```bash
1 --> [entry.express.ts or entry.preview.ts]
2 --> [plugin@some-name.ts] #Alphabetical order
3 --> [server$]
4 --> [entry.ssr.ts]
5 --> [root.tsx]
6 --> [layout.tsx onRequest  ->  onGet/onHttpVerb]
7 --> [globalLoaders]
8 --> [routeLoaders]
9 --> [jsx/components on a route]
```

### Nested Layouts

Layouts also **provide a way to add common UI to the rendered page**. For example, if you want to add a common header to all of the routes, add a Header component to the root layout.

For the given example, the Qwik components will be rendered in the following order:

1. `src/routes/layout.tsx`'s component
2. `src/routes/admin/layout.tsx`'s component
3. `src/routes/admin/index.tsx`'s component

```tsx
<RootLayout>
  <AdminLayout>
    <AdminPage />
  </AdminLayout>
</RootLayout>
```

## SPA Navigation

With Qwik, the distinction between MPA and SPA disappears; every app can be both at the same time.
The choice is no longer an architectural design determined at the beginning of the project,
instead, this decision can be made for every link.

Qwik provides a `<Link>` component and `useNavigate()` hook.
These can be used to initiate an SPA refresh or navigation between pages.

The `Link` component is the recommended way to navigate as it uses the HTML `<a>` tag,
  which is the most accessible way to move between pages.
However, if you need to navigate programmatically, you can use the `useNavigate()` hook.

```tsx
import { component$ } from '@qwik.dev/core';
import { Link, useNavigate } from '@qwik.dev/router';

export default component$(() => {
  const nav = useNavigate();
  return (
    <div>
      <Link href="/about">About (preferred)</Link>
      <button onClick$={() => nav('/about')}>About</button>
    </div>
  );
});
```

The `Link` component uses the `useNavigate()` hook internally.

### Preventing navigation

Use [`usePreventNavigate$`](/docs/advanced/prevent-navigation.md) to prevent navigation while your app's state is unsaved.

### `<Link reload>`

The `Link` component with the `reload` prop can be used together to refresh the current page.
You can also call the `nav()` function from the `useNavigate()` hook, without arguments.

```tsx
import { component$ } from '@qwik.dev/core';
import { Link, routeLoader$, useNavigate } from '@qwik.dev/router';

export const useServerTime = routeLoader$(() => {
  // This will re-execute in the server when the page refreshes.
  return Date.now();
});

export default component$(() => {
  const nav = useNavigate();
  const serverTime = useServerTime();

  return (
    <div>
      <Link reload>Refresh (better accessibility)</Link>
      <button onClick$={() => nav()}>Refresh</button>
      <p>Server time: {serverTime.value}</p>
    </div>
  );
});
```

When the page refreshes, all the matching `routeLoader$` and server handlers (`onRequest`) will re-execute in the server and the UI will re-render accordingly.

While refreshing the page, the `isNavigating` boolean from `useLocation()` will be `true` until the page is fully rendered.

### `<Link>` prefetching

Use `prefetchBundles` and `prefetchData` to control what a link prefetches and when it starts.

By default, `prefetchBundles` uses `visible`, while `prefetchData` uses `intent`, so route bundles
are prefetched when the link enters the viewport and route data is prefetched when the user shows
navigation intent.

For the full list of strategies, examples, and deprecated `prefetch` behavior, see
[`<Link>` prefetch in the API reference](/docs/api/#prefetch).

### Scroll Restoration

Qwik provides best-in-class scroll restoration for SPA's that closely mimics the native browser experience.
Your users should receive the exact same experience they've come to expect natively from an MPA,
except with all the added benefits of an SPA.

After you use one of the above methods to navigate, the user is automatically upgraded to an SPA.
This means that the current page, and the page they came from, now have an `SPA` context associated with them.

If a user then clicks a regular `<a>` tag, they will perform a regular navigation. This new page will have no SPA context,
and is effectively downgraded back to an MPA. You can swap between these as necessary,
and the user's experience will seamlessly switch between MPA and SPA as if it were all the same.

When a user re-visits the SPA-enabled history entries, such as with a refresh, back/forward button, browser session restarts, etc.,
Qwik will automatically restore their scroll position and bootstrap itself back into the SPA context as needed.

The script required to provide this robust experience never loads, nor is it ever even sent to the user's browser, unless the history entry has had an SPA context. Pure MPA pages never load this script. This is the magic of Qwik.

Scroll restoration in Qwik always occurs synchronously with render. When combined with Qwik's resumable and first-class SSR/MPA nature, the user should never experience scroll flashing.

Qwik's scroll restoration is entirely `history` based. This is different from many other frameworks
which rely on things like `sessionStorage`.

Qwik's ability to remember and restore scroll positions is extremely robust
and will survive everything from browser session restarts to users clearing their browser data,
which is not the case for many other frameworks.

**Using pushState() and replaceState() during SPA**

On a page with an SPA context, Qwik will patch the `pushState()` and `replaceState()` functions on the global `history`.
This is to ensure that any custom states you add as a developer, also receive the SPA context.

While these are patched, states you `push` or `replace` should always be an actual `Object` type.
This is because Qwik needs to be able to automatically append the SPA context to the state as a property.

If you provide a value that is not an object, Qwik will create a new object for state and add your provided
value to a new key: `{ _data: <your_value> }`

Qwik will also warn you in the browser's console in `dev` mode when this occurs.

## Request Event

Each request handler, such as `onRequest`, `onGet`, `onPost`, etc., are passed in a `RequestEvent` object as the first argument to the handler. The `RequestEvent` object contains utility functions and properties to get and set values to the server's request and response. This object contains the following properties:

- `basePathname`: The base pathname of the request, which can be configured at build time. Defaults to `/`.
- `cacheControl`: Convenience function to set the [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) response header.
- `cookie`: HTTP request and response [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies). Use the `get()` method to retrieve a request cookie value. Use the `set()` method to set a response cookie value.
- `env`: Platform provided environment variables.
- `error`: When called, the response will immediately end with the given status code. This could be useful to end a response with `404`, and use the 404 handler in the routes directory. See [Status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) for which status code should be used.
- `getWritableStream`: Low-level access to write to the HTTP response stream. Once `getWritableStream()` is called, the status and headers can no longer be modified and will be sent over the network.
- `headers`: HTTP [response headers](https://developer.mozilla.org/en-US/docs/Glossary/Response_header).
- `html`: Convenience method to send an HTML body response. The response will be automatically set the `Content-Type` header to`text/html; charset=utf-8`. An `html()` response can only be called once.
- `internalRequest`: Identifies Qwik Router internal JSON requests as `'loader'` or `'action'`. Returns `false` for normal page requests. Check this before applying broad rewrite rules.
- `json`: Convenience method to JSON stringify the data and send it in the response. The response will be automatically set the `Content-Type` header to`application/json; charset=utf-8`. A `json()` response can only be called once.
- `locale`: Which locale the content is in. The locale value can be retrieved from selected methods using `getLocale()`.
- `method`: HTTP request [method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) value.
- `next`: Call the next request handler. This is useful for middleware.
- `params`: URL path params which have been parsed from the current url pathname segments. Use `query` to instead retrieve the query string search params.
- `parseBody`: This method will check the request headers for a `Content-Type` header and parse the body accordingly. It supports `application/json`, `application/x-www-form-urlencoded`, and `multipart/form-data` content types. If the `Content-Type` header is not set, it will return `null`.
- `pathname`: URL pathname value. Does not include the protocol, domain, query string (search params) or hash.
- `platform`: Platform specific data and functions.
- `query`: URL query string [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) value. Use `params` to instead retrieve the route params found in the url pathname.
- `redirect`: URL to redirect to. When called, the response will immediately end with the correct redirect status and headers. See [Redirects](https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections) for which status code should be used.
- `request`: HTTP [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request).
- `send`: Send a body response. The `Content-Type` response header is not automatically set when using `send()` and must be set manually. A `send()` response can only be called once.
- `sharedMap`: Shared Map across all the request handlers. Every HTTP request will get a new instance of the shared map. The shared map is useful for sharing data between request handlers.
- `status`: HTTP response [status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status). Sets the status code when called with an argument. Always returns the status code, so calling `status()` without an argument can be used to return the current status code.
- `text`: Convenience method to send a text body response. The response will be automatically set the `Content-Type` header to`text/plain; charset=utf-8`. A `text()` response can only be called once.
- `url`: HTTP request [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL).

## Rewrite Routes

You can rewrite your pathnames in order to reuse one single page component with its own middlewares and layouts for multiple pages.
This could be useful for SEO purposes or to translate your pages in different languages.

**Translate localized urls with prefix**

For localization purposes you may want to translate your routes from `/products` to `/it/prodotti`
or to `/fr/produits` and `/products/product-name` to `/it/prodotti/nome-prodotto` or `/fr/produits/nom-du-produit`
without having multiple routes files for each locale but reusing the same page component, layouts, middlewares and so on.

The parameters name will not be changed so if the route file is `/products/[slug]/index.tsx` and the url is `/products/product-name`,
`/it/prodotti/nome-prodotto` or `/fr/produits/nom-du-produit` you will receive the same path parameter `slug` with
the values `product-name`, `nome-prodotto` or `nom-du-produit`.

**Rewrite urls without prefix**

It's rare but you may want to have aliases for the same path.
For example you may want both `/docs` and `/documents` to be rendered from the same page component or
you may want to translate `/products` to `/prodotti` without adding the `/it` prefix.

In each folder within the routes directory where there are instances of the paths keys in the pathname, the route node will be duplicated, and all occurrences of paths keys will be replaced with their corresponding paths values.
All path parameters will preserve the same name. If there is a prefix it will be added at the beginning of the rewritten pathname.

You can set the rewrite rules as follows in your `vite.config.ts`:

```tsx
import { defineConfig } from 'vite';
import { qwikRouter } from '@qwik.dev/router/vite';

export default defineConfig(async () => {
  return {
    plugins: [
      qwikRouter({
        rewriteRoutes: [
            {
              paths: {
                  'docs': 'documentation'
              },
            },
            {
              prefix: 'it',
              paths: {
                'docs': 'documentazione',
                'getting-started': 'per-iniziare',
                'products': 'prodotti',
              },
            },
          ],
      }),
    ],
  };
});
```

By default a config rewrites every matching route. Add `exclude` to skip routes that should not be rewritten under that config. The patterns use the same glob syntax as the SSG `include`/`exclude` and are matched per config:

```tsx
rewriteRoutes: [
  {
    prefix: 'it',
    paths: {
      'docs': 'documentazione',
      'products': 'prodotti',
    },
    // `/blog` stays English-only: no `/it` mirror is generated for it.
    exclude: ['/blog/*'],
  },
],
```

## Advanced routing

Qwik Router also supports:

- [Route Parameters](/docs/advanced/routing.md)
- [Nested layouts](/docs/advanced/routing.md#nested-layout)
- [Menus](/docs/advanced/menu/)
- [Request Handling](/docs/advanced/request-handling/)

## Typesafe Routing
- [Typed Routes](/docs/labs/typed-routes/#-typed-routes)
- [Declarative Routing](/docs/labs/typed-routes/#declarative-routing)

These are discussed later.
