Releases: getkirby/kirby
5.0.0-rc.2
Pre-release notes
https://getkirby.com/releases/5
Changelog since 5.0.0-rc.1
✨ Enhancements
page.changeTitle
andpage.changeSlug
hooks receive a new optional$language
parameter, which passes a fullLanguage
object. #7227- New
$filename
arguments forAsset::mediaPath()
,Asset::mediaUrl()
andAsset::mediaRoot()
to keep the Asset class consistent with the v5 changes in theFile
class #7241 - New
_preview
param for preview iframe URLs. This new parameter can now be used in the frontend to adjust the UI for when being shown inside Panel preview view. #7225
🐛 Fixed regressions from RC-1
- When changing the title for a
Page
or theSite
or the slug for aPage
(in a secondary language) , the::changeTitle()
and::changeSlug()
methods will check for an existingchanges
version and store them there as well. Otherwise, the changed title or slug would get reverted as soon as thechanges
version is published. #7227 - When changing the sort value for a
File
, theFile::changeSort()
, the method will check for an existingchanges
version and store it there as well. Otherwise, the changed sorting number would get lost as soon as the changes are published. #7230 - Added missing
Asset::mediaDir()
method. Thumbnails for assets can now be generated properly again. #7238 - Fixed empty writer toolbar when marks are disabled and inline mode is activated #7231
- When a structure field has disabled fields with a default value, the default value is now properly submitted and saved again. #7233
- Title fields in forms are no longer removed by accident #7232
Kirby\Form\Field
andKirby\Form\FieldClass
normalize type and name attributes and set the name to lowercase. This will now bring back the default column setup in structure fields if you use camelCase or anything else than lowercase for field names. #7236
🧹 Housekeeping
- Updated outdated JS dependencies
5.0.0-rc.1
Pre-release notes
https://getkirby.com/releases/5
Changelog since 5.0.0-beta.6
We are only listing the differences here from previous betas. For the full changelog for v5, please check out: https://getkirby.com/releases/5/changelog
🎉 Features since previous betas
- Language variables with multiple translation strings (for different counts) can now be edited in the Panel using the new entries field #7173

