# Configuration: routing and URL processing

> Source: https://ferron.sh/docs/configuration/routing/url-processing

This page documents directives that affect HTTP request matching and configuration layering inside host blocks. The `http-server` module's radix tree resolver processes these directives.

> [!info]
> For the full request order, see [Request pipeline order](https://ferron.sh/docs/configuration/fundamentals/request-pipeline.md). Ferron resolves host, `location`, and `if` blocks once per request, before any pipeline stage runs.

## Directives

### Path matching

- `location <path: string>`
  - This directive specifies a path prefix for request matching. `/api` matches `/api` and `/api/...`. Longer matches are more specific. If this block matches, Ferron automatically rewrites the URL to strip away the the base URL (for example, `/api/users` becomes `/users` for `/api` location). Default: not configured

**Configuration example:**

```ferron
example.com {
    location /api {
        # Configuration for /api paths
    }
}
```

> [!note]
>
> - Matching is prefix-based (`/api` matches `/api` and `/api/users`). More specific locations win over less specific ones.
> - If this block matches, Ferron automatically rewrites the URL to remove the base URL.
> - Ferron supports prefixes only. There is no regex form such as `location ~`. Use a `match` block with `if` or `if_not` for pattern routing. See [Conditionals and variables](https://ferron.sh/docs/configuration/fundamentals/conditionals.md).
> - Ferron selects the `location` block once, on the original URL, before pipeline stages run. A later `rewrite` does not move the request to a different `location` block. See [Request pipeline order](https://ferron.sh/docs/configuration/fundamentals/request-pipeline.md).

### Inheritance

A `location` block inherits directives from the enclosing host block and from global defaults. When the same directive appears at both levels, the value in the `location` block wins for requests in that block. The same rule applies to `if` and `if_not` blocks nested in a host or `location` block. Handler and backend selectors (`proxy`, `fcgi`, `cgi`, `scgi`, `forward_proxy`, `root`, `index`, `basic_auth`, and related static-file tunables) are host-isolated: they inherit from global defaults and from the enclosing named host into its `location` blocks, but a named host does not inherit them from the wildcard `*` host.

### Conditional matching

- `if <matcher-name: string>`
  - This directive specifies a named matcher to evaluate. When the named matcher evaluates to true, Ferron applies the nested block's directives. Default: not configured
- `if_not <matcher-name: string>`
  - This directive specifies a named matcher to evaluate. When the named matcher evaluates to false, Ferron applies the nested block's directives. Default: not configured

**Configuration example:**

```ferron
example.com {
    if api_request {
        # Applied when api_request matcher passes
    }

    if_not api_request {
        # Applied when api_request matcher fails
    }
}
```

> [!info]
> For named matcher syntax and available variables, see [Conditionals and variables](https://ferron.sh/docs/configuration/fundamentals/conditionals.md).

### Error handling

- `handle_error [status: integer]`
  - This directive associates a nested block with a specific error code, or with a default error case when you give no code. Default: not configured

**Configuration example:**

```ferron
example.com {
    handle_error 404 {
        # Custom handling for 404 errors
    }
}
```

### URL redirects

- `trailing_slash_redirect [bool: boolean]`
  - This directive specifies whether automatic 301 redirects from directory paths without a trailing slash to the same path with a trailing slash are enabled. When omitted, defaults to `true`. Host isolation: a named host does not inherit `trailing_slash_redirect` from the wildcard `*` host. It still inherits from global defaults, and a `location` block inherits it from its own host. Default: `trailing_slash_redirect true`

**Configuration example:**

```ferron
example.com {
    root /srv/www/example
    trailing_slash_redirect
}
```

> [!note]
> Notes for `trailing_slash_redirect`:
>
> - Only applies when the resolved request path maps to a directory on the filesystem.
> - Ferron preserves query strings in the redirect (for example `/blog?foo=bar` → `/blog/?foo=bar`).
> - This is useful for SEO consistency and for making sure relative links within directory-served pages resolve correctly.