# url

Sets the base URL for the site

****

****

## Auto-detection

By default, the `url` option is not set and Kirby will try to auto-detect your base URL, based on the `$_SERVER['SERVER_NAME']`:

```php
return [
  // any other config options
];
```

<info>
The `SERVER_NAME` is a variable provided from your web server to PHP and from PHP to Kirby. Its value depends on the server configuration. There is also the `HTTP_HOST` variable (which comes from the request) and the `HTTP_FORWARDED` and `HTTP_X_FORWARDED_HOST` variables (which also come from the request, but are usually set by reverse proxies that sit in between the client and Kirby).

As the latter variables can be set from the request, Kirby by default does *not* use these for auto-detection to protect against attacks.

If your site and Panel URLs are incorrect, this may be because of a reverse proxy that sits in between the client and Kirby. In this case please explicitly configure a fixed base URL or a set of possible base URLs (see below).
</info>

## Hard-coded base URL

By hard-coding the base `url` to a fixed value, you can switch off auto-detection.

```php
return [
  'url' => 'https://example.com'
];
```

This is useful if you only serve your site on a single domain. All URLs will be generated based on the hard-coded base URL, no matter the environment. We recommend to use this variant for best possible security.

You can also set relative URLs without a host:

```php
return [
  'url' => '/'
];
```

## URL allowlist

In most setups, you will have multiple different allowed base URLs, e.g. for production, staging and development.

If you set the `url` option to a list of allowed URLs, your Kirby installation will automatically pick the right one based on `HTTP_HOST`, `HTTP_FORWARDED`, `HTTP_X_FORWARDED_HOST` or `SERVER_NAME` (whatever is provided) and will make sure to send an error on an invalid host. This is perfect when you work with a reverse proxy in production but still want to allow other domains for testing.

```php
return [
  'url' => [
    'https://example.com',
    'https://staging.example.com',
    'http://example.test'
  ]
];
```

You can also define base URLs with subfolders here and the subfolders will be validated too.

<warning>
If you define an allowlist, any of the allowed domains can be used by setting the `Host`, `Forwarded` or `X-Forwarded-*` request headers. If your server doesn't filter these headers, attackers will be able to make Kirby behave like it's running on any of the allowed domains. This can be critical if you use domain-specific config files like `config.example.test.php` to set options that should not be set in production (like the `debug` option).

To prevent such attacks, either ensure that your server filters the mentioned request headers or use an URL override for the production deployment ([see below](#url-override-for-the-production-deployment)).
</warning>

## Wildcard option

If you fully trust your server setup, you can allow any host name coming from `HTTP_HOST`, `HTTP_FORWARDED` or `HTTP_X_FORWARDED_HOST`. This could be necessary in some situations, but is **insecure** and should only be used if you know what you are doing with your server configuration.

```php
return [
  'url' => '*'
];
```

## URL override per domain

In a <a href="https://getkirby.com/docs/guide/configuration#multi-environment-setup">multi-domain environment</a>, you may want to define the specific base URLs for each domain in the domain-specific config files.

As Kirby evaluates the `url` option twice, you can override the option value in the domain-specific config file and Kirby will ensure that the domain-specific value is used for the system's base URL.

For example, if your site is hosted in a subfolder on a particular domain but the subfolder is not passed to PHP and cannot be detected by Kirby automatically:

```php "site/config/config.php"
return [
  'url' => [
    'https://example.com',
    'https://staging.example.com',
    'http://localhost'
  ]
];
```

```php "site/config/config.localhost.php"
return [
  'url' => 'http://localhost/example-site'
];
```

<info>
To ensure security, Kirby loads the domain-specific config files based on the `url` option in the main config file and the `env.php` file (if it exists). So even if you set the `url` option again in the domain-specific config file, please make sure that the main config file allows the domain at all – otherwise your domain-specific config is never loaded and will not take effect.
</info>

## URL override for the production deployment

To protect against attacks when an allowlist is used, we recommend to pin the specific domain for your production site in the `env.php` config file:

```php "site/config/config.php"
return [
  'url' => [
    'https://example.com',
    'https://staging.example.com',
    'http://localhost'
  ]
];
```

```php "site/config/env.php"
return [
  'url' => 'https://example.com'
];
```

By adding the `env.php` file only on the production server (e.g. during the deployment), Kirby will allow any of the allowed domains on the testing servers, but only allow the production domain on the production server.

Pinning the URL with the `env.php` file also ensures that Kirby will never load any other domain-specific config file.