Version v1.84.0 Changelog October 15, 2026
Breaking Changes
Single Page Mode
- Engine: Single page mode is now part of the engine. Turn it on with the setting
features/singlePageModeEnabled. Usescene.setCurrentPagesto select one page, or two facing pages, to show. Usescene.getCurrentPagesto read them. All other pages stay in the scene and in saved files. An export of the scene holds every page, also the pages that the mode does not show. - Engine:
block.isVisiblenow returns only the value that you set withblock.setVisible. A page that single page mode does not show returnstrue. Usescene.getCurrentPagesto find the shown pages. - Engine: If single page mode is on when a scene loads, the mode controls the pages that the scene saved as hidden. The next save stores these pages as visible.
- Editor/Web: The layers panel lists only the pages that the mode shows, and lists every page again when the mode is off. A row of the list no longer changes the pages in view.
- Editor/Web: Use
cesdk.switchPageto show a page and scroll to it. It replacesunstable_switchPage, which is deprecated. The single page mode toggle now changesfeatures/singlePageModeEnabled.
Themes & Contrast
- Editor/Web: Added the
light-high-contrastanddark-high-contrastthemes. They meet WCAG 2.1 AAA text contrast and draw every control boundary at 3:1 or more. The label of an active control meets AA while it is hovered or pressed. Select them withcesdk.ui.setTheme()or in the settings panel. - Editor/Web:
cesdk.ui.getTheme()can now return'light-high-contrast'or'dark-high-contrast'. The'system'theme resolves to them when the operating system asks for more contrast.- A check like
getTheme() === 'dark'does not match the dark high-contrast theme. UsegetTheme().startsWith('dark')instead. - TypeScript code that stores the result as
'light' | 'dark'must use theThemetype. - Custom themes scoped with
[data-ubq-theme='light']or[data-ubq-theme='dark']do not apply to the high-contrast themes. Add those selectors only if your colors keep the contrast the high-contrast themes provide.
- A check like
- Editor/Web: Refreshed the
lightanddarkthemes. Buttons, inputs, tab bars and button groups have a 1px edge, active controls show a tint of the active color, and each theme uses one accent color whose button labels meet WCAG AA. Accent and danger split buttons separate their parts with a small gap. - Editor/Web: Added the
--ubq-interactive-stroke,--ubq-interactive-accent-stroke,--ubq-interactive-danger-strokeand--ubq-interactive-active-washtheme tokens. A custom theme that sets--ubq-interactive-accent-defaultor--ubq-interactive-danger-defaultshould also set the matching stroke token. Set--ubq-interactive-stroketotransparentto remove the edges of neutral controls. - Editor/Web: Color inputs now show hover and pressed feedback.
- Editor/Web: The placeholder over a broken block now uses a fixed light red in every theme, so its icon stays visible. Its color comes from the new
--ubq-static-error-statetoken instead of--ubq-notice-error.
PDF Conversion Runtime
- Plugins/Web: The print-ready PDF plugin runs Ghostscript in a worker and supports sharing the conversion runtime with EPS import. Existing PDF/X options and
convertToPDFX3remain available. For npm integrations, hostworker.browser.js,gs.js, andgs.wasmfrom@imgly/pdf-conversion-utilsand inject a runtime with thatassetBaseURL. For direct imports ofdist/index.mjs, deploy the complete plugindist/tree, includingpdf-conversion/. Update CSP to permit workers and WASM compilation; cross-origin workers also requireblob:and the asset origin. Hosting the worker on the application origin avoids the blob requirement. See the plugin README for migration details.
Structured Errors
- Engine/Web, Engine/Node:
engine.block.export,exportWithColorMask,exportAudio,saveToArchive,getVideoFillThumbnail,getVideoFillThumbnailAtlas,getPageThumbnailAtlas,generateThumbnailAtTimeOffsetandengine.scene.saveToArchivenow reject with anEngineErrorinstead of a string. On Web,engine.block.exportVideodoes the same.engine.block.getDominantColors,generateVideoThumbnailSequence,generateAudioThumbnailSequenceandengine.editor.getBufferDatareport anEngineErrorinstead of a plainError. Readerror.messageand branch onerror.codeinstead of treating the reason as a string. - Engine/Node Native:
engine.block.saveToStringandengine.block.saveToArchivereject an unknown block with an error that has acode, as@cesdk/nodedoes. Before, the error had nocode.
Video Capabilities
- Engine/Web: The engine now implements
video.decode.checkSupportandvideo.encode.checkSupport, also in@cesdk/nodeand@cesdk/node-native, so an integration without the editor can ask whether this browser plays or exports video. Each action measures the codecs on first use, then answers. CE.SDK overrides both to add its dialogs, so the editor behaves as before. - Editor/Web:
video.decode.checkSupportnow resolves to its answer asynchronously, likevideo.encode.checkSupport.cesdk.actions.run()callers are unaffected. Code that calls the function fromcesdk.actions.get('video.decode.checkSupport')directly, or uses theVideoDecodeCheckSupportActiontype, must now await it. - Editor/Web: Deprecated
cesdk.utils.supportsVideoDecode()andcesdk.utils.supportsVideoEncode(). Run thevideo.decode.checkSupportorvideo.encode.checkSupportaction with{ dialog: false }instead. The actions also answerfalseon iOS and iPadOS.supportsVideoDecode()again only checks that the video APIs exist, as before v1.80, so it can answertruein a browser that cannot decode H.264.supportsVideoEncode()measures the codecs on its first call, so that call can take a moment. - Engine/Web:
CreativeEngine.init()no longer measures the codecs. They are measured when something asks: the two video actions, orengine.editor.checkCapabilities(). Until then,engine.editor.getCapabilityState()reports each codec as'unchecked'. Init still measures the storage capabilities, which export staging and archiving read. The engine answers each capability once, so the first call can take a moment and later calls return at once. A measurement the browser cuts off, as a background tab can, is no answer: the engine measures again rather than report'unsupported'. - Engine/Node: Deprecated
engine.editor.isCapabilitySupported(). Useengine.editor.getCapabilityState()instead.CreativeEngine.init()no longer measures the codecs in@cesdk/node. Node has no WebCodecs, so the answer was always no. - Editor/Web: CE.SDK’s
video.decode.checkSupportandvideo.encode.checkSupportwrap the engine’s checks, which answer for the codecs alone, and add the iOS and iPadOS rule and the dialogs.
Actions
- Editor/Web:
cesdk.actions.run()is now typed to resolve to the value an asynchronous action resolves to. Before, the type said it resolved to a promise of that value. Code that awaited the result was already correct. - Engine/Web:
engine.actions.get(id)now returns every registered action, including the ones the engine registers such ashistory.undo, which it returns as an async function. Before, it returnedundefinedfor them. The function keeps running that action after the id is registered over, so an override can build on it. Also in@cesdk/nodeand@cesdk/node-native. - Engine/Web:
engine.actions.unregister(id)now removes the action whoever registered it, and nothing comes back in its place. Before, unregistering an id the engine registers restored the engine’s action. To restore it, register the functionengine.actions.get(id)returned before you replaced it. Unregistering an id the engine runs on input, such asselect, turns that interaction off. Also in@cesdk/nodeand@cesdk/node-native.
Animation & Cropping
- Engine: A Ken Burns animation now has room to pan when you attach it through the API, also in headless renders. Attaching it replaces the crop of the block. To use your own crop, set it after the image or video has loaded. Older scenes get the room when they load, with the crop centered.
Android List Builders
- Editor/Android:
addFirstwith analignmentin themodifyblock of a list builder now adds each item at the front of its group, asaddFirstwithout an alignment does. Before, each further call added its item after the previous one. If you calladdFirstmore than once with the same alignment, reverse the order of those calls to keep your current button order.
Deprecations
All items below remain functional this release; migrate before they are removed.
Video Capability APIs
- Engine/Web: Deprecated
supportsVideo(),checkVideoSupport(),supportsVideoExport()andcheckVideoExportSupport(). The first two only check that the video APIs exist, and the other two run a codec test of their own that can disagree with the engine. Run thevideo.decode.checkSupportorvideo.encode.checkSupportaction instead. - Engine/Web: Deprecated
engine.editor.isCapabilitySupported(). It answersfalsefor a capability that is not measured yet, the same as for one the platform lacks. Useengine.editor.getCapabilityState(), which tells the two apart, or run a video action to ask about video. The deprecated method logs a warning the first time it answersfalsefor that reason.
New Features
Agent Skills
- Editor/Flutter, Editor/RN: The
imgly-sdkagent skills plugin now covers Flutter and React Native. Thedocs,explain, andbuildskills detect a Flutter or React Native project, read the bundledimgly_editor,imgly_camera,@imgly/editor-react-native, and@imgly/camera-react-nativeAPI digests, guides, and examples, and point at the bundled Swift and Android references for the customizations that live in native code. To change part of a prebuilt editor, such as its dock, they start from the wrapper’s own Swift and Kotlin sources, which the plugin now bundles. Install it withclaude plugin install imgly-sdk@imgly,codex plugin add imgly-sdk@imgly, ornpx skills add imgly/agent-skills; an existingcesdk@imglyinstall picks up the new references on its next update.
Examples & Starter Kits
- Editor/Android: Make the curated guides and starter kits available in the runnable public examples app.
- Editor/iOS: Added a Content Moderation starter kit that checks a design’s images and text against a content moderation service, reports flagged categories grouped by block in a validation sheet, and gates export on the result.
Video Capabilities
- Engine/Web: Added
engine.editor.getCapabilityState(capability), also in@cesdk/nodeand@cesdk/node-native. It answers'unchecked'until something asks for the capability to be measured,'pending'while it is measured, then'supported'or'unsupported'. Only the codecs on the web are ever'unchecked'or'pending'. In CE.SDK, a component that renders from it updates by itself when the state changes.
Shapes & Asset Sources
- Editor/Web + Engine/Web + Engine/Node: The Outline, Gradient and Image groups of the Shapes library now include a Line, as the Filled group already did. The bundled
ly.img.vector.shapesource lists the same new Lines.
Node Native Live View
- Engine/Node Native: New experimental live view.
attachCanvas()hands the update loop to a host. The host reads each frame as RGBA with straight alpha and forwards mouse, wheel and keyboard input to the engine. - Engine/Node Native: New experimental
TerminalCanvasshows the engine in a terminal that supports the kitty graphics protocol, such as kitty, Ghostty or WezTerm.
Notifications
- Editor/Web: Users can choose how long notifications stay on screen (5, 10 or 20 seconds, or never) from the notifications themselves. The default is 5 seconds, and the choice persists in the browser.
Placeholders
- Editor/Web: A new
ly.img.placeholder.inspectorBarbutton marks and opens placeholder settings, and the Placeholder tab gained an “Always highlight on canvas” toggle, off by default.
UI Customization
- Editor/Web:
builder.ButtonacceptsactiveStateStyle, asbuilder.Dropdownalready does. Set it to'pill'to mark an active button with an underline instead of an outline. - Editor/Web: A
ly.img.assetLibrary.dockentry takes an optionaltooltip, as a string or a function that returns one.
Separate Audio
- Editor/Web: The clip menu of a video clip in the timeline has a new “Separate Audio” item below “Trim”. It moves the audio of the clip into new audio clips, one per audio track, and mutes the video clip. The audio clips start with the clip, keep its speed and volume, and take its name. The item shows for background clips and overlay clips whose video has audio.
- Editor/Web: The item is the
ly.img.video.clip.menu.separateAudiocomponent of the clip menu. Leave it out of the component order to hide it.
Text Formatting & Tabs
- Engine: Added subscript and superscript text formatting. Use
setTextScriptStyleandgetTextScriptStylesto move a range of text above or below the baseline. Lines and exports grow to include the shifted text. Use the block propertiestext/superscriptFontScale,text/superscriptVerticalShift,text/subscriptFontScaleandtext/subscriptVerticalShiftto change the size and the offset of the shifted text. - Engine: Text blocks now lay out tab characters. A tab moves the text after it to the next tab stop and wraps to the next line at the frame edge. The
tabStopIntervalsetting sets the distance between stops (default 2 × the base font size). The Tab key inserts a tab character through the newtext.tabaction. In a list, Tab and Shift+Tab change the indent level instead, throughtext.tabandtext.tabBack. A justified line that holds a tab keeps its natural width.
Print Marks & Grid Controls
- Editor/Web: A color picker in the Safety Margin controls sets the color of the safety margin on every page, as it does for the grid and the bleed. Enable or disable it with the new
ly.img.page.printMarks.safetyMargin.colorfeature key. - Editor/Web: A lock next to Grid Width and Grid Height links the two values. While it is on, a change to one sets both.
Improvements & Behavior Changes
Agent Skills
- Engine/Web, Editor/Web, Engine/Swift, Editor/iOS, Engine/Android, Editor/Android: The CE.SDK agent skills now ship as one
imgly-sdkplugin with three skills,docs,explain, andbuild, that cover Web, Swift, and Android. Each skill detects the platform from the project and loads the matching bundled references. Install it withclaude plugin install imgly-sdk@imgly,codex plugin add imgly-sdk@imgly, ornpx skills add imgly/agent-skills. The per-frameworkdocs-<framework>skills and the separatecesdk-swiftandcesdk-androidplugins are retired; an existingcesdk@imglyinstall picks up the new layout on its next update. - Engine/Web, Editor/Web, Engine/Swift, Editor/iOS, Engine/Android, Editor/Android, Editor/Flutter, Editor/RN: The CE.SDK agent plugin is now listed as “IMG.LY SDK” and installs as
imgly-sdk@imgly:claude plugin install imgly-sdk@imglyorcodex plugin add imgly-sdk@imgly. In Claude Code, an existingcesdk@imglyinstall keeps updating; its skills are now/imgly-sdk:docs,/imgly-sdk:explain, and/imgly-sdk:build. In Codex, replace it:codex plugin remove cesdk@imgly, thencodex plugin add imgly-sdk@imgly. Agents now pick the plugin for any request to build a photo, video or design editor, even when CE.SDK is not named. Prerelease channels have their own marketplace names, soimgly-sdk@imgly-nextandimgly-sdk@imgly-devcan be added beside stable; keep only one channel enabled. - Engine/Web, Editor/Web, Engine/Swift, Editor/iOS, Engine/Android, Editor/Android, Editor/Flutter, Editor/RN: The
imgly-sdkagent skills plugin now reads the CE.SDK guides for the project’s CE.SDK version fromhttps://img.ly/docs/cesdk/as Markdown instead of bundling them, so the skills need network access for guides. The API digests and agent rules stay bundled. Thebuildskill now clones the public starter kit repositories at the branch of the plugin’s CE.SDK version instead of copying bundled kits.
Camera Orientation
- Camera/Android + Camera/iOS: Camera controls, dialogs, photo previews, and captured photos and videos now follow the device orientation. On Android, photos and videos use the orientation at capture time, and capture results include matching dimensions and positions. Videos keep their starting orientation during recording. Reaction recordings keep the first take’s orientation until all takes are deleted. Front-camera photos are mirrored to match the preview.
Inspector & Page List
- Editor/Web: The fill button in the inspector bar shows a thumbnail of the block’s image or video, in place of the fill type icon. The inspector and the fill panel show the same thumbnail.
- Editor/Web: The opacity button in the inspector bar shows the opacity of the selected block, for example “50%”, in place of the “Opacity” label. Screen readers read the button as “Opacity: 50%”, with the
input.opacitylabel. - Editor/Web: The page list shows each page number before the page name, for example “Page 3 - Cover”. The number follows the page order, so a moved page shows its new number.
- Editor/Web: The Shadow button moved from the inspector bar into the Style popover, below Blur, in the CE.SDK editors and starter kits. When only one Style control applies to the selected block, the inspector bar shows that control directly. A shape or a text block, for example, keeps its Shadow button on the bar.
- Editor/Web: The rotation field in the inspector now shows decimal degrees with up to two decimals, such as 12.5°, instead of rounding the displayed angle to whole degrees.
- Editor/Web: The inspector now saves a new block name when you click outside the name field. Before, only Enter saved it.
Notifications
- Editor/Web: Every notification now stays for that chosen time, so the
durationvaluesshort,medium,longand custom milliseconds no longer change it.duration: 'infinite', errors and notifications with an action stay until closed. - Editor/Web: Notifications show the time they have left, and keyboard focus pauses them like mouse hover does.
Accessibility & Interaction
- Engine: A placeholder block now gets a dotted selection and hover frame, so color is not its only marker. The
alwaysHighlightPlaceholderssetting draws its frame dotted too, at half opacity. - Editor/Web: Scrollable panels, menus, lists, the dock and the inspector bar now fade out at each edge that has more content. The fade is always on.
- Editor/Web: While text is edited on the canvas, screen readers announce “Text content” in the language of the editor.
- Editor/Web: Controls have clearer accessible names for screen reader and speech recognition users.
- Editor/Android: Screen readers announce which blend mode and which font is selected in their lists.
- Editor/Web: Controls that show only an icon now have a tooltip and an accessible name, also on narrow screens.
- Editor/Web: Disabled number fields, and a disabled
builder.Checkboxwith a truncated label, show their tooltip on hover.
Themes & Canvas Colors
- Editor/Web: The canvas colors (page title, selection frame, placeholder highlight, progress, broken-block fill) now follow every theme change, including
cesdk.ui.setTheme()and a change of the operating system’s color scheme or contrast. A theme change overwrites values set withengine.editor.setSetting(); to keep custom canvas colors, set the matching theme tokens in CSS instead.
Keyboard Shortcuts
- Engine/Web: The engine now binds the keyboard shortcut listener to the canvas element it creates, so the default shortcuts reach the engine without extra wiring. Pass your own
canvasin the configuration and the engine has no element of its own, so name the listening element withengine.shortcuts.setRoot.
API Types & Validation
- Editor/Web: The
payloadoption ofbuilder.Component()is now typed asComponentPayloadinstead ofany. - Engine:
setInt,setBool,setFloatand theirsetSetting…forms store a number in an enum only when an option has that number.setStringandsetSettingStringreturn an error for an enum.setSettingBool,setSettingIntandsetSettingFloaton an enum setting are deprecated. UsesetEnumorsetSettingEnumfor an enum.
Localization & Labels
- Editor/Web: The stroke toggle is now named “Enable Stroke”, and the fill toggle of a text “Enable Fill”, instead of “Enable Color”.
- Editor/Web: Error dialogs for start-up, export, templates and uploads show a specific message in English and German, for example “Lizenz abgelaufen”. An error without such a message shows the dialog’s general text, never the English engine text.
- Editor/Web: A transition that fails to apply shows a translated notification instead of the English engine text.
- Editor/Web: In German, text presets, text combinations and caption presets show German names.
- Editor/Web: German sticker and shape names are corrected, for example “Klebeband 01” instead of “Tape01”.
- Editor/Web: The Tilt Shift effect is named “Tilt Shift” in English and “Tilt-Shift” in German, instead of “Tiltshift”.
- Engine/Web, Engine/Node: Every asset in the default asset sources has a German label.
- Engine/Web, Engine/Node: The
ly.img.effect.extrude_blurasset has the English label “Extrude Blur” instead of “Explode”, as in the editor. - Engine/Web, Engine/Node: The English labels “Thumps up” and “instagram Profile Photo” now read “Thumbs up” and “Instagram Profile Photo”.
- Editor/Web: German texts use one term for each concept, for example “Inspektor”, “Arbeitsfläche” and “Schleife”.
- Editor/Web: With the
differentPageFormatsfeature flag, the Resize panel now reads “Resize Selected Pages” with the page count when several pages are selected. Before, it read “Resize Page”. The new translation key iscomponent.pageResizePanel.labelSelectedPages.
Sliders & Page Resizing
- Editor/iOS, Editor/Android: The opacity slider in the Layer sheet now snaps to 5% steps, so the value shown is the value set. This makes it possible to set the same opacity on several blocks.
- Editor/iOS, Editor/Android: Percent readouts on sliders now round instead of truncate, so 89.5% shows 90 and not 89.
- Editor/iOS: The star Points and polygon Sides sliders in the Shape sheet now snap to whole numbers and show the value without decimals.
- Editor/Web: The Resize Page panel shows “Mixed” for a width or height that differs between the pages it resizes. Apply then changes only the values you type, and each page keeps its own value for the other side.
PDF Conversion Limits
- Plugins/Web: Print-ready PDF conversion accepts outputs larger than 100 MiB by default. Use
maxOutputBytesto set a limit when needed.
Resource Error Display
- Engine: A block whose file failed now draws its content below the error color. A block that you put in an error state with
setStatestill covers its content.
Scene Persistence
- Engine/Web, Engine/Node:
block.saveToStringalso allowsbundleresources by default, so a page with text in a default font saves with the default schemes. - Engine: Scenes and archives no longer store which blocks are selected, and loading one no longer selects blocks. Undo and redo still restore the selection.
Text Decoration
- Engine: A text stroke now also outlines the underline, strikethrough, and overline. Before, only the letters got the outline.
Video Resource Lifetime
- Engine: The engine releases the memory of a video when no block uses it. On Android, a removed audio or video fill also releases its decoder.
Starter Kit Timelines
- Editor/Web: The Video Animations and Export using CE.SDK Renderer starter kits, and the Adopter mode of the Video Placeholders starter kit, now use the simplified video timeline of the Video Editor starter kit, so the canvas keeps its room on laptop screens. Creator mode keeps the full timeline.
Performance & Package Size
- Engine: An image embedded as a
data:URI no longer leaves two extra copies of itself in memory for as long as the app runs. A scene with 20 embedded images of 4 MB now keeps 84 MB less after it is closed, and it loads faster, because the engine reads such a URI once instead of three times. - Engine: A loop of
block.export()calls uses much less memory on a scene with many blocks. Before, a large scene filled the WebAssembly heap and the next engine call stopped withAborted(). - Engine: Large scenes load faster and use less memory. A 300-page scene loads in about two thirds of the time, with 84 MB less peak memory. LUT filters and word-by-word text animations do less work on each frame.
- Engine: Reduced the bundled CMYK profile size from 584 KB to 296 KB without changing color conversion.
- Engine: You can now add and change text quickly in scenes with many blocks. Before, each text change took more time as the scene grew.
Android Diagnostics
- Engine/Android: The engine logs its graphics setup to logcat at debug level, under the tag
UBIQU. The log names the GPU driver, the drawing surface format and size, and Display P3 support. It also reports when the engine cannot create, re-create or present its drawing surface.
Bug Fixes
Engine
- In the Adopter role, a single drag on a group that allows selecting and moving now selects and moves it. Before, the first drag only selected the group.
- The engine no longer crashes on an old scene whose fill type does not match its data.
- An animation asset with an unknown type, or on a slot or block that does not support it, returns an error. Before, the engine crashed. A Ken Burns animation from the animation asset source now stays on the block.
- Audio exports now play each clip and fade at its time on the timeline, the same on every export.
- Audio extracted with
createAudioFromVideoorcreateAudiosFromVideoandkeepTrimSettingsnow plays like the video. It plays the same part of the video at the same speed, lasts as long as the clip, and keeps the volume, mute state, looping and audio fades of the video. The audio of a video faster than 3x is force muted, like the video. Before, the audio of a faster or slower clip played the wrong part at normal speed. - Exporting the audio of a block, a track or a group no longer crashes the engine or removes blocks from the page.
- An audio export that fails no longer changes what the next audio export contains.
combine,createCutoutFromOperationandcreateCutoutFromBlocksreturn an error that names the block when they cannot compute the boolean operation. Before, the result left out that block and the call reported success.- Crop mode now stays open while a transition covers the selected clip, and while the playhead sits outside it. Before, the mode dropped back to
Transformon the next change. createCutoutFromBlocksnow makes a cutout from a text block in a headless engine, such as@cesdk/node. Before, the call crashed the engine unlessuseExistingShapeInformationwasfalse.- The engine no longer crashes on a damaged GIF or MP4 file.
- Fixed blocks jumping to a wrong size or position when a drag runs while the camera is still moving, for example right after a pinch or a zoom.
exportVideoon a block that is not attached to the scene now fails withBLOCK.NOT_ATTACHED_TO_SCENE, asexportdoes. The native engines crashed the process instead.exportWithColorMaskwith the mime typeapplication/pdfnow reports “Color masking is not supported for PDF export.” A PDF export never runs the raster pass that builds the mask, so the call used to report a non-specific “Export failed.” The hint of the same error for SVG no longer points at PDF.- A block no longer jumps at the start of a move. The text cursor stays correct while an input method writes accented or non-Latin text.
- Fixed the thin bands that crossed a large gradient fill. A wide, low-contrast gradient now stays smooth on the canvas and in every export.
- Activating a new history with
setActiveHistorykeeps the current scene, including edits not yet committed withaddUndoStep. Before, those edits were lost. - Pages that overlap in a free layout now show the page in front. Before, the shared area was rendered blank during preview.
- The bleed band and the bleed line now cover the whole bleed of a page with
page/marginScaleabove 1 that is not square. - On any page with
page/marginScaleabove 1, the page background now fills the bleed and the page bounding box includes it. Blocks snap to the bleed edge and can move up to it, and a click on the bleed selects the page. - PDF export preserves fractional page dimensions instead of rounding them to whole points, keeping the physical page size and bleed geometry accurate.
- A PDF export with
exportPdfWithUnderlayerkeeps its underlayer whenunderlayerOffsetis negative. Some pages lost the white spot separation at particular offset values, for example -0.2 and -1.0, while nearby values worked - Two engines that play audio at the same time no longer mix their audio.
- The playhead now keeps its position when a split puts a clip into a new track, or when a clip moves into a track. Before, it jumped back to 5 seconds or to the old end of the track.
- A block that failed to load its image or video now shows the new file when you replace it. Before, the block kept the first error and never asked for the new file.
- A block waits, and no longer shows an error, while it loads the file that replaced a file that failed.
- When you resize or crop a block and it moves to another page, the edge you do not drag now stays in place. Before, the block jumped by the distance between the pages.
- A resource load that finishes after its block is gone no longer kills the process. With a URI resolver installed,
forceLoadResourcescould end the process at the next scene change or at shutdown. saveToStringfor blocks now checks the resources of the whole block hierarchy, the typeface fonts of text blocks included. Saving a page reports the resources of its children to the persistence callback and writes the persisted URLs. A child resource on a scheme that the call does not allow now gives an error, as documented.- Loading a page from an archive made with
saveToArchivenow links the images and other resources of its children to the files in the archive. Before, only the page itself was linked, and its children showed missing images. - A save no longer changes the resource URLs of the scene while uploads are in progress, or after one of them fails.
- After a save, a block that already used the URL an upload returned keeps that URL.
- Loading blocks from a string that is not valid returns an error. Before, it returned no blocks, or it changed blocks in the scene.
- A scene load with
features/removeForegroundTracksOnSceneLoadno longer loses clips. - Undo, redo, paste and duplicate no longer turn the
appearance/animationscope back on for blocks of older scenes. - A scene that you build through the API now reports the size of its first page in
scene/pageDimensionsuntil you set a value. The first save of such a scene now matches every later save. - A load no longer replaces the
scene/pageDimensionsthat you set with the size of the first page. - Applying a template now keeps the page size of a scene that you just built. On a scene without pages, the template keeps its own page size.
- Text with an
Outerdashed or dotted stroke and no fill no longer draws a thin line along the letters. The line appeared when the dash start and end caps had different shapes. - A strikethrough, underline or overline now draws in front of the text stroke. The outline of the letters covered it before.
- A text block without a typeface now accepts the font weight and style that the engine reports for it. Before,
setTextFontWeightandsetTextFontStylerejected the value thatgetTextRunsorgetTextFontWeightshad just returned. getTextRunsnow reports the real weight and typeface of a text block that has no typeface, instead ofnormaland an empty typeface.- The font weight, font style, bold and italic APIs now use the typeface of the font that a text block renders with when the block has no typeface.
- A change of the scene design unit keeps the text line breaks, the visible lines and the automatic font size. Before, a text block with a tight frame could break into two lines after
setDesignUnit('Pixel'). - Fixed text typed over a selection that took the font size of the next line. The new text now gets the style of the first selected character.
- A triple-click now selects a line without its line break, so typing over the line keeps it apart from the next line.
- The drop shadow of curved text, and of text with a per-letter, per-word or per-line animation, now follows the opacity of the text, its stroke and its decorations. Before, this text cast an opaque shadow, unlike other text.
getEnum,getInt,getGlobalScopeand the other typed getters return an error for an unknown value, or for a property or setting of another type. Before, the engine could crash or return a wrong value.- The engine no longer crashes on an unknown enum value in a scene.
getSettingEnumreturns an error for an unknown value, or for a setting of another type. Before, the engine could crash.- A video export that fails no longer blocks the next one. Before, every later video export on the same engine failed with a concurrent encoding error.
- A video export fails with an error when the video encoder stops, for example on a frame that is too large for it. Before, the export never ended, and on Linux with the open-source codecs the process crashed.
- Fixed pages that stayed a grey placeholder when the view jumped to them with viewport culling enabled. This happened after
zoomToBlockon load followed by a page thumbnail export, and after a page above them was resized. - A zoom with the mouse wheel or with a pinch keeps the design point under the pointer in place, also in a scene with many pages. Before, the view moved away from that point.
setZoomLevelkeeps the content at the center of the view in place, also in a scene with many pages.- A style change on one caption now also updates the size and line breaks of the other captions on the track.
- An absolute base path with
[,#or a space in a folder name now finds every bundled file, the ICU data included. A base path that is neither a file path nor a URI no longer stops the engine; the bundled files then fail to load. - Fixed
spliton a clip with an outgoing transition. Only the second half keeps the transition, so the cut between the halves has none. - Only the Creator role sees the dotted selection and hover frame of a placeholder block. All other roles see a solid frame again, as before 1.84. The
alwaysHighlightPlaceholdersframe stays dotted for every role. - Fixed a crash when a page with a track or a group was added below the visible part of a scene, for example after a video export.
Editor/Web
- In the Adopter role, the fill type picker, the Replace button and the shadow and stroke panels are locked when the block’s scopes deny those changes. Before, an Adopter could still change them.
- In the Adopter role, the color fill button is hidden when the block allows only cropping (
layer/crop), because a color cannot be cropped. - In the Adopter role, the advanced text options open when the block allows text styling (
text/character). Their frame sizing buttons also needlayer/resize. Before, the options needed both scopes to open. - The
cesdkagent skills plugin converts a starter kit to JavaScript again. Before, the transpile script could not load TypeScript, andnpm run buildfailed withtsc: command not foundafter the conversion. The script now also converts.tsxfiles. - For a release candidate or nightly version, the
cesdkagent skills plugin now tells the agent how to install the starter kits. Before,npm installfailed withERESOLVEfor kits that use an importer. - The code blocks in the
cesdkagent skills plugin now render as code. Before, they showed as literal backslashes and backticks. - The web starter kits in the
cesdkagent skills plugin now install withnpm installand start withnpm run dev. Before,npm installfailed withUnsupported URL Type "workspace:". The kits now match the public starter kit repositories. - The automatic font-size range now shows the same unit as the font size input. On a
Pixelscene it labelled pixel values aspt. - Switching the font size to
Autono longer shrinks the text on aPixelscene when thely.img.scene.fontSizeUnitfeature is disabled. The range was written in points and stored as pixels. - A
builder.Dropdownwith more items than fit its height now scrolls. - The Advanced row in the caption inspector now fits the inspector panel and shortens its label with an ellipsis, as in the text inspector.
- Fixed the Placeholder item in the video clip menu showing for caption clips when a custom order includes it. Captions have no Placeholder view, so choosing it did nothing; the item is now hidden for them.
- The “Set as clip” item in the video clip menu now shows only for overlay clips. Before, a custom order could add it to the background clip menu, where it resized the clip to fill the page and moved it to the end of the track.
- The “Set as overlay” item in the video clip menu now shows only for background track clips. Added to a caption menu through a custom order, it moved the caption off its caption track onto the page.
- Moving the color picker’s saturation and brightness field with the arrow keys now adds its own undo step.
- With
ly.img.crop.panel.autoOpendisabled, closing the crop panel no longer ends crop mode, and a page’s crop handles stay visible while in crop mode. - Fixed shortcuts that took the arrow, Home, End, Page Up, Page Down, Backspace and Delete keys from a focused field in their own panel. In the crop panel, the arrow keys now step the size, scale and offset fields and move the straighten slider.
- Loading a scene while the crop panel is open no longer fails with an error.
- An open asset library shows its labels in the new language after
cesdk.i18n.setLocale(). - Enter Group and Select Group in the canvas menu keep their icon when the menu hides labels.
- When an upload fails, the progress dialog closes and the error shows. Before, a failed image upload left the progress dialog open.
- In German, the toggles of fills, strokes, shadows, filters and effects name their property again, for example “Desert aktivieren”.
- In German, the preset tooltip shows the preset name instead of
$(input.preset). - In German, effect names, the Credits dialog, the asset credits and the photo editor dock are no longer English.
- The Settings panel shows the names of the “End Cap” and “Dash Pattern” features instead of raw keys.
- The Stack, Line Wipe and Clock Wipe transitions show their names instead of raw keys.
- The unsupported-browser alert is German when the editor configuration sets
locale: 'de'. cesdk.utils.showLoadingDialoglabels its cancel button “Cancel” when you pass no label.- An
ly.img.assetLibrary.dockentry with akeyand nolabeluses thelibraries.<key>.labeltranslation. Before, it showedlibraries.ly.img.assetLibrary.dock.label. - Fixed long video clips showing a broken image instead of thumbnails in the video timeline, for example a two-hour clip at the default timeline scale.
- Fixed the on-screen keyboard not being reserved on mobile when the editor runs inside an iframe, which left the edited text behind the keyboard. The keyboard is now measured against the embedding page when that page is same-origin.
- Entering Preview mode deselects the selected block when the Adopter role cannot select it.
- Closing a notification twice no longer closes a different notification. This happened when users double-clicked the close button, or when
cesdk.ui.dismissNotification()ran twice with the same ID. A double-click also no longer callsonDismisstwice. - Fixed number fields switching the decimal separator on focus, for example from
24.5to24,5. - Fixed number fields that waited for
Enterafter an arrow key pressed with a modifier.Shift+ArrowUpandShift+ArrowDownnow change the value by ten steps, and the arrow keys withCmd,CtrlorAltchange it by one step. Both apply the value at once, like the plain arrow keys. The stepper buttons of a field withoutminnow also step from the shown value, like the arrow keys. - Number fields now show the stored value once you confirm an edit, also when the editor adjusts or refuses the typed number. For example, polygon sides round 5.5 to 6 instead of showing 5.5 and logging an error.
- The flip orientation button in the Page panel keeps its icon on square pages, where it is disabled, instead of looking missing.
- In the Photo Editor, the Adjust, Filter and Effects dock buttons are now disabled when the page has a color or gradient fill instead of an image. Hovering them shows “Requires an image”. Before, a click did nothing.
- Pressing Escape right after clicking the inspector’s rename button now closes the name field. Before, it could close only the button’s tooltip, and a second Escape was needed.
- The Replace panel now closes when the selected block has nothing left to replace, for example after its fill changes from an image to a color. Before, it showed an empty “Replace Shape” panel.
- The Resize Page panel now shows the current size of the pages it resizes. Before, it could show an old size after a resize through the API or from the page inspector.
- Fixed a
Block <id> is unknownerror when a scene loads while ascroll.toPageorscroll.toBlockanimation is running. The animation now stops when a different scene loads, and the action resolves. - Reset in the settings panel restores every setting the panel changes to the value it had when the panel was first opened. The Reset button is disabled while nothing differs.
- Trimming or moving a clip in the video timeline that shows only the selected track no longer moves that clip below the other layers. The clips the timeline hides keep their layer order.
- A single click on a color, volume, crop straighten or asset property slider now adds an undo step. Tabbing onto a slider no longer adds an empty one.
- Fixed a gap in the video timeline after you drop a clip next to a clip with a transition. The dropped clip now joins the transition. A clip that you drag away from a transition now stays where you drop it.
- Turning off
ly.img.transform.rotationhides only the rotation input, and turning offly.img.transform.fliphides only the flip buttons. Before, turning off either one hid both. - Fixed an error when the selected video or audio block is destroyed through the API.
- The “Placeholder” item in a video timeline clip’s menu now opens the Placeholder tab of the inspector. Before, it only marked the clip as a placeholder and the inspector stayed on the Design tab.
- The video timeline playhead no longer covers the top of clips when the time ruler is turned off, and its line reaches the bottom of the timeline. The timeline now fits its tracks exactly when a horizontal scrollbar appears or its controls wrap onto a second row.
- A collapsed video timeline now stays collapsed until the user expands it. Adding or removing clips no longer opens it again, and the same holds after
timeline.collapse. - The video timeline now fits its tracks exactly. It no longer scrolls up and down by a few pixels or shows a vertical scrollbar when all tracks fit.
- In the AI Editor starter kit’s photo mode, the AI Edit dock button is now disabled when the page has no image (for example a color or gradient fill), and hovering it shows “Requires an image”, like Adjust, Filter and Effects. Before, it stayed enabled and opened a panel whose Generate button could never be used.
- Dragging a finger across the saturation/brightness field of the color picker now changes the color on touch devices.
- The Style menu opens for a block whose duotone filter has custom colors. Before, the editor showed “Unknown Error” when the colors matched none of the built-in duotone filters.
- Fixed a console error loop that could freeze the tab when the page removed the editor container after
CreativeEditorSDK.create()failed. The editor’s error screen now closes itself once its container leaves the page. - Dialogs and popovers now keep focus inside their own editor when several editors run on the same page.
- Fixed
CreativeEditorSDK.create()leaving the engine running when it failed after the engine had started. - Safari on iPhone and iPad no longer zooms into the page when a text field gets focus. On touch devices, text fields use 16px text in the
modernandnormalscales. A custom theme can target touch devices with thedata-ubq-touchattribute. - The speed controls and the Custom stroke style option show German labels in the German editor. They showed English labels before.
- Fixed number and text fields, such as the hex color field, that showed an old value after Cmd+Z or Ctrl+Z while the design kept the new one. Undo in a focused field now discards a value that was not confirmed yet.
- Fixed number fields, including font size, bleed, crop size and crop position, that recorded no undo step when a change brought the value back to what it was before an undo.
- In the AI Editor (photo mode), Start With Image and Force Crop starter kits, the Adjust, Filter and Effects dock buttons (Adjust and Filter in Force Crop) are now disabled when the page has a color or gradient fill instead of an image, and hovering them shows “Requires an image”, as in the Photo Editor. Before, they stayed enabled although there was nothing for them to edit.
- Fixed popovers that ran past the edge of a short window, which hid their last controls, for example the RGB fields of the grid color picker. A popover is now as tall as the space next to its button allows, and its content scrolls.
- The Video Editor and Advanced Video Editor starter kits now show only video templates in the Templates panel. Before, the panel also listed the static design templates.
Editor/Android
- Fixed a crash when the selected block is deselected or deleted while the canvas menu has an enter or exit transition.
- The canvas menu’s bring forward and send backward buttons now update when a block is added to or removed from the selected block’s parent.
- Fixed the timeline’s add clip and add audio menus showing an empty entry for a hidden option. A button with one visible option now triggers it directly, as its label says.
- The icon of the fill and stroke button in the inspector bar now follows the fill color and the gradient colors of the selected block. Before, the icon kept the previous color when the fill was changed through the engine API, for example from a custom color picker.
- The replace button of the inspector bar is now hidden for an audio block when the
fill/changescope is denied.
Engine/Node
- Audio exports in
@cesdk/nodeare no longer silent. - When
asset.addSourcerejects a source, the Node.js process can exit afterdispose().
Engine/Web
- Fixed video export being reported as unavailable in a browser that supports it, when the page was busy while the check ran. The same fix stops PDF export and archiving from falling back to building their files in memory in that situation.
- Fixed
ReferenceError: __filename is not definedat engine start in apps built with some bundlers. This happened when a bundler replacedtypeof __filenamebut did not define__filename, for example webpack withnode.__filename: 'eval-only'. You can remove a__filenameworkaround that you added for@cesdk/engine. In Node.js, use@cesdk/node. block.exportWithColorMasknow accepts every optionblock.exportaccepts, soallowTextOverhang,exportPdfWithDeviceCMYK,pdfImageQualityandpdfChunkSizeno longer report “Invalid arguments”. This applies with and withoutfeatureFlags.exportWorker.block.exportnow accepts every export option in both call forms. With the mime type as a separate argument it refusedexportPdfWithDeviceCMYK,exportPdfWithCropMarks,exportPdfWithRegistrationMarks,printMarkOffset,cropMarkLength,printMarkWidth,pdfImageQualityandpdfChunkSize. WithfeatureFlags.exportWorkeron, it also refusedpdfChunkSizein the other form.- With
featureFlags.exportWorkeron,underlayerRenderRatio,underlayerMaxError,printMarkOffset,cropMarkLengthandprintMarkWidthnow refuseNaNandInfinity, as they already did without it and as their documentation states. - The engine releases a held mouse button when the editor loses the pointer. Before, the back and forward buttons could crash the engine.
- Fixed a crash (“memory access out of bounds”) that could stop the editor while several videos stream at the same time.
Engine/Web + Engine/Node Native
block.saveToStringandscene.saveToStringnow reject whenonDisallowedResourceSchemethrows, rejects, or returns no string. Before, the call never finished and the error was an unhandled promise rejection.
Editor/iOS
- Fixed the video editor in landscape. The timeline now collapses while a sheet is open, so sheets no longer float over a band of bare timeline chrome, and it shows one track row by default in landscape, so the canvas stays visible. The show/hide timeline toggle is now also available in landscape. Timeline customization follows: the default
heightis.fixed(tracks: 1)in a compact vertical size class, andTimeline.Buttons.toggleExpandedis visible in every size class by default. - Fixed the voiceover recording layout in landscape. The timeline lifts above the record bar, so the recording placeholder stays visible while recording.
- Sheet detents are now distinct in landscape. Small and medium sheets no longer collapse to the same height, and the drag indicator shows when a sheet is resizable.
- Fixed the preview-mode page layout when the editor is launched directly in landscape.
- Sheets are taller in landscape, so their content fits: effect and filter strips no longer cut their labels, and sheets such as Add Captions and Resize no longer overlap their title.
Editor/Android, Editor/iOS
- Fixed the previous page and next page navigation bar buttons, which stayed visible on the first and last page when the page carousel was enabled.
- Fixed clips that overlapped after a drag and drop in a track with transitions. A transition at a cut that the drop changes is now removed, and a message tells the user.
- Fixed the split position of a clip with an incoming transition. The clip is now split at the playhead.
Plugins/Web
- Fixed PDF/X export creating an empty TrimBox when the input PDF has no print bounds. The print-ready PDF plugin now uses each page’s CropBox or full page bounds and preserves existing TrimBox, ArtBox, and BleedBox values.
Engine/Android
- When
addSourcerejects a source because its id is in use, the registered source keeps working.
Renderer
- Emoji now render in color. Before, they rendered as empty boxes or in black and white. The assetless images now ship the Noto Color Emoji font.
- An engine option given on the command line, such as
--default-emoji-font-file-urior--max-image-size, now overrides the value that the scene stores. - Fixed video exports that stalled or showed frames in the wrong order for H.264 videos without B-frames when decoded by the AV-Licensed codec pack.
Renderer + Engine/Node
- Fixed video exports that stopped progressing when the decoder skipped frames of a source video. On Engine/Node: Fixed video exports on Linux and Windows that stopped progressing when the decoder skipped frames of a source video.
Engine/Node Native
process.exit()no longer crashes while the engine downloads a font.CreativeEngine.initon Windows no longer stops the Node.js process. The engine loads its bundled files, such as the ICU data, from the assets folder of the package.
Engine/Web, Engine/Node
features/textEditModeTransformHandlesEnabledis now part of the publicSettingstype, sosetSettingaccepts it without a TypeScript error. It keeps the resize, scale and rotate handles of a text block visible while its text is edited. Off by default.createAudioFromVideoandcreateAudiosFromVideonow extract the audio of a video file that is not completely in memory, such as an uploaded or a remote video. Before, the audio of such a video played noise or no sound, or the call failed. The audio now arrives after the call returns. Until then,unstable_isAVResourceLoadedreturnsfalse,forceLoadAVResourcewaits for the audio, and the audio block is pending once it is in the scene.
Engine/Swift
- A video export no longer crashes the app when it finishes, or after an engine was destroyed during an export.