✨ Enhancements from previous betas
- New
Model::versions()
method, which returns an array with the two versionslatest
andchanges
. If there's no changes version, thelatest
will be used. #7153 - New
Version::sibling()
method to fetch a different version for the same model #7161 - The Fields class constructor now accepts a string value for the language parameter #7164
- The Fields class will fall back to the site if no model is given. #7164
Fields::passthrough()
will resolve closure values (just like fill and submit) #7164- Add missing since tags to Fields class methods. #7164
- Added missing since tags to Form class methods. #7165
- Support for named parameters in Form constructor. Passing the
$props
array is still supported but deprecated. #7166 - Support for named parameters in
Form::for()
. Passing the$props
array is still supported here as well, but also deprecated. #7166 panel.content.changes()
has been renamed topanel.content.diff()
- New
panel.content.hasDiff()
method. - New
panel.content.version(versionId)
method - New
panel.content.versions()
method - The
content
andoriginal
props have been removed from all model views. - A new
versions
prop has been added instead withlatest
andchanges
as child objects. - The
changes
property in the<k-model-tabs>
component has been renamed todiff
. - hasChanges has been renamed to hasDiff in all components.
- The PreviewView component and backend code has been radically simplified and its UX has been improved. You can now switch between versions and languages easily. #7220
changes.mp4
- The old open button is back in each model view and a new preview button has been added. #7220
🐛 Fixed regressions and issues from previous betas
- Support
false
to disable view buttons ****[#7139](#7139) - Fixed file template change [#7145](#7145)
- Fields with null values will be removed again when saving changes. This
will also fix the removal of the focus point for images. [#7022](#7022) - The content.js module no longer merges changes with the originals.
- The content.js module now also recognizes removed fields when finding changes to show the form controls.
- The
Fields::passthrough()
method no longer supports passing an empty array to reset all passthrough values. [#7164](#7164) - Tags field preview: is selectable again [#7176](#7176)
- Fix UUID access in after hook [#7180](#7180)
- Creating a file content translation no longer throws an exception [#7184](#7184)
- Latest content file for translations is no longer created too early [#7185](#7185)
- Custom slug in secondary language is no longer overwritten on publish [#7183](#7183)
- Deleting pages and files no longer results in a PHP warning when PHP is compiled with localized warning messages [#7209](#7209)
- Grouping collections by closure works again [#7215](#7215)
- Fix
LC_MESSAGES
constant check [#7224](#7224)
🚨 Breaking changes from/since previous betas
- Removed the new ExceptionField class again [#7167](#7167)
- The
content
prop has been removed from all model views. - Removed
Kirby\Content\Version::prepareForContent()
again [#7192](#7192) - The PreviewButton class now uses
preview
as icon andPreview
as text. [#7220](#7220) - All model views now use the new
OpenButton
instead of thePreviewButton
and the refactoredPreviewButton
in addition to that. [#7220](#7220) - The
PreviewDropdownButton
has been removed [#7220](#7220)
☠️ Deprecated since previous betas
Kirby\Panel\Model::content()
is deprecated. UseModel::versions()[’changes’]
instead. [#7153](#7153)Form::content()
is deprecated. UseForm::toStoredValues()
instead. [#7166](#7166)Form::data()
is deprecated. UseForm::toStoredValues()
instead. [#7166](#7166)Form::strings()
is deprecated. UseForm::toStoredValues()
instead. [#7166](#7166)Form::values()
is deprecated. UseForm::toFormValues()
instead. [#7166](#7166)
♻️ Refactored since previous betas
- Remove
$defaults
argument from form and field methods wherever possible, to clean up default value handling [#7134](#7134)- Removed from
Field::toFormValue
- Removed from
Field::toStoredValue
- Removed from
FieldClass::toFormValue
- Removed from
FieldClass::toStoredValue
- Removed from
Fields::toFormValues
- Removed from
Fields::toStoredValues
- Removed from
Form::toFormValues
- Removed from
Form::toStoredValues
- Removed from
- Use
Fields::for
method to simplify theModelWithContent::createDefaultContent
method and get rid of the Form class usage. [#7149](#7149) - Use the Fields class to improve Version comparison. This will especially help to improve the performance of comparing two versions, as the field instances can be reused. [#7150](#7150)
- New
Version::errors()
method [#7155](#7155) - New
Version::isValid()
method, which is now used inModelWithContent::isValid()
instead of the Form class. [#7155](#7155) - The Fields class is now used instead of Form in the Changes controller to save changes. [#7156](#7156)
- Refactor form and toStoredValue code in the EntriesField class [#7175](#7175)
- Consistent VersionId code style [#7181](#7181)
🧹 Housekeeping since previous betas
- Updated JS and PHP dependencies
4.8.0-rc.1
4.7.2
4.7.1
Update:
Unfortunately, this security release contains a regression in thumbnail generation for public folder setups. If you are working with a public folder setup, please use version 4.7.2.
🚨 Security
This release fixes three path traversal vulnerabilities in the Kirby core:
Description | Severity | CVE ID |
---|---|---|
Path traversal of snippet names during file system lookup | Medium (6.3) | CVE-2025-30159 |
Path traversal of collection names during file system lookup | Medium (6.3) | CVE-2025-31493 |
Path traversal in the router for PHP's built-in server | Low (2.3) | CVE-2025-30207 |
TL;DR
The first two vulnerabilities only affect Kirby sites that call the snippet()
or collection()
helpers with dynamic name values that could be controlled by an attacker. Sites that only use fixed calls to the snippet()
or collection()
helpers (i.e. calls with a simple string for the snippet/collection name) are not affected.
The last vulnerability only affects Kirby setups that use PHP's built-in server. Such setups are commonly only used during local development.
Impact
All three vulnerabilities have in common that they can be exploited via path traversal. By using special elements such as ..
and /
separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the ../
sequence, which in most modern operating systems is interpreted as the parent directory of the current location.
The missing path traversal checks allowed attackers to navigate and access all files on the server that were accessible to the PHP process, including files outside of the relevant system roots or even outside of the Kirby installation. Depending on the vulnerability, the existence of the traversed file could be revealed or contained PHP code could be executed.
You can read more about the vulnerabilities and their impact in the security advisories linked above.
Credits
Thanks to Bruno Meilick (@bnomei) and Tobias Möritz (@tobimori) for their responsible disclosure and for bringing this type of attack vector to our attention.
Note
If you deliberately use path traversal with the snippet()
helper in your projects, these uses will break after updating to this patched version. You can read more about this and possible alternatives in the security advisory.
✨ Enhancements
- Improve
$page->dirname()
/diruri()
docblocks #7102
🐛 Bug fixes
- Fix block selector not closing after pasting block #7087 (thanks to @fnwbr)
Media::thumb()
: Fix passingFile $model
and test logic #7142- Fix duplicated slash in the
router.php
for the built-in PHP server #7188
🧹 Housekeeping
3.10.1.2
🚨 Security
This release fixes three path traversal vulnerabilities in the Kirby core:
Description | Severity | CVE ID |
---|---|---|
Path traversal of snippet names during file system lookup | Medium (6.3) | CVE-2025-30159 |
Path traversal of collection names during file system lookup | Medium (6.3) | CVE-2025-31493 |
Path traversal in the router for PHP's built-in server | Low (2.3) | CVE-2025-30207 |
TL;DR
The first two vulnerabilities only affect Kirby sites that call the snippet()
or collection()
helpers with dynamic name values that could be controlled by an attacker. Sites that only use fixed calls to the snippet()
or collection()
helpers (i.e. calls with a simple string for the snippet/collection name) are not affected.
The last vulnerability only affects Kirby setups that use PHP's built-in server. Such setups are commonly only used during local development.
Impact
All three vulnerabilities have in common that they can be exploited via path traversal. By using special elements such as ..
and /
separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the ../
sequence, which in most modern operating systems is interpreted as the parent directory of the current location.
The missing path traversal checks allowed attackers to navigate and access all files on the server that were accessible to the PHP process, including files outside of the relevant system roots or even outside of the Kirby installation. Depending on the vulnerability, the existence of the traversed file could be revealed or contained PHP code could be executed.
You can read more about the vulnerabilities and their impact in the security advisories linked above.
Credits
Thanks to Bruno Meilick (@bnomei) and Tobias Möritz (@tobimori) for their responsible disclosure and for bringing this type of attack vector to our attention.
Note
If you deliberately use path traversal with the snippet()
helper in your projects, these uses will break after updating to this patched version. You can read more about this and possible alternatives in the security advisory.
3.9.8.3
🚨 Security
This release fixes three path traversal vulnerabilities in the Kirby core:
Description | Severity | CVE ID |
---|---|---|
Path traversal of snippet names during file system lookup | Medium (6.3) | CVE-2025-30159 |
Path traversal of collection names during file system lookup | Medium (6.3) | CVE-2025-31493 |
Path traversal in the router for PHP's built-in server | Low (2.3) | CVE-2025-30207 |
TL;DR
The first two vulnerabilities only affect Kirby sites that call the snippet()
or collection()
helpers with dynamic name values that could be controlled by an attacker. Sites that only use fixed calls to the snippet()
or collection()
helpers (i.e. calls with a simple string for the snippet/collection name) are not affected.
The last vulnerability only affects Kirby setups that use PHP's built-in server. Such setups are commonly only used during local development.
Impact
All three vulnerabilities have in common that they can be exploited via path traversal. By using special elements such as ..
and /
separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the ../
sequence, which in most modern operating systems is interpreted as the parent directory of the current location.
The missing path traversal checks allowed attackers to navigate and access all files on the server that were accessible to the PHP process, including files outside of the relevant system roots or even outside of the Kirby installation. Depending on the vulnerability, the existence of the traversed file could be revealed or contained PHP code could be executed.
You can read more about the vulnerabilities and their impact in the security advisories linked above.
Credits
Thanks to Bruno Meilick (@bnomei) and Tobias Möritz (@tobimori) for their responsible disclosure and for bringing this type of attack vector to our attention.
Note
If you deliberately use path traversal with the snippet()
helper in your projects, these uses will break after updating to this patched version. You can read more about this and possible alternatives in the security advisory.
5.0.0-beta.6
Pre-release notes: https://getkirby.com/releases/5
Changelog since 5.0.0-beta.5
✨ Enhancements
- Form improvements #7114 #7115 #7125 #7126
- New
Fields::validate()
method - New
Form::validate()
method, which is a proxy forFields::validate()
- Use
Form::validate()
inModelWithContent::update()
- New
::isTranslatable($language)
method forField
andFieldClass
- New
::extendModels()
method in HasModels trait. - New
::isSubmittable
method forField
andFieldClass
- New
✨Enhancements from previous betas
- Form and Field improvements #7117 #7123
FieldClass::fill()
now returns static instead of void. This no longer introduces a difference to the Field class and also makes::fill()
chainable, which can be handy.- Value-related methods and properties are now all moved to the Value mixin
Required
methods and properties are now moved to the Validation mixin::fill()
is no longer setting anull
default value, which makes no sense.
🐛 Fixed regressions from previous betas
- Fixed notice issue in the
Field::fill()
method when no computed properties exist. #7113 - Avoid broken field component state after
:fill()
method call #7113 - Fixed named exports on global Vue constructor for plugins (thx @johannschopplich)
- Fix
App::$events
initialization #7121 - User and page models can be registered without lowercase keys again #7124
🚨 Breaking changes
- All
Kirby\Blueprint
classes have been removed. Those classes never were involved in rendering Blueprints. We used a small part of it for the field options, but had them mostly in there in preparation for a Blueprint code refactoring that never happend as planned. The removal should not cause any damage, because the code was internal and never useful for plugins. But we still want to mention it here. #7119 - The Field class no longer exposes public properties
value
anddefault
. Public access to properties has not been documented or encouraged anywhere, so it technically should not have been used anyway. #7123 ::isSaveable
has been renamed to::hasValue
in theFieldClass
class. #7125
♻️ Refactored
k-panel-menu
: simplify gap #7108
♻️ Refactored from previous betas
::isSaveable
has been renamed to::hasValue
in all form classes. #7125
🧹 Housekeeping
- Update JS dependencies
5.0.0-beta.5
Pre-release notes: https://getkirby.com/releases/5
Changelog since 5.0.0-beta.4
✨ Enhancements
- Make
Vue
bundle accessible as JS Import map #7107 - Use type hinting in
A::get()
instead of theis_array
check. Results in a 2% improvement of total execution time according to tests by @bnomei #7096
🐛 Bug fixes
- Users field preview: displays HTML correctly #7065
- The site preview button is now hidden when the home page preview is disabled #7070
- Fixed cases where after resorting a page, the parent's children collection was incomplete #7044
- Ensure same listing style (breaking or not) in list view #6904
🐛 Bug fixes from previous betas
- Image preview: fix coords input squeezing image #7048
- Fixed return type issue when a page has a custom model #7084
- Pages with drafts can now be deleted properly again #7097
🚨 Breaking changes
A::get()
no longer accepts a first argument that is not an array
🧹 Housekeeping
- Removed deprecated icons #7046
- Removed
circle-outline
. Usecircle
instead - Removed
circle-funnel
. Usefilter
instead - Removed
heart-outline
. Useheart
instead - Removed
image-outline
. Useimage
instead
- Removed
- Small Vue fixes in preparation for Vue 3. We plan to add Vue 3 support in Kirby 6, but already add step by step preparations with every release #7106
4.7.0
✨ Enhancements
- New
session::store
core component: return your customSessionStore
handler #6961 - Show info text when variable is an array #6930
- The Vue template compiler can be switched off in the config. This will load the vue runtime version. Plugins and the lab views that rely on the template compiler will no longer work.
// `/site/config/config.php` return [ 'panel' => [ 'vue' => [ 'compiler' => false ] ] ];
- Panel: user needs to confirm current password when changing their own password or the password of another user (e.g. as admins) #6971
- Panel system view: Some security checks will be skipped on local setups #6932
- The security check for an accessible
kirby
folder now uses theLICENSE.md
file instead ofcomposer.json
to avoid false-positive blocks by web application firewalls #6932
🐛 Bug fixes
- Custom sections: fixed issue where Vue mixin would overwrite
load
method #6809 - Requests for a page's
html
representation get redirected to the normal page URL without extension #6509 - Panel menu: fixed backdrop on narrow viewports #6983
- Link dialog: fixed permalinks for default language #6982
- Fixed file template wrongfully being written to secondary language content file #6739
- Add missing title for toolbar buttons #6998