🚚 How to migrate to Kirby Tips & tutorials
Skip to content
Next major version

Kirby 5 – alpha releases

Get a glimpse into the future at Kirby's next major release and help us polish it until the end of the year.

What to expect

As we have switched to a new versioning scheme with Kirby 4, the next major release of Kirby will be v5 and is expected for the end of 2024. v5 behaves to v4 a lot more than e.g. 3.8 to 3.7. It won't be such a massive step as v3 to v4 and therefore even easier to upgrade.

We are sharing a very first alpha with you. But please treat it for what it is: a very first alpha. This means that this version is far from complete. More features will be added over the next few months, and other parts will change again.

How to contribute

We would love to get your feedback. Try out the alpha with a fresh Starterkit or locally with one of your projects. And help us find any bugs or regressions.

Have a look at the breaking changes. An important one: v5 will require PHP 8.2.

We recommend to not use this alpha version in a production project.

And my license?

Kirby 5 will be a free upgrade for everyone with a Kirby Basic or Enterprise license for Kirby 4. Our new licenses include three years of major updates.

🎉 Features

Dark theme: Turn off the Panel lights

As requested from many – whether as personal preference or for making the Panel more accessible with certain sight conditions – you are able to activate a dark theme for the Panel from your account view in v5. #6299

We do expect to receive a lot of feedback on this feature and that the exact styling will be fine-tuned in the following pre-releases based on your feedback.

New in Alpha 2

Bring out the big files: Chunked uploads

Kirby 5 supports large Panel uploads. Uploads are no longer restricted by the server's upload_max_filesize limit but instead uploaded in chunks that are pieced back together on the server.

If you want to keep restricting the upload size to some limits, the file blueprint accept maxsize option is your friend.

View buttons: Put your own button up there

Kirby 5 adds new extensions that allow plugin developers to add custom view buttons to most views of the Panel (e.g. page, site, file, user, language). These buttons can be added alongside the default buttons, such as the preview button or settings dropdown button. #6393

There are different ways to define a custom button: in a blueprint, in the config.php, in a Panel area or as a full custom Vue component.

In a blueprint

To select which buttons to show on a particular view you can set the buttons option in the corresponding blueprint:

site/blueprints/pages/note.yml
buttons:
  - preview
  - settings
New in Alpha 2

This way, you can reference existing buttons by name and decide which ones to include and in what order. You can however also define new custom buttons:

buttons:
  - preview
  - settings
  myBytton:
    text: My Button
    link: https://getkirby.com
    theme: positive

The available options are based on the k-view-button component (better docs will follow until the final release).

In the config.php

Similarly to the blueprints, buttons can be defined in your config file. In this case, not for a specific template but in general for the different view types (page, file, site, user, system, ...):

site/config/config.php
'panel' => [
  'viewButtons' => [
    'site' => [
      'preview',
      'a' => [
        'icon'   => 'heart',
        'text'   => 'Kosmos',
        'theme'  => 'purple-icon',
        'target' => '_blank',
        'link'   => 'https://getkirby.com'
      ],
      'b-dropdown' => [
        'props' => [
          'icon'     => 'info',
          'text'     => 'Info',
          'dropdown' => 'my/dropdown/route'
        ]
      ],
      'c-component' => [
        'component' => 'my-custom-component',
        'props' => [
          'foo' => 'bar'
        ]
      ]
    ]
  ]
]

What you can see above are three different ways to define a custom button:

  • The first one directly defines the options. It's a shortcut that assumes these are the props for the k-view-button component.
  • In the second example, they are already wrapped inside the props key. But no component is defined, so k-view-button is used as well.
  • In the third example, we actually define a custom Vue component that should be used instead, alongside passing props to this component.

In a Panel area

If you do not want to define just one button via the config, but reuse it (or even ship it as part of your plugin), you can add them to the Panel area extension:

site/plugins/your-plugin/index.php
Kirby::plugin('custom/buttons', [
  'areas' => [
    'todos' => function () {
      return [
        'buttons' => [
          'todos.add' => function () {
            return [
              'props' => [
                'icon'   => 'add',
                'dialog' => 'todos/create'
              ]
            ];
          }
        ]
      ];
    }
  ]
]);

You have the same options for your return value: full component-props array or just props on top-level. In addition, you can also return directly a Kirby\Panel\Ui\Button\ViewButton object.

A custom Vue component

Some custom buttons might need more options, more interactivity, more glamour than <k-view-button> offers. Those can create their own Vue component in your plugin's JavaScript file:

