Skip to content

Kirby 4.1.2

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']:

return [
  // any other config options
];

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).

Hard-coded base URL

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

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:

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.

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.

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).

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.

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

URL override per domain

In a multi-domain environment, 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:

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

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.

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:

site/config/config.php
return [
  'url' => [
    'https://example.com',
    'https://staging.example.com',
    'http://localhost'
  ]
];
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.