Changelog
4.0.1 2026-11-01
Fixed
- Fixed editor JavaScript loading twice when Craft’s
buildIdsetting is configured. - Fixed the Emoji picker exposing duplicate dialogs to assistive technology.
- Fixed Vizy 3 upgrades failing when fields selected JSON editor config files, including when retrying a failed upgrade.
- Fixed Vizy 3 upgrades failing when a Block Type reused the same Craft field with different placement handles.
- Fixed upgrades losing editor configs named
Default.jsonor using uppercase letters, spaces, dots, numeric names, orstandard.json. - Fixed migrated images disappearing on sites added after the asset was created, and preserved explicit image site references.
- Fixed content conversion failing when Craft created revisions referencing legacy Matrix anchors.
- Fixed the rich-text field migration wizards creating a database backup when “Create a database backup” was unchecked.
4.0.0 2026-10-28
{warning} Before upgrading to Vizy 4, review the Upgrading from v3 guide for breaking changes and required migration steps.
Added
- Added named Editor Configs, managed in the control panel or as JSON files in
config/vizy/, with visual builders for content capabilities, toolbars, dropdowns, Bubble Menus, and insertion controls. (#183 (opens new window)) - Added shared Project Config-backed Block Types with reusable Craft field layouts, icons, colours, preview images, summaries, grouping, and per-field availability. (#60 (opens new window), #222 (opens new window), #261 (opens new window), #271 (opens new window))
- Added toolbar, gutter, and slash insertion for Blocks, with configurable list and grid pickers, a default display, and optional search. (#296 (opens new window), #330 (opens new window), #360 (opens new window), #341 (opens new window))
- Added responsive Layout and Column nodes with configurable presets, wrapping, resizing, reordering, and GraphQL support. (#72 (opens new window))
- Added Hosted Vizy Editors with independent Editor Configs and support for up to five levels of nested Vizy fields on Block Type layouts. (#45 (opens new window), #125 (opens new window))
- Added native footnotes with editable definitions, automatic numbering, keyboard navigation, accessible frontend HTML, GraphQL support, and migration from Verbb Footnotes markup. (#303 (opens new window))
- Added native Emoji, Find and Replace, Ruby text, task lists, collapsible details, and syntax highlighting for code blocks. (#204 (opens new window))
- Added Font family, Font size, Text colour, highlight colour, and Line height controls. (#201 (opens new window))
- Added Character Count, Placeholder, and Typography behaviour extensions, plus automatic list-boundary keyboard handling. (#204 (opens new window))
- Added Craft Entry and current-user conditions for field-local Block Type availability, plus Entry-aware field and tab conditions inside Blocks. (#178 (opens new window))
- Added native Craft element-card previews and automatic collapsed Block summaries from nested Vizy content. (#332 (opens new window), #140 (opens new window))
- Added a visual icon designer for Editor Config toolbar, dropdown, and Bubble Menu controls. (#342 (opens new window))
- Added control-panel wizards and console commands for converting between Vizy and CKEditor, Redactor, or Plain Text fields, with conversion previews, recovery data, and generated deployment migrations. See Migrating Rich-Text Fields. (#288 (opens new window))
- Added content recovery records and commands to restore saved documents and their nested Matrix content across sites. See Content Recovery.
- Added concurrent-edit conflict handling that preserves unsaved changes and offers saved-version review and an unsaved-content download.
- Added a structural GraphQL API for documents, nodes, marks, layouts, Blocks, and generated Block Type fields, with filtering, ordering, limits, rendered HTML, and raw data access. (#52 (opens new window), #124 (opens new window), #129 (opens new window))
- Added PHP and JavaScript extension APIs for registering TipTap nodes, marks, behaviour modules, toolbar controls, dropdowns, and rendering behaviour. (#93 (opens new window), #137 (opens new window))
- Added
EditorManifests::EVENT_MODIFY_EDITOR_CONFIGfor field-scoped runtime configuration changes. - Added custom boolean Link attributes that modules can register in the Link dialog, with optional
rel,class, ordata-*output mappings. (#257 (opens new window)) - Added Twig template partials for built-in and custom node and mark types, configured by convention or per render. (#29 (opens new window), #212 (opens new window), #291 (opens new window), #298 (opens new window))
- Added
block.ownerto Block Type templates for access to the Craft element containing the Vizy field. (#285 (opens new window)) - Added a raw content API for inspecting and migrating embedded field values, with placement identities, explicit changes, dry runs, and caller-owned transactions. (#313 (opens new window), #371 (opens new window))
- Added an HTML importer API that respects the field’s content schema, reports conversion losses, and supports strict conversion, asset resolution, and custom nodes and marks. (#142 (opens new window))
- Added Feed Me support for canonical Vizy documents and mappings from HTML elements to custom Blocks, including nested field values and matching or creating assets from image attributes. (#251 (opens new window))
Changed
- Vizy now requires Craft CMS 5.9 or later.
- Rebuilt the editor on TipTap 3 and Plugin Kit, with accessible toolbar controls and Bubble Menus. Integrations that mounted Vue components or targeted the legacy editor DOM must migrate to the Extensions APIs.
- Vizy field values are now immutable
VizyDocumentobjects backed by versioned canonical JSON. Render fields explicitly withrender(); usequery(),all(),blocks(),content(), ortraverse()for structured access. - Block definitions are now global Block Types referenced by UID instead of field-owned definitions. Craft’s plugin migrations convert existing field configuration and content through a resumable, verified upgrade.
- Block Type templates now receive field values through the
blockvariable. - The GraphQL contract now uses structural
VizyDocument,Vizy*node and mark types, and UID-qualified generated Block types. Existing Vizy 3 fragments and JSON-encodedwherearguments must be updated. - Editor integrations now use named Editor Configs and the Extensions registry instead of per-field inline configuration or Vizy 3 plugin registration hooks.
- Matrix fields inside Vizy now use Inline Blocks so edits follow the containing entry’s save and draft workflow. Other Matrix display modes retain their configured appearance outside Vizy.
- Asset uploads and nested field values are finalised with the owning element save, with recoverable status for deferred or failed uploads.
- Improved Word and Google Docs pasting to preserve supported formatting, lists, tables, and footnotes according to the field’s Editor Config, with warnings when content or formatting cannot be retained. (#134 (opens new window))
- Feed Me HTML mappings now use the field’s Editor Config, report conversion losses, and can require lossless conversion. See Importing with Feed Me. (#289 (opens new window))
- Search indexing now includes document text, image details, link values, Block fields, and nested Vizy content.
- Rewrote the documentation for field setup, authoring, rendering, querying, GraphQL, extensions, and upgrading from Vizy 3. (#283 (opens new window))
Fixed
- Fixed a moderate-severity cross-site scripting vulnerability in Tiptap (GHSA-cp6q-959q-f8rh (opens new window)).
- Fixed duplicated entries and repeated field placements sharing or losing Matrix content inside Vizy Blocks. (#376 (opens new window))
- Fixed Matrix validation checking saved rows instead of submitted changes, and preserved pending Matrix edits when an entry fails validation.
- Fixed removed Vizy Blocks leaving their Matrix content active. Restoring a removed Block restores its owned content.
- Fixed Craft field merges leaving Block Type layouts pointed at deleted fields, which could remove embedded values on a later save. (#346 (opens new window))
- Fixed Craft field and tab conditions inside Blocks not updating as sibling field values change. (#64 (opens new window), #233 (opens new window))
- Fixed Entry fields inside Blocks resolving relations against the wrong site in multi-site installs. (#319 (opens new window))
- Fixed custom-field conditions on Matrix entry queries inside Blocks. (#309 (opens new window))
- Fixed JSON fields inside Blocks failing to load or persist, and JSON-looking Plain Text values being decoded as arrays. (#352 (opens new window))
- Fixed unsupported TipTap nodes blanking the editor or appearing to lose content. Legacy
list_itemnodes are repaired and other unsupported content is visibly preserved. (#231 (opens new window)) - Fixed private asset volumes being omitted from field settings and asset pickers, including support for image editing and transform previews when originals have no public URL. (#256 (opens new window))
- Fixed custom Entry sources being omitted from link pickers and restricted sources being shown. (#226 (opens new window))
- Fixed link insertion at an empty caret, schemeless
www.URLs, and plain email addresses being stored withoutmailto:. (#262 (opens new window), #290 (opens new window), #238 (opens new window))
Deprecated
- Deprecated
VizyDocument::getField(),getRawNodes(),renderHtml(), andrenderStaticHtml(); usefield(),content().nodes(), andrender(). - Deprecated the GraphQL
rawNodesandrenderHtmlaliases; userawor noderaw, andrenderedHtml. - Deprecated legacy editor toolbar tokens that can be converted to Vizy 4 Editor Config controls.
- Deprecated
EVENT_DEFINE_VIZY_CONFIG,EVENT_MODIFY_PURIFIER_CONFIG,registerPlugin(), and theCraft.Vizy.ConfigJavaScript API. These compatibility surfaces no longer configure the editor; use named Editor Configs,EditorManifests::EVENT_MODIFY_EDITOR_CONFIG, and the Extensions APIs.
Removed
- Removed the Vizy 3
NodeCollectionfield-value contract, string-cast rendering, typed GraphQL tree, and field-local Block Type ownership. - Removed
Content::modifyFieldContent(); integrations should usecaptureFieldLocations()andmodifyFieldValues()from the raw content API. - Removed non-empty attribute-map configuration from
renderHtml()andrenderStaticHtml(); use node render events or Block templates to customise output. - Removed the unused
recursiveFieldCountsetting and the ability for a Vizy field save to modify global Block Type schema as a side effect.