site/plugins/your-plugin/index.js
panel.plugin("getkirby/custom-view-buttons", {
    viewButtons: {
        applause: {
            template: `<k-button icon="heart" variant="filled" theme="love" size="sm" @click="applause">Applause</k-button>`,
            methods: {
                applause() {
                    alert("👏");
                },
            },
        },
    },
});

You can then reference it by name in your blueprints or config file. Or if you want to pass props as well:

buttons:
  - preview
  - settings
  applause:
    component: k-applause-view-button
    props:
      foo: bar
New in Alpha 3

File previews: your media at a glance

With Kirby 5, we're opening up the preview part of the Panel's file view to more rich media previews that aren't just images.

It starts with basic previews for video and audio files that now ship as part of the core:

But you can also add custom file previews as plugin extensions to customize the preview for these formats or create previews for other file formats.

Custom file previews consist of two parts:

  • a PHP class defining what data is passed to the preview and what files this preview is used for
  • a Vue component to render the preview

Custom FieldPreview class

For a custom file preview, you need a new class that extends Kirby\Panel\Ui\FieldPreview. In this example, we're building a custom preview for .glb files that are used to display 3D data:

class GlbFilePreview extends FilePreview
{
    public function __construct(
        public File $file,
        public string $component = 'k-glb-file-preview'
    ) {
    }

    public static function accepts(File $file): bool
    {
        return $file->extension() === 'glb';
    }
}

This is the minimal setup for a custom class. What it does:

  • It defines which Vue component to use, in this case k-glb-file-preview which we will create later. If no component is specified, k-default-file-preview will be used.
  • Something you must define is the ::accepts($file) method. It is used to determine which preview class is used for a certain file. Kirby will loop through all available preview classes and use the first one that accepts the file.

Register your preview class

To use your custom file preview class, you need to register it as a plugin extension:

Kirby::plugin('your/plugin', [
    'filePreviews' => [
        GlbFilePreview::class
    ]
]);

Vue component

Finally, we need to create the Vue component that is used to render the preview. As above listed, we have named it k-glb-file-preview.

