K3 plugins assets not generating in media folder

hi, i am trying to make a plugin for a weather widget. i am following de kirby docs…

I created a folder (eg myplugin /) and inside I created index.php and an assets folder and I put an image and css files.

but in the middle folder the corresponding files are not generated. Do you have to initialize in some way the reading of assets in the media folder?

my index.php

Kirby::plugin('diezmilseres/weather', array(
  'snippets' => [
      'weather' => __DIR__ . '/snippets/weather.php'


What does your structure inside the plugins folder look like?





I think it works if you put the files into corresponding folders:


i change the flder structure, but nothing happened, media folder still not populated with plugins assets.


Do other files like thumbs get generated?

plugin assets in media folder are referenced by symlink. they are not copied. maybe your setup does not support that? can you provide more information on that?

Pages and panel plugins assets (ex. matomo plugin) are generated.

i installed a bitnami lamp to test if my setup was wrong… same thing…

MEDIA FOLDER (panel, pages, site are generated)


PLUGIN FOLDER (put css file on assets folder, etc. nothing happened)



i created a manualy a symlink (ln -s) from plugin assets to media folder an its work ergo symlinks are not the problem


any ideas? it a bug or i am doing something wrong? sorry my english!

@texnixe it seems that something is not working properly

  1. kirby/config/routes.php has the correct pattern and return correct action
  2. it seems that the plugin assets folder gona be created only when the route is requested
  3. but… on media/assets plugin folder it is not created


        'pattern' => $media . '/plugins/(:any)/(:any)/(:all).(css|gif|js|jpg|png|svg|webp|woff2|woff)',
        'env'     => 'media',
        'action'  => function (string $provider, string $pluginName, string $filename, string $extension) use ($kirby) {
            return PluginAssets::resolve($provider . '/' . $pluginName, $filename . '.' . $extension);

on kirby/src/Cms/PluginAssets.php

namespace Kirby\Cms;

use Kirby\Http\Response;
use Kirby\Toolkit\Dir;
use Kirby\Toolkit\F;

 * Plugin assets are automatically copied/linked
 * to the media folder, to make them publicly
 * available. This class handles the magic around that.
class PluginAssets
     * Clean old/deprecated assets on every resolve
     * @param string $pluginName
     * @return void
    public static function clean(string $pluginName)
        if ($plugin = App::instance()->plugin($pluginName)) {
            $root   = $plugin->root() . '/assets';
            $media  = $plugin->mediaRoot();
            $assets = Dir::index($media, true);

            foreach ($assets as $asset) {
                $original = $root . '/' . $asset;

                if (file_exists($original) === false) {
                    $assetRoot = $media . '/' . $asset;

                    if (is_file($assetRoot) === true) {
                    } else {

     * Create a symlink for a plugin asset and
     * return the public URL
     * @param string $pluginName
     * @param string $filename
     * @return string
    public static function resolve(string $pluginName, string $filename)
        if ($plugin = App::instance()->plugin($pluginName)) {
            $source = $plugin->root() . '/assets/' . $filename;

            if (F::exists($source, $plugin->root()) === true) {
                // do some spring cleaning for older files

                $target = $plugin->mediaRoot() . '/' . $filename;
                $url    = $plugin->mediaUrl() . '/' . $filename;

                // create the plugin directory first
                Dir::make($plugin->mediaRoot(), true);

                if (F::link($source, $target, 'symlink') === true) {
                    return Response::redirect($url);

                return Response::file($source);

return null;

I don’t know. Maybe symlinks don’t work when created through PHP. Does this happen locally or on a remote server?

i try locally, in a bitnami lamp container and a php built in server. same thing. only panel, page, site media are generated.

i just found that inside /media/panel/plugins the plugins assets are generated (only when i login to the panel)


that index.css is the index.css of my plugin


this test are from a fresh plainkit

Yes, the assets for panel plugins are created inside the `media/panel folder. They are not created as symlinks, only assets for frontend plugins.

i now. my plugin is not a panel plugin.

index.php (plugin)


Kirby::plugin('superwoman/superplugin', [
  'snippets' => [
    'header' => __DIR__ . '/snippets/weather.php'

snippets/weather.php (plugin)

<?= css( $page->url() . '/media/plugins/superwoman/superplugin/index.css'); ?>

index.css (plugin)

#weatherWidget {
  width: 100vw;
  height: 200px;
  display: block;
  background-color: green;
  background-color: blue;

media folder



i am doing something wrong?

Are you sure that is your file? Because the index.css in the Panel folder should be concatenated file with all styles from all panel plugins.

yes is it my file.

Provided you styles are in /plugins/superwoman/assets/css/index.css, your code should look like this:

<?= css(['media/plugins/superwoman/superplugin/css/index.css']) ?>

i changed it but nothing changed.

Have you also placed your styles into the /plugins/superwoman/assets/css/ folder?

What Kirby version are you using, btw? And have you tried it in a fresh Starterkit?

And what is your local dev environment?