ūüĆĪ The next big step: Kirby 4 Beta Learn more
Skip to content

Breaking changes

Removed deprecated code


  • We have added more native PHP type hints throughout the system. When extending core classes, this might require you to update your method to include those type hints as well.
  • When thumb generation fails, the image API now throws an error and no longer loads the original image.
  • Files: manipulate and focus are now used by core methods. They are no longer available for custom file methods and content fields with these names can only be accessed via e.g. $file->content()->get('focus').
  • I18n::translate(): If $fallback is an array and neither the array $key nor the array $fallback have a matching entry for the locale, the first element of the $key array will now be returned (not anymore the one from $fallback). If $fallback is a string, it will be considered with priority over both of these.
  • If overwriting the¬†hidden¬†field, it must return¬†'hidden' => true¬†now
  • Kirby\Uuid\Uuid¬†is now an abstract class, child classes need to implement the¬†id¬†method
  • Kirby\Uuid\Uuid::key()¬†can now also return¬†null¬†if the new¬†$generate¬†parameter isn't passed as¬†true¬†and no UUID has yet been generated for the model
  • Errors are no longer hidden when a response is converted to a string
  • Kirby\Cms\ModelWithContent¬†doesn't extend¬†Kirby\Cms\Model¬†anymore.
  • Removed the ::clone() method from Kirby\Cms\Auth\Status, Kirby\Http\Uri, Kirby\Cms\FileVersion, Kirby\Filesystem\Asset, Kirby\Filesystem\File, Kirby\Image\Image, Kirby\Cms\Plugin, Kirby\Cms\Role, Kirby\Cms\StructureObject and Kirby\Cms\ContentTranslation classes
  • Removed the ::hardcopy() method from Kirby\Api\Api, Kirby\Cms\Api,Kirby\Email\Email, Kirby\Email\Body, Kirby\Cms\Auth\Status, Kirby\Toolkit\Pagination, Kirby\Http\Uri, Kirby\Cms\FileVersion, Kirby\Filesystem\Asset, Kirby\Filesystem\File, Kirby\Image\Image, Kirby\Cms\Role, Kirby\Cms\StructureObject and Kirby\Cms\ContentTranslation classes
  • Removed ::site() method from Kirby\Cms\Plugin, Kirby\Cms\Role and Kirby\Cms\StructureObject classes
  • Removed ::kirby() method from Kirby\Cms\Role and Kirby\Cms\StructureObject classes
  • Unauthenticated API and Panel calls now return a correct 401 HTTP code instead of 403.
  • Registering a default block model now needs to be done with the key default, not Kirby\Cms\Block
  • new Structure()/new StructureObject() don't work anymore as before. Use Structure::factory()/StructureObject::factory() instead.
  • Structure object IDs aren't simply their collection index numbers anymore but receive a Str::uuid() as blocks do
  • Items::factory() and all inheriting classes throw an exception now if malformed data is passed
  • Users field doesn't automatically uses the current user as default, add default: true to keep this functionality
  • Blocks: Removed keyboard shortcut to move block focus up/down
  • Extending the internal $model->contentFile(), $model->contentFiles(), $model->contentFileDirectory(), $model->contentFileExtension(), $model->contentFileName(), $model->readContent() and $model->writeContent() methods in a page model will no longer have an effect as these methods are no longer called by the core. Please extend the new Kirby\Content\PlainTextContentStorageHandler class instead and return an instance of your custom class from $model->storage(). Please note that the interface of PlainTextContentStorageHandler is internal and may change in the future.
  • The $translations->start() and $translations->stop() methods were no longer in use and have been removed. Content files are automatically converted by the Language class.
  • $languages->codes() now returns ['default'] for single language installations.


  • Removed this.$config.search from Panel
  • Area search plugins receive two additional arguments for their query callback: $limit and $page to be used to paginate the results. They should then return an array with entries results and pagination. #5191
  • this.$library.autosize¬†has been removed, wrap <textarea> elements inside <k-autosize> element instead.
  • Defining the footer slot in <k-dialog> will no longer wrap the slot content in the <footer> element. This can now be more flexibly handled by using <k-dialog-footer> inside the slot.
  • The form drawer no longer automatically closes on submit. This is introducing the same behaviour as in dialogs. Auto-closing might often not be the intended result of submitting the form and it's easier to close it manually in a submit handler than to re-open it again.
  • this.$store.state.isLoading¬†is no longer available. You can now use¬†window.panel.isLoading¬†or¬†this.$panel.isLoading¬†in Vue components to access the current loading state.
  • this.$store.state.dialog¬†is no longer available. Use¬†this.$panel.dialog¬†instead.
  • Removed¬†this.$store.state.drag, use¬†window.panel.drag/this.$panel.drag¬†instead.
  • k-button¬†,¬†k-link,¬†k-headline and k-content-item only emit the¬†click¬†event. For other native events, use the¬†.native¬†event listener modifier
  • Native events (e.g.¬†click,¬†dbclick) need the¬†.native¬†modifier now when used on¬†k-block¬†and¬†k-block-title
  • Need to use¬†.native¬†modifier for all previous event listeners on¬†k-box and¬†k-image