By default, file preview components will receive three default props:

  • url to the file
  • details array with basic file information (ideally used for <k-file-preview-details>)
  • image object with the thumb icon/image also used in sections etc. (we don't use it for this preview)

We also use the <k-file-preview-frame> component as wrapper for our actual 3D model, which adds a pattern background.

panel.plugin("getkirby/custom-file-preview", {
    components: {
        "k-glb-file-preview": {
            template: `
                <figure class="k-default-file-preview k-glb-file-preview">
                    <k-file-preview-frame>
                        <model-viewer :src="url" />
                    </k-file-preview-frame>

                    <k-file-preview-details :details="details" />
                </figure>
            `,
            props: {
                details: Array,
                url: String,
            },
        },
    }
});

The <model-viewer> element is from a library that helps to actually display the GLB file. I won't go into the details how to use it exactly (loading external script etc.). You can try the full custom file view.

✨ Enhancements

  • Improved support for IDE autocompletion and type hints for collection items ($pages, $files...) #6391
  • Radio and select fields: default prop supports Kirby queries #6459
  • New --color-l-min and --color-l-max CSS properties #6299
  • Relying front-end validation on native HTML invalid states #6099 #6320
    • Choice input: unselected choices get disabled when max is reached #6343
    • Added <k-input-validator> helper element to provide native form validation for complex/group inputs and fields #6321
  • site controller data will now always be merged as default data with data from page template specific controllers.https://feedback.getkirby.com/422
  • Thumbnails don't need to be regenerated when page sorting changes #6432
  • <k-link> (and subsequently <k-button> and <k-dropdown-item>) has a new download attribute to force direct download of a file
New in Alpha 2
  • New files.sort permission #1969
  • UUIDs are fully lowercased now to avoid issues between filesystems handling casing differently #6566
  • <k-tag>: new element and theme props #6569
  • <k-tags>: new element, element-tag and theme props #6569
  • New <k-tags-field-preview> component #6569
  • New <k-view-button> component #6540
  • New uploadAsChunks JS helper function #6421
  • New Panel\Panel::buttons() method that collects all defined buttons from all Panel areas #6541
  • New Panel\Ui namespace with basic Panel\Ui\Component and Panel\Ui\Button classes #6539
    • Each component renders as an array with a component, unique key and props entries
  • New Panel\Ui\Buttons\ViewButtons and Panel\Ui\Buttons\ViewButton classes #6542
    • responsible for gathering and transforming view buttons configured in blueprints, config files and/or Panel areas
    • renders them as PHP array definitions that can be handed to the dedicated Vue frontend components
    • Added Panel\Model::model() method
  • Backend classes for core view buttons #6545
New in Alpha 3
  • Sections: improved title and info wrapping #6447
  • Calendar input: first day of the week is chosen based on user language or date.weekday config option (0 for Sunday ... 6 for Saturday) #6635
  • Duplicating pages: All UUIDs within the copied page, its files and children that point to an object that got copied as - well will be replaced with the UUID of the copied version. If no copying files, any UUID pointing to a file within the copied page gets removed. #6567

🐛 Bug fixes

  • Headers with null as value are no longer added to JS API requests. #6435
  • $helper.object.clone is no longer deprecated. Please use it instead of structuredClone as this might cause issues down the road with Vue 3. #6479
Since Alpha 2
  • Fixed thumb issues resulting from EXIF orientation entry #2695
  • Kirby is better at removing failed file uploads from the server tmp directory #2476
  • Canceling the file upload dialog now also cancels ongoing uploads #6421
  • <k-header>: fixed wrapping with many buttons in narrow screens #6544
Since Alpha 3
  • Model hooks for actions: multiple hooks don't overwrite each others' changes to the model #6460 #2828

🚨 Breaking changes

  • Kirby requires at least PHP 8.2
  • Data/variables from your site controller will now be passed to all templates #6412
  • PHP (return) type hints have been added to many collection methods. If you are extending any collection classes, you might need to add the same to your methods.
  • CSS attribute selectors must be written fully qualified (e.g. [data-hidden="true"] as only [data-hidden] can start matching also elements where that attribute is false) #6109
  • While <k-writer> is still included as alias for <k-writer-input>, some use cases where you accessed the <k-writer> component via the $refs of <k-writer-input> have to be adapted #6172
  • Select field: empty prop was removed. Use combination of requiredplaceholder and default to replicate functionality #6459
  • <k-draggable>: the move callback function is receiving an event with an altered data structure
  • <k-form> and <k-fieldset> as well as many fields and inputs don't emit an invalid event anymore. Use native HTML invalid state of elements instead. #6099
  • novalidate prop has been removed from all elements but <k-form> #6099
  • Removed hasErorrs methods of k-fieldset #6173
  • Str::camel(), Str::camelToKebab(), Str::float(), Str::kebab(), Str::kebabToCamel(), Str::length(), Str::lower(), Str::safeTemplate(), Str::short(), Str::slug(), Str::snake(), Str::studly(), Str::substr(), Str::template(), Str::ucfirst(), Str::ucwords(), Str::unhtml(), Str::upper() and Str::widont() can no longer be called without a value argument (passing a null value still works) #6401
  • All content storage methods must now use the VersionId instead of a simple string. #6436
New in Alpha 2
  • Kirby requires the following browser versions to use the Panel (other browser requirements remain unchanged)
    • Safari 16+
    • Mobile Safari 16+
    • Android Browser 126+
    • Chrome for Android 126+
  • If file sorting was previously disabled via the files.update permission, the new file.sort permission has to be configured accordingly. #6589
  • Panel uploads can exceed the upload_max_filesize limit #6421
  • Increased PHP type hinting: when you're extending core classes, you might have to add the same type hints to your code as added to our core classes.
  • Image\Dimensions::forImage() now receives an Image\Image object #6591
  • Image\Exif::read() is now a static method that receives an absolute path to a file #6591
  • Thumb driver autoOrient option has been removed and now is always applied #6591
New in Alpha 3
  • Model action before hooks: rules get applied after the hook runs
  • <k-file-preview> got fully refactored. If you were replacing or extending it, your code likely will break. Check out the new custom file preview feature if you want to provide previews for specific files. #6578
  • Calendar dropdown input will show Sunday now as first day of the week (depending on the user's language). If you want to enforce Monday as first day of the week, you can set the date.weekday option to 1. #6635
  • All methods in *Rules classes are now marked to return void instead of a boolean #6660
  • Users without a role in their credentials file will now receive the default role (if exists), not the visitor role anymore #6656
  • Site::changes is now a new method to track changes across the site. The changes field is used as a storage for those changes and has thus become a reserved field for Kirby.
  • All methods in *Rules classes are now marked to return void instead of a boolean #6660

Removed deprecated

Removed Use instead
<k-aspect-ratio> <k-frame>
<k-autocomplete> -
<k-bar>: left, right and center slots default slot
<k-breadcrumb>: view prop Add as first entry to crumbs prop
<k-button>: tooltip prop title prop
<k-button-disabled> <k-button :disabled="true">
<k-button-link> <k-button link="...">
<k-button-native> <k-button>
<k-dialog>: disabled, icon and theme props. submit-button prop
<k-dropdown> <k-dropdown-content> as standalone
<k-grid>: gutter prop style="gap: " or variant prop
<k-header>: left and right slots buttons slot
<k-header>: tabs prop standalone <k-tabs>
<k-headline>: size prop tag prop
<k-headline>: theme prop -
<k-icon>: removed support for other viewBox than 0 0 24 24 Wrap icon in an <svg> element with corresponding viewBox attribute
<k-inside> <k-panel-inside>
<k-loader> <k-icon type="loader" />
<k-outside> <k-panel-outside>
<k-plugin-view> -
<k-progress>: set method value prop
<k-text>: theme prop -
<k-upload> $panel.upload module
<k-view> -
$store.drawer $panel.drawer
$store.notification $panel.notification
$store.dialog() $panel.dialog.open()
$store.drag() $panel.drag.start(type, data)
$store.fatal() $panel.notification.fatal()
$store.isLoading() $panel.isLoading
$store.navigate() -
JS $events.$on, $events.$off, $events.$emit $events.on, $events.off, $events.emit
Array.wrap() this.$helper.array.wrap()
Array.fromObject() this.$helper.array.fromObject()
myArray.split() this.$helper.array.split(myArray, delimiter)
myArray.sortBy() this.$helper.array.sortBy(myArray, sortBy)
Kirby\Cms\Model -
Kirby\Cms\Properties trait PHP native named properties
Kirby\Cms\File::contentFileDirectory() -
Kirby\Cms\File::contentFileName() -
Kirby\Cms\ModelWithContent::contentFile() $model->storage()->contentFile()
Kirby\Cms\ModelWithContent::contentFiles() $model->storage()->contentFiles()
Kirby\Cms\ModelWithContent::contentFileDirectory() -
Kirby\Cms\ModelWithContent::contentFileName() -
Kirby\Cms\ModelWithContent::contentFileExtension() -
Kirby\Cms\Page::contentFileName() -
Kirby\Cms\Site::contentFileName() -
Kirby\Cms\User::contentFileName() -

☠️ Deprecated

  • <k-writer> will be removed in a future version. Use <k-writer-input></k-writer-input> instead #6172
  • --color-backdrop CSS property has been deprecated. Use --overlay-color-back instead #6299
New in Alpha 2
  • <k-bubble>, <k-bubbles> and <k-bubbles-field-preview>. Use <k-tag>, <k-tags> and <k-tag-field-preview> instead. #6569
New in Alpha 3
  • Exception classes: passing $arg array will be removed in a future version. Use named arguments. #6618

♻️ Refactored

  • <k-writer> has been merged into <k-writer-input> #6172
  • Streamline input validation
    • Use <k-string-input> for all text inputs #6103
    • <k-slug-input> is now built on top of <k-string-input> #6320
    • Stricter native URL validation for <k-url-input> #6320
    • Removed vuelidate library #6099
  • Preparations for a move to Vue 3 in v6
    • <k-draggable> is directly built on top of SortableJS now #6387
    • Replace Vue $listeners #6107
    • Use strict CSS selectors for boolean (data) attributes #6109
    • Explicitly added $attrs.class to components that disable inheriting attributes #6332
    • Use more modern PHP syntax and PHPUnit assertions where applicable #6401
  • Improved class typing by adding Stringable interface to relevant classes #6433
  • New Kirby\Content\VersionId class to represent versions #6436
  • Refactored all content storage classes and models to use the new VersionId #6436
  • Refactor PlainTextStorageHandler implementation #6439
  • Remove option to pass null as language to internal ContentStorageHandler::exists method to avoid unwanted logic in handler methods. #6439
  • New Version class which inherits the logic from the ContentStorage handler and replaces it.
  • New Language::single() method to create a Language placeholder object in single language installations #6448
  • Use full language objects in ContentStorageHandler and PlainTextContentStorageHandler methods #6448
  • Convert the ContentStorageHandler interface to an abstract class #6449
  • Use "new" functions from PHP 8.0 #6476
    • str_contains()
    • str_starts_with()
    • str_ends_with()
New in Alpha 2
  • New Kirby\Api\Upload class to handle file uploads via the REST API #6421
New in Alpha 3

🧹 Housekeeping

  • Extended rule list for php-cs-fixer #6398
  • Tests: DRY $app property #6474
  • Replacing get_class() method with ::class notation #6475
New in Alpha 2
  • Vite: Make dev server by default https://sandbox.test instead of http://sandbox.test #6522
  • Turn panel JS modules fully reactive #6529
  • The ::setUpSingleLanguage and ::setUpMultiLanguage helper test methods in global TestCase class. #6561