Change URL, but only for pages


What is the easiest (best) way to change the URL for all pages (and also in e.g. paginations) - but only for the the pages.
URL’s for CSS/JS/files/media/… should remain the same?


Shouldn’t that work through the URL component? URLs | Kirby


Thx! I think that component changes all URL’s…
Tbh, I’m confused a bit where it’s different from changing the base url via the config.

Anyway, I can’t get it to work…
Pasting the code from the reference in a new plugin in my project results in a 500 error.
In a clean starterkit, it produces following error:

Argument 3 passed to Kirby\Toolkit\F::{closure}() must be of the type array, null given, called in /home/vagrant/ on line 67

Do you have any clues where to look to get this working?

I have also investigated this a bit before asking here.

I know you can

  • create a page method via a plugin; but this can’t override the built-in methods. You need to use a model for that.
  • change the URL via a model; but that would be super redundant the create a page model for each template for this purpose…
  • As stated above: change the base url via the config; but that’s for everything (also for the JS/CSS/files/media/…) which is not wanted.

Actually, I’ld need to be able to switch this behaviour (“default kirby url” OR “my custom base url”) on and off in a route…

May I ask what your use case actually is?


I need to serve some content that will be maintained in a Kirby installation (in a subdomain) to a Varnish proxy that will include it as ESI (some sort of Server Side Include) in HTML coming from another system.

All links used in paginations and pages should be built using the domain (and not the subdomain) to work that way… When Kirby editors preview content, the URL should be built with the subdomain.

All other assets (JS/CSS/files/…) should also link to the subdomain and let Kirby manage that.

I still think the URL component would be the way to go. Even if it does change all URLs (does it really?), you can still use conditions to limit what URLs should be changed or not.

Yea, sounds logical.

Now I got to make this work somehow …

Have you done this before?

Tried, yes, but I would have a hard time trying to find it again.

Here is an example of how to use the component, though. In your case, you would exclude paths that contain assets or mediaetc.´

Note that the example uses now deprecated $original($path, $options) which should be replaced as indicated in the docs.

Hi, thanks for that link.

I found a bit of clues on how to work with that here:

So, I got the URL component running in a plugin now, like this:

Kirby::plugin('bvdputte/urlhelper', [
  'components' => [
    'url' => function ($kirby, $path, $options) {
        // Don't override absolute urls and assets
        if (str::startsWith($path, "http://") || str::startsWith($path, "https://") || str::startsWith($path, "assets")) {
            return $kirby->nativeComponent('url')($kirby, $path, $options);

        return '' . $path;

But, in my tests I notice that it’s not used “everywhere” which contradicts the modify all urls claim:

  • it’s used for css() and js() stuff :+1:
  • it’s used in fields with e.g. $page->myField()->kt() :+1:
    • albeit not for (image:) - which makes me think it’s unused for $file at all
  • it’s not used for $page->url() calls in e.g. templates/snippets? :face_with_monocle:
  • it’s not used for e.g. $site->homepage()->url() :face_with_monocle:
  • it’s not used for html($translation->code()) :face_with_monocle:
  • it’s not used for $pagination such as $pagination->prevPageURL() or $pagination->pageURL($p) or $pagination->nextPageURL() :face_with_monocle:
  • it’s also not used in $file->url() (which is good for my use case)

Is this expected?

What you are asking for is content filtering/replacement which is typically a task on the reverse proxy. Are you sure that Varnish is not able to do it by itself? If not, are you in control of the webserver/vhost configuration on the Kirby site and are you using Apache? Then you can use mod_substitute which is designed for that purpose.

I don’t want to “replace” all URL’s: assets, files, etc still need to point to the Kirby subdomain. So there’ll need to be some logic involved?

Also; previewing the pages should still be possible for logged in kirby users. So here I actually want the default behaviour!

The devs of the platform I’m “integrating” Kirby with set up the proxy and basically “prefix” paths for “blocks” to be inserted via ESI that will be rendered by Kirby. Kirby recognizes these requests via the prefix and renders those “blocks” via a content representation. That’s my setup so far.

Of course, mod_substitute can do a regex replacement. This is a common task when working with reverse proxy.

This can be handled by different vhost configurations and if

then the webserver is also able to do so.

But I do not know the details of your architecture so this is just a hint for a possible solution.

Thanks for your input, but I’ld prefer to manage it all in Kirby via path overrides if that’s possible. This is the solution I’m searching for.

Since “url” is extensible I’ld think that must be somehow possible? Then all my logic is centralized in 1 place.

I’m lost “where” to find this place though, and in need for help for this!

Ok, despite its description, the component doesn’t seem to be doing what it promises.

I wonder if it is possible to set up the url in the index.php, like described here:

But I’m not sure if it will work with the base url type, which is used for page urls, nor if it works in a multilanguage context.

It’s not really what I’m after anyway.

I basically want just 1 site that in certain content representations renders the $page and $pagination objects with a different base URL…