NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #3801 most downloaded on Packagist
Craft CMS
Last release today
07 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Most releases are documented
notes for 41 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
1343 releases · first in 2013
The Login page now displays the Login Page Logo above the login form, rather than within the header.
allowAdminChanges is disabled, indicating that settings are read-only. (#16563)craft\web\User::getDefaultReturnUrl().cp.login.alternative-login-methods hook to the system login template.allowAdminChanges was false. (#16509)craft\services\Sso::findUser() wasn't accounting for soft-deleted users. (#16491)One column per quarter.
Fixed a bug where all multi-byte characters were getting stripped out of search indexes.
craft\elements\Asset::getSrcset() (and srcset method arguments) weren’t producing the correct transform URLs if the asset already had a named transform applied to it. (#16486)utils/delete-empty-volume-folders command was deleting folders that had no assets directly, but had subfolders. (#16388)Deprecated the ucfirst Twig filter. capitalize should be used instead.
allowAdminChanges is disabled. (#16265)elementChip() and elementCard(). (#16267)elements/delete-all-of-type command. (#16423)utils/delete-empty-volume-folders command. (#16388)resave commands.resave commands’ --drafts, --provisional-drafts, and --revisions options can now be set to null, causing elements to be resaved regardless of whether they’re drafts/provisional drafts/revisions.systemTemplateCss config setting. (#16344)loginPath, logoutPath, setPasswordPath, and verifyEmailPath config settings are now respected in headless mode. (#16344)_partials/entry.twig as opposed to _partials/entry/typeHandle.twig. (#16125)primarySite global Twig variable. (#16370)PHP_INT_MAX global Twig variable.duration Twig filter now has a language argument. (#16332)indexOf Twig filter now has a default argument, which can be any integer or null. (-1 by default for backwards compatibility.){% cache %} tags now cache any JavaScript import map entries registered via craft\web\View::registerJsImport() within them.{% requireAdmin %} tag now supports passing a boolean value, which determines whether administrative changes must be allowed (defaults to true).withProvisionalDrafts element query param, which causes the resulting elements to be replaced with any provisional drafts for the current user.orderBy and select params (e.g. myDateField.tz). (#16157)where params. (#16318)0, and a number formatted with the correct decimal points when using MySQL. (16369)affiliatedSite and affiliatedSiteId user query and GraphQL params. (#16174)affiliatedSiteHandle and affiliatedSiteId user GraphQL field. (#16174)X-Craft-Site header set to a site ID or handle. (#16367)value keys set to element instances or IDs. (#16255)disable2fa config setting. (#16426)config/redirects.php. (#16355)ucfirst Twig filter. capitalize should be used instead.craft\attributes\EnvName.craft\base\ConfigurableComponentInterface::getReadOnlySettingsHtml(). (#16265)craft\base\CrossSiteCopyableFieldInterface. (#14056)craft\base\Element::EVENT_DEFINE_ALT_ACTIONS. (#16294)craft\base\ElementInterface::getAltActions(). (#16294)craft\base\ElementInterface::getIsCrossSiteCopyable(). (#14056)craft\base\ElementTrait::$viewMode. (#16324)craft\base\Field::copyCrossSiteValue(). (#14056)craft\base\Field::dbTypeForValueSql().craft\base\Indicative.craft\base\NestedElementTrait::ownerType().craft\base\PluginTrait::$hasReadOnlyCpSettings. (#16265)craft\base\Plugininterface::getReadOnlySettingsResponse(). (#16265)craft\base\conditions\BaseElementSelectConditionRule::allowMultiple().craft\base\conditions\BaseElementSelectConditionRule::getElementIds().craft\base\conditions\BaseElementSelectConditionRule::setElementIds().craft\elements\User::$affiliatedSiteId.craft\elements\User::getAffiliatedSite().craft\elements\User::getHasPassword().craft\elements\conditions\entries\FieldConditionRule.craft\elements\db\ElementQueryInterface::getFieldLayouts().craft\elements\db\NestedElementQueryTrait::fieldLayouts().craft\events\DefineAltActionsEvent.craft\events\RedirectEvent. (#16355)craft\fieldlayoutelements\BaseField::actionMenuItems().craft\fieldlayoutelements\BaseField::isCrossSiteCopyable().craft\fields\BaseRelationField::gqlFieldArguments().craft\fields\Color::$allowCustomColors. (#16249)craft\fields\Color::$palette. (#16249)craft\fields\Color::getDefaultColor(). (#16249)craft\fields\Color::setDefaultValue(). (#16249)craft\fields\Link::$fullGraphqlData.craft\fields\data\LinkData::$ariaLabel.craft\fields\data\LinkData::$class.craft\fields\data\LinkData::$id.craft\fields\data\LinkData::$rel.craft\fields\data\LinkData::$title.craft\fields\data\LinkData::$urlSuffix.craft\fields\data\LinkData::getElementQuery(). (#16458)craft\fields\data\LinkData::getUrl().craft\fields\linktypes\BaseElementLinkType::elementQuery().craft\gql\types\LinkData.craft\gql\types\generators\LinkDataType.craft\helpers\Cp::colorHtml().craft\helpers\Cp::readOnlyNoticeHtml(). (#16265)craft\helpers\Image::EXIF_IFD0_ROTATE_0_MIRRORED.craft\helpers\Image::EXIF_IFD0_ROTATE_0.craft\helpers\Image::EXIF_IFD0_ROTATE_180_MIRRORED.craft\helpers\Image::EXIF_IFD0_ROTATE_270_MIRRORED.craft\helpers\Image::EXIF_IFD0_ROTATE_90_MIRRORED.craft\helpes\Html::disableInputs(). (#16265)craft\mail\Mailer::$siteId.craft\mail\Mailer::$siteOverrides.craft\models\AssetIndexingSession::$forceStop. (#16435)craft\models\EntryType::$original. (#16453)craft\models\EntryType::$validateHandleUniqueness. (#16453)craft\models\EntryType::getUsageConfig(). (#16453)craft\models\MailSettings::$siteOverrides.craft\services\Elements::canSaveCanonical().craft\services\Entries::getEntryType(). (#16453)craft\services\Gql::getFieldLayoutArguments().craft\web\ErrorHandler::EVENT_BEFORE_REDIRECT. (#16355)craft\web\RedirectRule. (#16355)craft\web\UrlRule::regexTokens().craft\web\User::getImpersonator().craft\web\User::getImpersonatorId().craft\web\User::setImpersonatorId().craft\web\View::clearJsImportBuffer(). (#16414)craft\web\View::registerJsImport(). (#16414)craft\web\View::registerScriptWithVars(). (#16414)craft\web\View::setTwig().craft\web\View::startJsImportBuffer(). (#16414)craft\web\twig\variables\Cp::EVENT_REGISTER_READ_ONLY_CP_SETTINGS. (#16265)GuzzleHttp\Client is now instantiated via Craft::createObject(). (#16366)craft\elements\Entry::getAvailableEntryTypes() now has a $triggerEvent argument.craft\elements\NestedElementManager::getIndexHtml() now supports passing defaultSort in the $config array. (#16236)craft\elements\conditions\entries\MatrixFieldConditionRule is now an alias of FieldConditionRule.craft\helpers\App::envConfig() now checks for a craft\attributes\EnvName attribute on public properties, which can be used to override the environment variable name (sans prefix) that is associated with the property.craft\helpers\Cp::elementIndexHtml() now supports passing defaultSort in the $config array, when sources is null. (#16236)craft\helpers\Cp::fieldHtml() now supports passing an actionMenuItems array in the config. (#16415)craft\helpers\DateTimeHelper::humanDuration() now has a $language argument. (#16332)craft\models\ImageTransform objects are now instantiated via Craft::createObject(). (#15646)craft\models\Site now implements craft\base\Chippable.craft\services\Revisions::createRevision() no longer creates the revision if an EVENT_BEFORE_CREATE_REVISION event handler sets $event->handled to true and at least one revision already exists for the element. (#16260)defineCardAttributes() methods can now return a placeholder value set to a callable.craft\controllers\RedirectController. (#16355)craft\elements\User::EVENT_REGISTER_USER_ACTIONS.craft\elements\User::IMPERSONATE_KEY. craft\web\User::getImpersonatorId() should be used instead.craft\fields\Color::$presets. (#16249)craft\fields\Link::$showTargetField._includes/forms/autosuggest.twig now supports a suggestTemplates variable._includes/forms/colorSelect.twig now supports options and withBlankOption variables._includes/forms/componentSelect.twig now supports a showIndicators variable._includes/forms/entryTypeSelect.twig now supports an allowOverrides variable._includes/forms/selectize.twig now supports a color property in option data, which can be set to a hex value or a color name.Craft.EntryTypeSelectInput.Craft.IntervalManager. (#16398)/login (per the loginPath config setting) if a site template doesn’t exist in the same location. (#16344)/login (per the loginPath config setting) to complete the verification process. (#16344)systemTemplateCss config setting. (#16344)preview/<elementId> control panel route, which renders Live Preview in a standalone mode for the element. (#16441)actions/app/health-check) now send no-cache headers by default. (#16364)craft\config\GeneralConfig::safeMode() set Safe Mode to false by default.relatedTo* GraphQL arguments to null. (#16433)craft\events\DefineAssetUrlEvent::$transform wasn’t always defined for assets’ EVENT_BEFORE_DEFINE_URL and EVENT_DEFINE_URL events. (#16464)* weren’t respecting caseInsensitive: true. (#16409)Fixed a bug where the control panel could display a notice about the Craft CMS license belonging to a different domain, even when accessing the contro
relatedTo* GraphQL arguments to null. (#16431)entry-types/merge command. (#16394)utils/prune-revisions command was deleting nested entry revisions.Fixed a bug where custom fields could cause validation errors when running the users/create command.
users/create command.children and descendants eager-loading wasn’t working on some environments. (#16381, #16382)search param was used in conjunction with offset or limit. (#16183)Fixed an RCE vulnerability. (CVE-2025-23209)
getInputHtml() method returned an empty string.@transform GraphQL directives weren’t always working on Assets fields with overridden handles. (#15718)craft\base\NestedElementTrait::getOwner() or getPrimaryOwner() were called on a nested element whose owner didn’t exist in the same site. (#16359)Fixed a bug where elements’ getPrev() and getNext() methods could cause duplicate queries.
getPrev() and getNext() methods could cause duplicate queries. (#16329)ancestors, children, descendants, and parent eager-loading wasn’t working for previewed elements. (#16327)owner or primaryOwner on nested elements. (#16339)Fixed a bug where some blank user group and entry type values weren’t getting omitted from project config data. (#16272, #16273)
+ characters rather than -. (#16300)Fixed a bug where asset, category, and entry sources defined by the EVENT_REGISTER_SOURCES event didn’t have any custom fields available to them, unle
EVENT_REGISTER_SOURCES event didn’t have any custom fields available to them, unless the EVENT_REGISTER_FIELD_LAYOUTS event was also used to define the available field layouts for the event-defined source. (#16256)string types in CustomFieldBehavior rather than craft\fields\data\LinkData.Reduced the likelihood of a deadlock error occurring when updating search indexes.
phpinfo() function is disabled. (#16229)isSelectable() methods weren’t being respected.EVENT_INIT or EVENT_DEFINE_BEHAVIORS entry event handlers were calling getType() on the entry. (#16254)Element indexes now sort by ID by default, for sources that don’t define a default sort option.
craft\events\ApplyFieldSaveEvent::$field wasn’t being set consistently by craft\services\Fields::EVENT_BEFORE_APPLY_FIELD_SAVE. (#16156)project-config/rebuild. (#16189)Fixed an error that could occur if an invalid folder ID was passed to craft\services\Assets::deleteFoldersByIds().
craft\services\Assets::deleteFoldersByIds(). (#16147)resave/all command, if any of the options passed weren’t supported by other resave/* commands. (#16148)Fixed a Twig deprecation error.
entry-types/merge command can now be run non-interactively. (#16135)craft\services\Structures::fillGapsInElements() wasn’t working properly if the elements weren’t passed in hierarchical order. (#16085)craft\helpers\Console::table() wasn’t handling multi-byte characters and ANSI-formatted strings properly.entry-types/merge command. (#16102)entry-types/merge command. (#16087, #16102)Deprecated the enableBasicHttpAuth config setting. craft\filters\BasicHttpAuthLogin should be used instead.
icon is now a reserved field handle. (#16077)pc/* commands as an alias of project-config/*.resave/all command.users/remove-2fa command. (#16053)--except, --minor-only, and --patch-only options to the update command. (#15829)--with-fields option to all native resave/* commands.fields/merge and fields/auto-merge commands now prompt to resave elements that include relational fields before merging them, and provide a CLI command that should be run on other environments before the changes are deployed to them. (#15869)encodeUrl() Twig function. (#15838){% cache %} tags now support setting the duration number to an expression. (#15970)select()/addSelect() methods. (#15827)$PRIMARY_SITE_URL/uploads).craft\base\Element::EVENT_REGISTER_CARD_ATTRIBUTES.craft\base\Element::EVENT_REGISTER_DEFAULT_CARD_ATTRIBUTES.craft\base\Element::defineCardAttributes().craft\base\Element::defineDefaultCardAttributes().craft\base\ElementInterface::attributePreviewHtml().craft\base\ElementInterface::cardAttributes().craft\base\ElementInterface::defaultCardAttributes().craft\base\ElementInterface::indexViewModes().craft\base\NestedElementTrait::saveOwnership(). (#15894)craft\base\PreviewableFieldInterface::previewPlaceholderHtml().craft\base\RequestTrait::getIsWebRequest(). (#15690)craft\base\conditions\BaseElementSelectConditionRule::elementSelectConfig().craft\console\Controller::output().craft\console\controllers\ResaveController::hasTheFields().craft\elements\db\NestedElementQueryTrait. (#15894)craft\events\ApplyFieldSaveEvent. (#15872)craft\events\DefineAddressCountriesEvent. (#15711)craft\events\RegisterElementCardAttributesEvent.craft\events\RegisterElementDefaultCardAttributesEvent.craft\fieldlayoutelements\Template::$templateMode. (#15932)craft\fields\data\LinkData::$target.craft\fields\data\LinkData::setLabel().craft\filters\BasicHttpAuthLogin. (#15720)craft\filters\BasicHttpAuthStatic. (#15720)craft\filters\ConditionalFilterTrait. (#15948)craft\filters\UtilityAccess.craft\helpers\Console::$outputCount.craft\helpers\Console::$prependNewline.craft\helpers\Console::indent().craft\helpers\Console::indentStr().craft\helpers\Console::outdent().craft\helpers\Cp::cardPreviewHtml().craft\helpers\Cp::cardViewDesignerHtml().craft\helpers\Cp::rangeFieldHtml(). (#15972)craft\helpers\Cp::rangeHtml(). (#15972)craft\helpers\ElementHelper::linkAttributeHtml().craft\helpers\ElementHelper::uriAttributeHtml().craft\helpers\Session::addFlash().craft\helpers\Session::getAllFlashes().craft\helpers\Session::getFlash().craft\helpers\Session::hasFlash().craft\helpers\Session::removeAllFlashes().craft\helpers\Session::removeFlash().craft\helpers\StringHelper::firstLine().craft\helpers\UrlHelper::encodeUrl(). (#15838)craft\log\MonologTarget::getAllowLineBreaks().craft\log\MonologTarget::getFormatter().craft\log\MonologTarget::getLevel().craft\log\MonologTarget::getMaxFiles().craft\log\MonologTarget::getName().craft\log\MonologTarget::getProcessor().craft\log\MonologTarget::getUseMicrosecondTimestamps().craft\models\FieldLayout::getCardBodyAttributes().craft\models\FieldLayout::getCardBodyElements().craft\models\FieldLayout::getCardView().craft\models\FieldLayout::prependElements().craft\models\FieldLayout::setCardView().craft\services\Addresses::EVENT_DEFINE_ADDRESS_COUNTRIES. (#15711)craft\services\Addresses::getCountryList(). (#15711)craft\services\Fields::EVENT_BEFORE_APPLY_FIELD_SAVE. (#15872)craft\services\Gc::deleteOrphanedFieldLayouts().craft\services\Users::getMaxUsers().craft\web\View::registerCpTwigExtension().craft\web\View::registerSiteTwigExtension().craft\fields\data\LinkData::getLabel() now has a $custom argument.craft\helpers\Console::output() now prepends an indent to each line of the passed-in string, if indent() had been called prior.elements/save-nested-element-for-derivative action. (#16002)enableBasicHttpAuth config setting. craft\filters\BasicHttpAuthLogin should be used instead. (#15720)serializeForm event to Craft.ElementEditor. (#15794)range() and rangeField() macros to _includes/forms.twig. (#15972)fieldLayoutDesigner() and cardViewDesigner() global Twig functions for control panel templates.withCardViewDesigner param. (#15283sortable option. (#15963)craft.cp.fieldLayoutDesigner() function. The global fieldLayoutDesigner() function should be used instead.Location headers added via craft\web\Response::redirect() are now set to encoded URLs. (#15838)utils/fix-field-layout-uids command was misidentifying missing/duplicate UUID issues.Fixed a bug where entry/category drafts weren’t retaining new parent selections.
craft\services\Categories::saveGroup() and craft\services\Tags::saveTagGroup() weren’t respecting predefined UUID values on new models.autosaveDrafts was disabled. (#15985)Fixed an information disclosure vulnerability.
install command now runs through database connection setup, if Craft can’t yet connect to the database. (#15943)authorId, authorIds, authors, and sectionId are now reserved field handles for entry types. (#15923)craft\elements\db\NestedElementQueryInterface.craft\services\Gc::$silent.'<operator> <values>' weren’t being parsed correctly.craft\services\Entries::saveSection() and craft\services\Volumes::saveVolume() weren’t respecting predefined UUID values on new models.entrify/tags and entrify/global-set commands would prompt for the target section after one had just been created.entrify commands weren’t copying the original field instance UUIDs into newly-created entry types, causing content to appear missing. (#15935)Fixed a privilege escalation vulnerability.
craft\helpers\App::isTty().Fixed a missing authorization vulnerability.
InvalidConfigException is now thrown if the defaultCountryCode config setting is set to an empty string. (#15812)sql_generate_invisible_primary_key was enabled. (#15853)Fixed an information disclosure vulnerability.
deletedWithEntryType values in the entries table weren’t getting set back to null after being restored.Element conditions now show rules for fields with the same name but unique handles, if the “Show field handles in edit forms” user preference is enabl
required properties were always false. (#15752)craft\helpers\StringHelper::toHandle() was allowing non-alphanumeric/underscore characters through. (#15772)maxBackups config setting wasn’t working. (#15780)entries/save-entry controller action. (#15737)entrify/global-set command. (#15746)username values weren’t getting updated based on email address changes when useEmailAsUsername was enabled. (#15758)hasAlt asset query param wasn’t working properly. (#15762)> This update fixes a critical data deletion bug for PostgreSQL installs.
[!IMPORTANT]
This update fixes a critical data deletion bug for PostgreSQL installs.
Fixed a bug where soft-deleted structures weren’t getting hard-deleted via garbage collection.
Fixed an information disclosure vulnerability.
craft\services\Security::isSystemDir().craft\helpers\StringHelper::lines() was returning an array of Stringy\Stringy objects, rather than strings.Fixed a bug where element chips within thumbnail views weren’t getting light gray backgrounds.
Deprecated craft\db\mysql\Schema::quoteDatabaseName().
notRelatedTo and andNotRelatedTo element query params. (#15496)notRelatedTo GraphQL element query argument. (#15496)relatedToAssets, relatedToCategories, relatedToEntries, relatedToTags, and relatedToUsers GraphQL arguments now support passing relatedViaField and relatedViaSite keys to their criteria objects. (#15508)craft\elements\Address::getCountry() now return the country in the current application locale.craft\base\ApplicationTrait::getEnvId(). (#15313)craft\base\ElementInterface::getRootOwner(). (#15534)craft\base\ElementInterface::showStatusIndicator().craft\elements\conditions\NotRelatedToConditionRule.craft\elements\conditions\SiteGroupConditionRule.craft\gql\arguments\RelationCriteria.craft\gql\types\input\criteria\AssetRelation.craft\gql\types\input\criteria\CategoryRelation.craft\gql\types\input\criteria\EntryRelation.craft\gql\types\input\criteria\TagRelation.craft\gql\types\input\criteria\UserRelation.craft\helpers\Cp::componentPreviewHtml().craft\helpers\Inflector.craft\helpers\Session::close().craft\services\Sites::getEditableSitesByGroupId().craft\helpers\Cp::chipHtml() now supports a hyperlink option.craft\helpers\Session methods are now safe to call on console requests.craft\services\Elements::saveElement() now saves dirty fields’ content even if $saveContent is false. (#15393)craft\db\mysql\Schema::quoteDatabaseName().craft\db\pgqsl\Schema::quoteDatabaseName().craft\helpers\ElementHelper::rootElement(). craft\base\ElementInterface::getRootOwner() should be used instead.Craft.cp.announce(), simplifying live region announcements for screen readers. (#15569)craft\base\Element::safeActionMenuItems() and destructiveActionMenuItems() can now include a showInChips key to explicitly opt into/out of being shown within element chips and cards.allowAdd and allowRemove settings. (#15639)X-Robots-Tag: none headers for preview requests. (#15612, #15586)x-craft-preview and x-craft-live-preview params are now hashed, and craft\web\Request::getIsPreview() will only return true if the param validates. (#15605)x-craft-preview or x-craft-live-preview query string params based on the requested URL, if either were set to an unverified string. (#15605)db/convert-charset command if there were any custom database views or sequences. (#15598)craft\helpers\Db::supportsTimeZones() could return false on databases that supported time zone conversion. (#15592)null values within associative arrays were ignored when applying project config data. (#10512)id param was overridden. (#15570)users/delete-user-photo or users/upload-user-photo from the front end. (#15487)Fixed a bug where it wasn’t possible to override named transforms in GraphQL queries.
{% cache %} tags were caching content for Live Preview requests. (#15586)Fixed a bug where craft\helpers\App::env() and normalizeValue() could return incorrect results for values that looked like floats.
craft\helpers\App::env() and normalizeValue() could return incorrect results for values that looked like floats. (#15533)users/set-password action wasn’t respecting redirect params. (#15538)composer.json. (#15559)Fixed a bug where the system name in the control panel’s global sidebar was getting hyperlinked even if the primary site didn’t have a URL.
Fixed an error that could occur if a new element was saved recursively.
config/general.php returned an array with unsupported config settings. (#15514)Improved the appearance of some system settings icons.
craft\db\afterDown().craft\db\afterUp().searchScore values were null when ordering an element query by score. (#15513)Fixed a bug where craft\filters\Headers and craft\filters\Cors were applied to control panel requests rather than site requests.
The allowedGraphqlOrigins config setting is now deprecated. craft\filters\Cors should be used instead.
mailto and tel URIs, and entry/asset/category relations. (#15251, #15400)lang attribute, in case it differs from the user’s preferred language.role="radio" to listed elements’ checkboxes.@web alias for URL settings, regardless of whether it was explicitly defined. (#15347)entry-types/merge command. (#15444)fields/auto-merge command. (#15472)`fields/merge command. (#15454)general and db configs (e.g. config/general.web.php). (#15346)general and db config files can now return a callable that modifies an existing config object. (#15346)lazyGqlTypes config setting. (#15429)env, env/set, and env/remove commands. (#15431)value and caseInsensitive keys. (#15404)Field after the Matrix/CKEditor field handle. (#15269)allowedGraphqlOrigins config setting is now deprecated. craft\filters\Cors should be used instead. (#15397)permissionsPolicyHeader config settings is now deprecated. craft\filters\Headers should be used instead. (#15397){% cache %} tags now cache any asset bundles registered within them.CommerceGuys\Addressing\Country\Country objects. (#15455, #15463).twig.x-craft-preview/x-craft-live-preview URL query string params are now added to generated URLs for Live Preview requests, so craft\web\Request::getIsPreview() continues to return true on subsequent pages loaded within the iframe. (#15447)craft\base\ApplicationTrait::getDb2(). (#15384)craft\base\ElementInterface::addInvalidNestedElementIds().craft\base\ElementInterface::getInvalidNestedElementIds().craft\base\Field::EVENT_AFTER_MERGE_FROM.craft\base\Field::EVENT_AFTER_MERGE_INTO.craft\base\Field::afterMergeFrom(). (#15454)craft\base\Field::afterMergeInto(). (#15454)craft\base\Field::canMergeFrom(). (#15454)craft\base\Field::canMergeInto(). (#15454)craft\base\FieldLayoutComponent::EVENT_DEFINE_SHOW_IN_FORM. (#15260)craft\base\FieldLayoutElement::$dateAdded.craft\base\FieldTrait::$dateDeleted.craft\base\Grippable.craft\base\MergeableFieldInterface. (#15454)craft\base\RelationFieldInterface. (#15400)craft\base\RelationFieldTrait. (#15400)craft\config\GeneralConfig::addAlias(). (#15346)craft\elements\Address::getCountry(). (#15463)craft\elements\Asset::$sanitizeOnUpload. (#15430)craft\elements\Entry::isEntryTypeCompatible().craft\elements\actions\MoveToSection.craft\enums\CmsEdition::Enterprise.craft\events\DefineShowFieldLayoutComponentInFormEvent. (#15260)craft\events\MoveEntryEvent.craft\fields\Link.craft\fields\data\LinkData.craft\fields\linktypes\Asset.craft\fields\linktypes\BaseElementLinkType.craft\fields\linktypes\BaseLinkType.craft\fields\linktypes\BaseTextLinkType.craft\fields\linktypes\Category.craft\fields\linktypes\Email.craft\fields\linktypes\Phone.craft\fields\linktypes\Url.craft\filters\Cors. (#15397)craft\filters\Headers. (#15397)craft\helpers\App::configure().craft\models\FieldLayout::getAllElements().craft\models\ImageTransform::$indexId.craft\services\Elements::ensureBulkOp().craft\services\Entries::EVENT_AFTER_MOVE_TO_SECTION.craft\services\Entries::EVENT_BEFORE_MOVE_TO_SECTION.craft\services\Entries::moveEntryToSection().craft\services\Fields::areFieldTypesCompatible().craft\web\View::clearAssetBundleBuffer().craft\web\View::startAssetBundleBuffer().craft\helpers\DateTimeHelper::toIso8601() now has a $setToUtc argument.craft\helpers\UrlHelper::cpUrl() now returns URLs based on the primary site’s base URL (if it has one), for console requests if the baseCpUrl config setting isn’t set, and the @web alias wasn’t explicitly defined. (#15374)craft\services\Config::setDotEnvVar() now accepts false for its value argument, which removes the environment variable from the .env file.craft\fields\BaseRelationField::$localizeRelations.craft\fields\Url, which is now an alias for craft\fields\Link.craft\services\Relations.craft\web\assets\elementresizedetector\ElementResizeDetectorAsset.Craft.EnvVarGenerator.Craft.endsWith().Craft.removeLeft().Craft.removeRight().Craft.ui.addAttributes().Craft.ElementEditor now triggers a checkActivity event each time author activity is fetched. (#15237)Craft.NestedElementManager now triggers an afterInit event after initialization. (#15470)Craft.ensureEndsWith() now has a caseInsensitive argument.Craft.ensureStartsWith() now has a caseInsensitive argument.Craft.startsWith() is no longer deprecated, and now has a caseInsensitive argument.Garnish.once(), for handling a class-level event only once.targetPrefix setting.showHandle setting.showHandles setting.Permissions-Policy header on control panel responses. (#15348)resize events now use ResizeObserver.cpresources folder is writable.</body> tag, rather than at the end of the response HTML.graphql/api requests no longer update the schema’s lastUsed timestamp if it was already updated within the last minute. (#15464)users/send-password-reset-email action weren’t accounting for the useEmailAsUsername config setting. (#15425)$element->isNewForSite was always false from fields’ normalizeValue() methods when propagating an element to a new site.assets/generate-transforms requests could generate the wrong transform, if another transform index with the same parameters existed. (#15402, #15477)autosaveDrafts was disabled. (#15418)Nothing published for this version
Nothing published for this version
Fixed a bug where it wasn’t possible to render element partial templates for assets, categories, or tags.
deleteAsset, deleteCategory, deleteEntry, and deleteTag GraphQL mutations were returning null rather than true or false. (#15465)exists() element queries weren’t working if distinct, groupBy, having, or union params were set on them during query preparation. (#15001, #15223)username properties weren’t getting set if useEmailAsUsername was enabled. (#15475)EVENT_BEFORE_PREPARE were getting overridden for all core element types except entries. (#15446)utils/prune-orphaned-entries command was deleting top-level entries. (#15458)Added craft\helpers\Money::normalizeString().
craft\helpers\Money::normalizeString().craft\base\Element::EVENT_AFTER_SAVE weren’t getting saved, when an element was getting fully saved from an unsaved draft state. (#15369)useEmailAsUsername was enabled. (#15401)Fixed a bug where element index result counts weren’t getting updated when the element list was refreshed but pagination was preserved.
craft\helpers\UrlHelper::actionUrl() now returns URLs based on the primary site’s base URL (if it has one), for console requests if the @web alias was
craft\helpers\UrlHelper::actionUrl() now returns URLs based on the primary site’s base URL (if it has one), for console requests if the @web alias wasn’t explicitly defined.sectionId or fieldId + ownerId values. (#15345)CustomFieldBehavior. (#15336)transaction: true. (#7615)autosaveDrafts config setting was set to false. (#15353)> Craft now sends no-cache headers for requests that generate/retrieve a CSRF token. If your Craft install is behind a static caching service like Clo
[!NOTE] Craft now sends no-cache headers for requests that generate/retrieve a CSRF token. If your Craft install is behind a static caching service like Cloudflare, enable the asyncCsrfInputs config setting to avoid a significant cache hit reduction. (#15293, #15281)
craft\web\Request::getCsrfToken(). (#15293, #15281)craft\helpers\ElementHelper::isDraft(), isRevision(), and isDraftOrRevision() weren’t returning true if a nested draft/revision element was passed in, but the root element was canonical. (#15303)ownerId param, when refreshing elements’ table rows.Craft now sends no-cache headers for any request that generates a CSRF token. (#15281, verbb/formie#1963)
asyncCsrfInputs config setting was enabled.title values on nested Matrix entries, when saving section entries via GraphQL. (#15270)DECIMAL() expression was passed into a query’s select() or groupBy() methods. (#15271)Improved the styling of inactive users’ status indicators.
Garnish.once() and Garnish.Base::once(), for registering event handlers that should only be triggered one time.name value.single set to true would set existing elements’ input names ending in [].Fixed a potential vulnerability with TOTP authentication.
craft\helpers\Db::prepareForJsonColumn().Added craft\base\conditions\BaseNumberConditionRule::$step.
craft\base\conditions\BaseNumberConditionRule::$step.craft\helpers\Db::parseColumnPrecisionAndScale().Garnish.muteResizeEvents().distinct, groupBy, having, or union params were set on them during query preparation. (#15001)Element index table views now show provisional drafts’ canonical elements’ values for the “Ancestors”, “Parent”, “Link”, “URI”, “Revision Notes”, “Las
craft\web\View::getModifiedDeltaNames().craft\web\View::registerDeltaName() now has a $forceModified argument.graphql/create-token command was prompting for the schema name, when it meant the token name. (#15205)Live Preview now supports tabs, UI elements, and tab/field conditions.
--format option to the db/backup and db/restore commands for PostgreSQL installs. (#14931)db/restore command now autodetects the backup format for PostgreSQL installs, if --format isn’t passed. (#14931)install command and web-based installer now validate the existing project config files at the outset, and abort installation if there are any issues.resave/entries command now has an --all-sections flag.CRAFT_EDITION environment variable. (#15094)CRAFT_REBRAND_PATH environment variable. (#15110){% expires %} tag, which simplifies setting cache headers on the response. (#14969)withCustomFields element query param. (#15003)* to the section param, to filter the results to all section entries. (#14978)draftOf param.craft\elements\ElementCollection::find(), which can return an element or elements in the collection based on a given element or ID. (#15023)craft\elements\ElementCollection::fresh(), which reloads each of the collection elements from the database. (#15023)collect() Twig function now returns a craft\elements\ElementCollection instance if all of the items are elements.craft\elements\ElementCollection::contains() now returns true if an element is passed in and the collection contains an element with the same ID and site ID; or if an integer is passed in and the collection contains an element with the same ID. (#15023)craft\elements\ElementCollection::countBy(), collapse(), flatten(), keys(), pad(), pluck(), and zip() now return an Illuminate\Support\Collection object. (#15023)craft\elements\ElementCollection::diff() and intersect() now compare the passed-in elements to the collection elements by their IDs and site IDs. (#15023)craft\elements\ElementCollection::flip() now throws an exception, as element objects can’t be used as array keys. (#15023)craft\elements\ElementCollection::map() and mapWithKeys() now return an Illuminate\Support\Collection object, if any of the mapped values aren’t elements. (#15023)craft\elements\ElementCollection::merge() now replaces any elements in the collection with passed-in elements, if their ID and site ID matches. (#15023)craft\elements\ElementCollection::only() and except() now compare the passed-in values to the collection elements by their IDs, if an integer or array of integers is passed in. (#15023)craft\elements\ElementCollection::unique() now returns all elements with unique IDs, if no key is passed in. (#15023)craft\db\Query, element queries, and craft\elements\ElementCollection.craft\base\NestedElementTrait::$updateSearchIndexForOwner.craft\db\getBackupFormat().craft\db\getRestoreFormat().craft\db\setBackupFormat().craft\db\setRestoreFormat().craft\enums\Color::tryFromStatus().craft\events\InvalidateElementcachesEvent::$element.craft\fields\BaseRelationField::existsQueryCondition().craft\helpers\Cp::componentStatusIndicatorHtml().craft\helpers\Cp::componentStatusLabelHtml().craft\helpers\Cp::statusLabelHtml().craft\helpers\DateTimeHelper::relativeTimeStatement().craft\helpers\DateTimeHelper::relativeTimeToSeconds().craft\helpers\ElementHelper::postEditUrl().craft\helpers\ElementHelper::swapInProvisionalDrafts().craft\helpers\StringHelper::indent().craft\models\Volume::getTransformSubpath().craft\models\Volume::setTransformSubpath().craft\queue\Queue::getJobId().craft\web\twig\SafeHtml, which can be implemented by classes whose __toString() method should be considered HTML-safe by Twig.craft\base\Element::defineTableAttributes() now returns common attribute definitions used by most element types.craft\elements\ElementCollection::with() now supports collections made up of multiple element types.craft\models\Volume::getSubpath() now has a $parse argument.craft\services\Drafts::applyDraft() now has a $newAttributes argument.reloadOnBroadcastSave setting to Craft.ElementEditor. (#14814)waitForDoubleClicks setting to Garnish.Select, Craft.BaseElementIndex, and Craft.BaseElementIndexView.exists() element queries.craft\base\Element::toArray().users/login action wasn’t checking if someone was already logged in. (#15168)Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Fixed an error that could occur if a Local filesystem wasn’t configured with a base path.
Fixed a bug where the db/backup command could fail on Windows.
db/backup command could fail on Windows. (#15090)Added craft\helpers\Gql::isIntrospectionQuery().
craft\helpers\Gql::isIntrospectionQuery().craft\helpers\Html::id() now allows IDs to begin with numbers. (#15066)craft\base\FieldLayoutComponent::getAttributes() if the $elementType property wasn’t set yet. (#15074)craft\elements\Address::toArray() would include a saveOwnership key in its response array.users/create command would fail without explaining why, when the maximum number of users had already been reached.uid values. (#15103)serve command could hang. (#14977)Scalar element queries no longer set their $select property to the scalar expression, fixing an error that could occur when executing scalar queries f
$select property to the scalar expression, fixing an error that could occur when executing scalar queries for relation fields. (#15071)primaryOwnerId values. (#15063)Added craft\services\Fields::getRelationalFieldTypes().
Scalar element queries now set $select to the scalar expression, and $orderBy, $limit, and $offset to null, on the element query.
$select to the scalar expression, and $orderBy, $limit, and $offset to null, on the element query. (#15001)craft\fieldlayoutelements\TextareaField::inputTemplateVariables().craft\helpers\Assets::prepareAssetName() wasn’t sanitizing filenames if $preventPluginModifications was true.count() methods were factoring in the limit param when searching with orderBy set to score. (#15001)up command could remove component name comments from the project config YAML files, for newly-added components. (#15012)craft\helpers\UrlHelper::isAbsoluteUrl() was returning true for Windows file paths. (#15043)Improved the performance of element indexes that contained asset thumbnails.
craft\elements\db\ElementQuery::exists() would return true if setCachedResult() had been called, even if an empty array was passed.craft\web\Response::redirect() was called. (#15014)eagerly() wasn’t working when a custom alias was passed in.Fixed a SQL error that could occur when applying or rebuilding the project config.
serve command wasn’t serving paths with non-ASCII characters. (#14977)craft\helpers\Html::explodeStyle() and normalizeTagAttributes() weren’t handling styles with encoded images via url() properly. (#14964)db/backup command would fail if the destination path contained a space.Fixed a bug where the db/backup command would prompt for password input on PostgreSQL.
db/backup command would prompt for password input on PostgreSQL. (#14945)Your coding agent can read these notes before it upgrades. Set up the MCP server →