Skip to content

Kirby 4.1.2

panel

Options for the Panel

Disabling the Panel

If you don't need the Panel at all and you just want to work in your content folder, you can switch the Panel off in your config file.

/site/config/config.php
return [
  'panel' => false
];

Allow the Panel to be installed on a remote server

As a security measure, you cannot install the Panel on a public server by default. To allow this, you can enable the panel.install option:

/site/config/config.php
return [
  'panel' =>[
    'install' => true
  ]
];

It's recommended to remove this setting after the installation on your remote server is complete.

Move the Panel to a different URL

If you want to add a little bit of additional security to your site and hide the Panel behind a different URL, you can set the URL slug in your config.

/site/config/config.php
return [
  'panel' => [
    'slug' => 'super-secret-admin-area'
  ]
];

Your Panel is now accessible at http://yourdomain.com/super-secret-admin-area

Since 4.0.0

Panel menu

You can customize what entries the Panel menu is showing and even add your own:

/site/config/config.php
return [
  'panel' => [
    'menu' => [
      'site' => [
        'label' => 'Overview'
      ],
      '-',
      'notes' => [
        'icon'  => 'pen',
        'label' => 'Notes',
        'link'  => 'pages/notes',
        'current' => function (string $current): bool {
          $path = Kirby\Cms\App::instance()->request()->path()->toString();
          return Str::contains($path, 'pages/notes');
        }
      ],
      'users'
    ]
  ]
];

This example shows the three ways you can define a menu entry:

  • Include a default Panel area by simply naming it (users in the example)
  • Extend a default Panel area by naming it and passing options that should overwrite the defaults (customizing the label for site in the example)
  • Create your own menu entry

When creating your own entry, include an icon and label as well as either a link or dialog. The current callback can be used to add some logic for when the menu entry should be shown as the currently active one.

Note that you need to explicitly list all items you want in the menu. Custom menu entries will not automatically be merged with the default ones.

When you add a menu entry that links to a page or file, you probably also want to overwrite the current callback for the site item, otherwise your menu entry as well as the site entry will be active at the same time:

'site' => [
  'current' => function (): bool {
        // the links of all your custom menu entries
        $links = ['pages/notes', 'pages/albums'];

        $path  = Kirby\Cms\App::instance()->request()->path();
        return A::every($links, fn ($link) => Str::contains($path, $link))
  },
],

If you need to use the $kirby object to set up your menu entries, wrap the option in a closure:

return [
  'panel' => [
    'menu' => function ($kirby) {
      return [...]
    }
  ]
];

Custom Panel CSS

We have made the design of the Panel as usable, beautiful and reduced as possible so that you or your clients can fully concentrate on creating content. However, if you want to spice it up a little or adjust to your or your clients branding, you can do that with your own custom stylesheet file. Add it to your config.php file like this:

/site/config/config.php
return [
  'panel' => [
    'css' => 'assets/css/custom-panel.css'
  ]
];

If you have multiple environments like staging, production etc., you can use different stylesheets per environment in your domain-specific config files. Shared styles can be imported into each domain-specific stylesheet with an import statement:

@import url("custom.css");

More information:

Instead of adding it to your config.php, CSS to be applied globally in the Panel can also be added via a plugin: if an index.css file is present in the root folder of a plugin, it will be automatically loaded into the Panel.

Custom Panel JS

You can also add your own custom Panel scripts in the config.php, giving you even more power to bend the Panel to your liking.

/site/config/config.php
return [
  'panel' => [
    'js' => 'assets/js/panel.js'
  ]
];

Custom Panel Favicon

To offer a full white-label solution for your customers, you can even set a custom favicon for the Panel. From a simple implementation…

/site/config/config.php
return [
  'panel' => [
    'favicon' => 'assets/favicon.ico'
  ]
];

…to full control over all formats:

/site/config/config.php
return [
  'panel' => [
    'favicon' => [
      'apple-touch-icon' => [
        'type' => 'image/png',
        'url'  =>  'assets/apple-touch-icon.png',
      ],
      'shortcut icon' => [
        'type' => 'image/svg+xml',
        'url'  => 'assets/favicon.svg',
      ],
      'alternate icon' => [
        'type' => 'image/png',
        'url'  => 'assets/favicon.png',
      ]
    ]
  ]
];

Default Panel language

You can set the default Panel language that is used before a user logs in or when the user does not have a valid language configured:

/site/config/config.php
return [
  'panel' => [
    'language' => 'de'
  ]
];

If the Panel language is not configured, Kirby will default to English on single-language sites and the default content language on multi-language sites.

KirbyText/Markdown

If false, the Panel formatting buttons and drag and drop for files and links will create regular Markdown instead of KirbyTags.

/site/config/config.php
return [
  'panel' => [
    'kirbytext' => false
  ]
];

Drag texts

You can define custom callback functions (pageDragText or fileDragText) for the text that gets inserted when dragging a page or a file on a textarea, e.g.

return [
  'panel' => [
    'kirbytext' => [
      'fileDragText' => function(Kirby\Cms\File $file, $url) {
        if($file->extension() === 'jpg') {
          return sprintf('(screenshot: %s)', $url);
        }

        if($file->type() === 'video') {
          return sprintf('(video: %s loop: true)', $url);
        }

        return null;
      },
      'pageDragText' => function (Kirby\Cms\Page $page) {
        return sprintf('Check out this great page: %s', $page->url());
      },
    ],
  ],
];

Allow frame embedding

The Panel sets the Content-Security-Policy: frame-ancestors 'none' header by default. This protects against clickjacking attacks by preventing embedding in frames on other pages.

If you need to embed the Panel into another page or site, you can customize this header:

return [
  'panel' => [
    // allow frame embedding from the same domain
    'frameAncestors' => true,

    // allow frame embedding from the same *and* from the specified domains
    'frameAncestors' => ['*.example.com', 'https://example.com'],

    // allow frame embedding on any domain (not recommended)
    'frameAncestors' => '*',
  ]
];

Only allow embedding if you fully control the domains you allowlisted. Otherwise your site may be vulnerable against clickjacking attacks. Read more at OWASP.