Use PHP and Kirby in CSS File

I have been using the code below for a long time to use PHP and Kirby in CSS files. So far everything has always worked great. But when I wanted to test Laravel Herd today, I noticed that this program probably has a problem with this file.

Is it ok how I do it or is there a better way? Does anyone know why it works with Mamp Pro but not with Laravel Herd?

PS: even if I only output the header it doesn’t want to work.

  header('Content-type: text/css; charset: UTF-8');
  require dirname(__DIR__, 2) . '/kirby/bootstrap.php';
  $kirby = new Kirby;
  $site = site();
  $color_primary = $site->color_primary();

Nobody an idea what’s wrong? I am a bit desperate because I would like to use Laravel Herd instead of Map Pro, but I just can’t get it to work

The server probably send the wrong content type (text/html) despite your header in your php file.

So you would have to configure Nginx to make an exception for those files.

Or change the way you work with variables in your CSS, to get rid of these php files.

Ok. But as I know I can also set the Header with Kirby? Maybe Kirby overrides the Header? I had also cases where this happens.

Edit: ok, it has something to do with Kirby. If I create a simple index.php and include the template.css.php it works perfectly.

You could work around this issue with a route, in your header, you only load a css path, in your route you require the php file and return a response with type text/css

Does not really work for me. The CSS is also used in the Panel and in a lot of other Places where I can only link to a CSS File. It’s also used outside of the Kirby instance. But I really wonder what Kirby does behind the Scenes that this is not working with Herd.

I has also opened a ticket at Herd and they say the Framework is responsible for this.

Given that it works with MAMP, the built-in php server, and ddev (which is also Nginx) and probably other platforms, I nevertheless think this still has to do with server-side mime type configuration. This setup is really an edge case, but I also understand that you cannot change it quickly.

Yes, I also thought it was related to something else at first, but it must be due to Kirby! I have set up another instance in Herd, created an index.php with a stylesheet to a template.css.php and it works perfectly. So there is no other way that Kirby is (unfortunately) the cause of this.

At Herd Github they asked for a repo. I will try to create one, maybe they have an idea what’s wrong.

The discussion with the developers of Herd has resulted in the following:

Discussion here:

Is that anything that can be fixed or should I simply not using Herd? Is it a bug in Kirby with that driver or simply it’s crossing in development?

Was my guess that it is an issue in the driver as well, but don’t really know what changes it would need or how to test any changes. What I tried so far didn’t work.

Since using Laravel Herd is not a must, you might as well stick with MAMP.

Thanks for the info. Do you think I should report it on Kirby Github? Of course I can continue to use Mamp, but Herd is about 10 times faster and better to use, which is why I would like to switch. But I also don’t know if this is a bug or a edge case.

Internet says the error is most often due to a wrong SCRIPT_FILENAME parameter. I don’t work on Mac, so I can’t test this, but the Kirby Valet driver in fact always sets the SCRIPT_FILENAME parameter to either index.php or panel/index.php (Kirby’s front controllers).

So, when you request /assets/css/dynamic.css.php (or really any PHP script that nginx is actually able to find), the SCRIPT_FILENAME parameter set by Valet doesn’t match with the actually running script filename. I guess.

I presume you could adjust the Kirby Valet Driver to accept any existing PHP file (outside of the content, site and kirby folders) as “front controller”.

     * Get the fully resolved path to the application's front controller.
    public function frontControllerPath(string $sitePath, string $siteName, string $uri): ?string
        $scriptName = '/index.php';

        if ($this->isActualFile($sitePath.'/index.php')) {
            $indexPath = $sitePath.'/index.php';

        if ($isAboveWebroot = $this->isActualFile($sitePath.'/public/index.php')) {
            $indexPath = $sitePath.'/public/index.php';

        if (preg_match('/^\/panel/', $uri) && $this->isActualFile($sitePath.'/panel/index.php')) {
            $scriptName = '/panel/index.php';
            $indexPath = $sitePath.'/panel/index.php';

        // add this block
        if (preg_match('/^\/(?!(kirby|site|content)\/).+\.php$/', $uri)) {
            if (
                $this->isActualFile($sitePath.$uri) || 
                $isAboveWebroot && $this->isActualFile($sitePath."/public".$uri)
            ) {
                $scriptName = $uri;
                $indexPath = $sitePath.$scriptName;

        $sitePathPrefix = ($isAboveWebroot) ? $sitePath.'/public' : $sitePath;

        $_SERVER['SCRIPT_NAME'] = $scriptName;
        $_SERVER['SCRIPT_FILENAME'] = $sitePathPrefix.$scriptName;

        return $indexPath;

As I said, I can’t test this, but it might just work out of sheer luck

1 Like

Ok, that’s actually a bit too high for my level of knowledge. Where exactly should the code go? In Kirby and if so, in which file?

Oh; all I know is that the valet driver they’re talking about in the issue is here:

But, as I cannot use valet or herd, I can’t really tell you where that file would be installed.

Googling a bit seems to point to either:

/Library/Application Support/Herd/config/valet/Drivers/



Maybe someone with a Mac can help you with this

On my Mac, it’s here: /Applications/

1 Like

Yep, I also have found it. But now this error appears:

Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in /Applications/ on line 5

Uhm. Line #5 shouldn’t have changed. :confused:

Above is only the code to replace the frontControllerPath function, that’s lines 34 - 58.

Apart from a missing closing parenthesis in the code above, it actually works, @rasteiner

1 Like

whoops! thanks, should be fixed :slight_smile:

looks like the last version of the valet driver was contributed by @pedroborges, maybe he’s interested in having a look at this version and see if it still does what he expected (especially with the $isAboveWebroot thingy). And, like, maybe update the code :slight_smile:

Thank you very much, indeed everything is working now! I have submitted a PR and hope that it will be approved. I will also inform Herd shortly