Upgrading to Hyvä Commerce 1.4.0
Hyvä Commerce 1.4.0 includes Hyvä CMS 1.3.0. This guide covers the upgrade from CMS 1.2.x, with the deployment changes and compatibility work needed by custom integrations. For the complete list of features and fixes, see the CMS changelog.
Follow the Commerce upgrade process to update the metapackage. If you are upgrading from a CMS version older than 1.2, also apply the CMS 1.2 upgrade guidance.
Hyvä CMS
CMS 1.3 replaces the editor's internal Magewire runtime with CmsConnect, adds shared admin styles, moves every Hyvä CMS permission onto its own ACL tree and includes the Media Gallery. The compatibility work falls on custom editor panels, fields, content types and modules that call the old Magewire APIs or override editor templates. Component declarations, PHP component rendering templates and existing content carry over unchanged.
Before Upgrading Hyvä CMS
- Test the upgrade on a staging copy with your custom components and content. Back up the database and media, and ask editors to save their drafts before deployment.
- Upgrade CMS and its integrations together: Menu Builder, Email & Newsletter Templates, Form Builder, the CMS AI features and custom modules, each at a version that supports CMS 1.3, and test their editor flows. CMS 1.2 cannot supply the CmsConnect, shared admin styles or editor APIs they use. Email & Newsletter Templates and Form Builder are generally available, and the AI features are experimental.
- Check your root
composer.jsonfor pins and version aliases that stop Composer selecting the new versions, and remove them. Look for CMS pins targeting1.2.x, and for anything left from the beta: a1.3.0-beta1or1.3.0-beta2CMS pin, the1.3.0-beta2 as 1.2.2alias, and0.1.0pins on Form Builder or Email & Newsletter Templates. A broad constraint does not prove that a third-party extension supports the new editor. - Make sure Composer can resolve
hyva-themes/commerce-module-media-gallery. The Hyvä package repository supplies it through the CMS dependency, and projects using individual Git repositories must add its repository to the root project. - Enable the new
Hyva_CmsConnect,Hyva_CmsAdminStylesandHyva_MediaGallerymodules, run the usual schema upgrade, DI compilation, cache refresh and static-content deployment, then build the admin styles.
A CMS upgrade does not deploy an AI worker or configure an AI provider. For CMS AI generation, set up provider credentials, execution configuration and the worker with AI Worker setup and configuration.
Add Admin Styles to the Deployment Pipeline
CMS 1.3 adds Hyva_CmsAdminStyles, which builds one admin stylesheet from the editor's shared foundations and each participating module's CSS fragment. Run this from the Magento root after the final module set is installed and enabled, static content is deployed and any step that clears pub/static has run:
Cleaning the configuration cache lets the registry see added, removed or changed style manifests. Rebuild whenever participating packages, templates or styles change. Requirements, artifacts and fallback styles are under Admin Styles and Custom Modules.
Grant the New Hyvä CMS Permissions to Custom Roles
CMS 1.3 gates every admin screen, editor action and REST route with its own ACL resources, under a Hyvä CMS node in System → Permissions → User Roles. Magento_Backend::content no longer opens any Hyvä CMS screen. The editor's page, block and attribute settings need the entity's Save draft instead of Magento_Cms::save, Magento_Cms::block, Magento_Catalog::products or Magento_Catalog::categories. The editor's link pickers still need Magento_Cms::page, Magento_Cms::block, Magento_Catalog::products and Magento_Catalog::categories, because they list Magento's own data.
Nothing is migrated. A custom role that reached Hyvä CMS through Magento_Backend::content loses access as soon as the code deploys, and a REST integration with a custom resource list is refused. After deploying, edit each such role and integration and tick the Hyvä CMS resources it should have. The Administrators role holds Magento_Backend::all and is unaffected.
The node has a group per entity (Pages, Blocks, Product attributes, Category attributes, Templates, Snippets, Instance components) plus the Transfer Center, which both import and export need, each with the verbs its entity supports: View, Save draft, Publish, Delete, Export, Version history and Scheduling. REST follows the same tree: GET needs View, POST and PUT need Publish (Save for templates, snippets and instance components) and DELETE needs Delete. The Tailwind CSS routes are an exception: POST, PUT and DELETE need Save draft (Save for templates and snippets). The editor hides what a role cannot do, opening read-only without Save draft, and Publish, Schedule, Import/Export and the version history controls each follow their own resource. The server still checks every request.
From CMS 1.3.1, Stores → Configuration → Hyvä Commerce → Hyvä CMS needs Hyvä CMS Section (Hyva_Cms::config) instead of Content. A role that manages these settings needs Stores → Settings → Configuration and that resource.
Grant the companion packages' resources in the same pass:
- Menu Builder adds a Menus group with the same verbs. The menu widget chooser needs Menus > View instead of
Magento_Widget::widget_instance. - Form Builder adds a Forms group with View, Save draft, Publish, Delete, Export and Version history. From Form Builder 1.0.1, its configuration section needs Hyvä Form Builder Section (
Hyva_FormBuilder::config) instead of Content. Public form submission is unchanged. - Email & Newsletter Templates adds Email templates and Newsletter templates groups. Magento's own template grids still need
Magento_Email::templateandMagento_Newsletter::template, so a role that opens the Hyvä editor from them needs both. - Media Gallery adds
Hyva_MediaGallery::media, covered under Configure the Included Media Gallery. - AI translation needs
Hyva_CmsAiTranslations::translate. - AI generation adds an AI generation group under Hyvä CMS. AI Page Generation (
Hyva_AiWorkerCms::generate) needs Save draft, or Publish when the generator publishes, on the page, block, snippet or template it writes into. AI Instance Component Generation (Hyva_AiWorkerCms::instance_component_generate) needs Instance components > Save as well. - AI Worker adds two resources under Content. AI Worker (
Hyva_AiWorker::manage) opens the Hyvä AI menu and lets a generation start, report its status and resume after an interruption, so every role that generates needs it. AI Jobs (Hyva_AiWorker::jobs) opens the job list, with cancel, retry, delete and pin, and Start from previous run. - AI settings each have their own section under Stores → Settings → Configuration: Hyvä AI Section (
Hyva_Ai::config) for Hyvä AI → Settings from Hyvä AI 1.3.1, Hyvä AI Worker Section (Hyva_AiWorker::config) for Hyvä AI → AI Worker, and Hyvä AI CMS Section (Hyva_AiWorkerCms::config) for Hyvä AI → Hyvä CMS.
With AI Worker CMS installed, the AI Translation, Generation and Image Generation groups move from Hyvä AI → Settings to Hyvä AI → Hyvä CMS. The saved values stay where they are, but the groups now follow Hyvä AI CMS Section, so a custom role that managed AI translation settings loses them until that resource is ticked.
A custom content type registers its ACL prefix with the content type authorization resolver. Until it does, every verb falls back to Magento_Backend::content and a warning is logged to var/log/hyva_cms.log. ACL Resources has the tree, the resolver and the checklist.
Migrate Custom Editor Integrations to CmsConnect
In CMS 1.3 the editor keeps the working document in the browser and saving submits it to Magento, which stays responsible for permissions, validation, rendering and persistence. An integration that wrote to the old server-side working copy through Magewire must move to the editor commands or an approved Connect action. The table lists the changes, and the upgrade scanner reports the old classes, directives, events and endpoints in your code.
| CMS 1.2 integration | Required change for CMS 1.3 |
|---|---|
Hyva\CmsLiveviewEditor\Magewire\… classes |
Update imports, subclasses and DI references to Hyva\CmsLiveviewEditor\Composer\…. |
Copied editor templates using $magewire |
Update the override against the current template and use $composer. A retained variable alias does not restore interactive behavior. |
wire:model, wire:click and other wire:* directives |
Replace them with Alpine bindings, editor commands or approved Connect actions. The old directives are inert. |
Direct field/tree mutations or old $wire.updateField / $wire.doSave calls |
Use window.liveview.editor commands for document changes and saving. The remaining $wire facade only exposes supported Connect actions. |
| Magewire hydration, JavaScript lifecycle hooks or directive registration | Rework the integration around local document state and the new editor/Connect APIs. The old runtime is gone. |
magewire:update, magewire:available and loader events |
Migrate transport listeners to connect:update, connect:booted and connect:loader:*. Observe document changes through editor:* events. |
Requests to the old liveview-magewire transport endpoints |
Use the Connect client and approved actions. Legacy transport routes return HTTP 410. |
The temporary Hyva_CmsMagewire compatibility module keeps selected PHP stubs, module dependencies, static rendering and event aliases, but not hydration, directives or the old request protocol. It will be removed in a future release, so migrate anything that depends on it. Keep the Magewire dependencies other Magento features need, such as unrelated checkout integrations, and the standalone magewirephp/validation package.
Scan Custom Code for Magewire Editor APIs
The CmsConnect upgrade scanner ships with CMS and finds old Magewire editor classes, wire:* directives, magewire:* events and transport calls in your custom code. A project with no custom editor integrations can skip it. It needs Node.js 18 or later. From the Magento project root, run:
Add the directories of third-party CMS integrations as extra arguments. The scan skips vendor unless you pass --include-vendor. Exit code 1 means findings remain, and 2 means a usage error. To apply the mechanical renames, add --fix:
node vendor/hyva-themes/commerce-module-cms/tools/connect-upgrade-scan.mjs app/code app/design --fix
Review the diff, rerun without --fix, and migrate what remains using the table above and the API guidance below. The scanner cannot redesign custom state management or prove an integration works, so test the migrated controls even when the scan is clear.
Choose the Correct API
Use window.liveview.editor.run() for document changes, such as field.update, component.add and component.reorder, and document.save for saving, so they join the editor's draft and undo/redo. Observe completed changes through events such as editor:field:updated and editor:document:saved.
Server-backed integrations extend Hyva\CmsConnect\Component, register in Hyva\CmsConnect\Model\ComponentPool and expose approved methods with #[Hyva\CmsConnect\Api\Action]. Each action receives explicit inputs, since PHP property writes no longer synchronize an editor document. Use the Connect client for signed state and request validation.
Review copied layout handles and templates too, since an override can keep obsolete bindings or miss new initialization while its classes still load. The CmsConnect migration guide has the API details and command examples.
Admin Styles and Custom Modules
The admin styles build needs Node.js 20 or later, npm, npm registry access and write access to var and pub/static, and uses Tailwind CSS 4.1.18. --install installs the locked compiler dependencies with npm ci --ignore-scripts; omit it if your pipeline already installs them. The build covers the admin interface only, so keep your storefront theme and CMS content Tailwind steps.
Ship both generated files in the deployment artifact to every application node:
pub/static/_cache/hyva-cms-admin-styles/<content-hash>/<surface>/styles.css
pub/static/_cache/hyva-cms-admin-styles/<content-hash>/<surface>/manifest.json
The combined build is an optimization. If it never ran, failed or is stale, the editor uses the shipped host stylesheet and package fragments, which need no Node. Packages must still ship compiled CSS, and static-content deployment is still required.
Custom Module Styles
If your integration added templates to the editor's Tailwind scan or changed the editor's compiled stylesheet, move it to the shared style contract:
- Declare its
liveview-editorstyles inview/adminhtml/tailwind/hyva-cms-admin.json. - Provide the module's source rules and content scans in
module.css, and ship its compiled CSS fragment. - Mark rendered roots with
data-hyva-cms-styles="<package>", including teleported dialogs, so the fragment's utilities apply correctly. - Rebuild the package's fragment after changing its templates or styles, then rebuild the combined styles during deployment.
The combined build does not regenerate a package's fallback CSS. Check custom selectors against the new editor markup, and test with both the shipped fragments and the combined stylesheet. Admin Styles has the full manifest and build examples.
Configure the Included Media Gallery
CMS 1.3.0 installs the new Media Gallery through the hyva-themes/commerce-module-media-gallery dependency. Prepare Magento's media index before editors use the picker:
- Under Stores → Configuration → Advanced → System → Media Gallery, set Enable Old Media Gallery to No, save and refresh the invalidated cache.
- Ensure the
media.gallery.synchronizationandmedia.content.synchronizationconsumers run. Only files in Magento's media asset index are selectable, so files copied onto disk need indexing. - Grant
Hyva_MediaGallery::mediaunder Hyvä CMS in System → Permissions → User Roles to each role that should use the gallery:asset_viewfor browsing, search and the picker, thenasset_upload,asset_saveandasset_deletefor assets andfolder_saveandfolder_deletefor folders. - Keep Magento cron running. Trash retention defaults to seven days and is set under Hyvä Commerce → Hyvä CMS → Media Gallery.
To fall back to Magento's default media gallery picker, set Stores → Configuration → Hyvä Commerce → Hyvä CMS → Media Gallery → Enable Media Gallery Picker in Live View to No. The package stays installed, and Magento's enhanced gallery and synchronization settings are untouched.
Test custom image fields and picker integrations. Image fields stay single-select unless a field opts into multiple selection. Gallery selections store asset IDs, so CMS resolves the current path after a move or rename; existing literal image URLs do not gain that. The Media Gallery guide has the details.
Handle Save Conflicts, Validation and Permissions
Custom save and publish integrations must preserve the draft when a request fails:
| Response | Meaning and required handling |
|---|---|
| HTTP 409 | Another user or tab saved a newer version. Keep or export the unsaved draft, review the newer version and reload before retrying. Do not repeatedly resubmit the stale base version. |
| HTTP 422 | A provider rejected the content or field values. Display the returned message and field errors, and let the editor correct the draft. |
Providers report field errors through Hyva\CmsConnect\Exception\UnprocessableContentException, keyed by component UID and field name. Update code that treats every response as a successful save or replaces the local document after a failure.
Document validation and size and complexity limits now apply to saves, APIs and imports alike, so structures another persistence path used to accept can be rejected. Test custom importers and serializers with representative content, including store-view overrides.
Page and block settings, transfers and content operations also check content-type permissions, so test with real editor roles. Custom content types must keep configured protected roots and root limits, and enforce content restrictions on the server as well as in the editor. See Extending for Other Content Types.
Check GraphQL Consumers
GraphQL content and styles follow published state and store availability, so integrations expecting disabled or unassigned content must handle that. hyvaCmsBlocks accepts at most 50 identifiers per request, so batch larger requests. Preview queries need a valid CMS preview capability, not just a preview flag, and page and block previews still read published content and styles, never the unsaved draft. Details are in CMS APIs.
Refresh Editor Sessions and Preview Links
The editor's token generators now use HMAC, so tokens issued before deployment, including those in open editor tabs, stop working. Ask editors to reload after the upgrade. Create fresh draft-preview links and update shared review links, because an old link can silently show the published page instead of the draft.
Hyvä CMS Tailwind JIT 2.0.4
CMS 1.3.0 requires hyva-themes/magento2-cms-tailwind-jit 2.0.4 or later, and Composer installs it with Hyvä CMS, so most projects have nothing to do. The one change to check for in custom code: the JIT's storefront observers now read Magento CMS page and block content with getData('content') instead of getContent(), so a plugin on Magento\Cms\Model\Page::getContent() or Magento\Cms\Model\Block::getContent() no longer affects JIT-styled output. Hyvä CMS content is unaffected.
Verify the Upgrade
Before reopening editing on production, check the upgraded installation with representative content and editor roles:
- Open and edit existing pages, blocks and any custom content types. Test custom fields, previews, undo/redo, draft save and publish.
- Log in with each custom content role and check that it can open the editor, and that Publish, Schedule and Import/Export appear only where the role holds them.
- Exercise a conflicting save in two tabs and a provider validation error. Confirm that the draft remains available and the errors are actionable.
- Check the admin styles, including custom panels and dialogs, after deploying the generated CSS and manifest.
- Select and upload an image, and verify the Magento picker fallback if you disable the Hyvä picker.
- Check translations, a representative import/export, version history and scheduled publication.
- Check storefront output, GraphQL requests and newly generated preview links.
Hyvä Form Builder
Form Builder leaves beta with this release. Upgrading from the 0.1.0 beta is mostly automatic: setup:upgrade migrates every form, so nobody has to rebuild a form in the editor. Form Builder needs CMS 1.3, so upgrade both together. For everything that changed, see the Form Builder changelog.
Before Upgrading Form Builder
Take a database backup
The Form Builder upgrade rewrites every form's draft, its published content and every version history row. The backup is your way back. Version history isn't, because the upgrade rewrites it too.
Check your form identifiers as well. Saving a form now refuses any identifier that isn't lowercase letters, numbers and underscores, and the migration saves every form. A beta form created through REST or an import with an identifier like Contact-Us stops setup:upgrade. Rename it in the Forms grid before you upgrade.
What the Form Builder Upgrade Changes
The two beta roots, single_step_form and multi_step_form, become one hyva_form root with a Layout field that picks single page or multi-step. In the editor, that root is now the components panel's header rather than a tree row. Every existing form is assigned to All Store Views, and the same identifier can now exist once per store view.
After deploying, rebuild your theme's Tailwind CSS and flush static content. The new required markers and error styles are CSS, and the storefront stylesheet is cached for a year, so hard reload too.
Updating Custom Form Roots and Integrations
Custom form roots need four changes:
- Accept Form Sections (
form_step) as children. - Replace
x-html="resultMessage"withx-ref="result"on the success element. - Pass
$blocktorenderForm()andrenderFormScriptHtml(). - If your root ships its own submit script, treat HTTP 400 as the validation response and 500 as a mail failure.
On the storefront, a custom root renders through the layout chosen in its Layout field, or the Single page layout if it has none. The root's own template only shows in the editor, as it did in 0.1.0. To change a form's storefront markup, add a form layout.
REST integrations should know that GET /V1/hyvaForm/identifier/:identifier now returns 404 for a disabled form, and that identifiers are unique per store view rather than globally. Use GET /V1/hyvaForm/identifier/:identifier/store/:storeId to get the form a store view shows.
One case needs a manual fix. A beta form with a CMS Form component nested inside it keeps that nested form after the upgrade, so open it in the editor and remove it.
Verifying the Form Builder Upgrade
Before anyone opens the editor, check a single-step form and a multi-step form on the storefront and send a test submission from each. Then restore an older version of a form from its version history and confirm it opens cleanly.