Skip to main content

Version v1.19 of CreativeEngineSDK and CreativeEditorSDK introduces structural changes to many of the current design blocks, making them more composable and more powerful. Along with this update, there are mandatory license changes that require attention. This comes with a number of breaking changes. This document will explain the changes and describe the steps you need to take to adapt them to your setup.

License Changes#

The license parameter is now required for CreativeEngineSDK and CreativeEditorSDK. This means that you will need to update your license parameter in the CreativeEngine.init and CreativeEditorSDK.create configuration object properties. There is also a new userId, an optional unique ID tied to your application's user. This helps us accurately calculate monthly active users (MAU). Especially useful when one person uses the app on multiple devices with a sign-in feature, ensuring they're counted once. Providing this aids in better data accuracy.

Graphic Design Block#

A new generic Graphic design block with the type id //ly.img.ubq/graphic has been introduced, which forms the basis of the new unified block structure.


Similar to how the fill of a block is a separate object which can be attached to and replaced on a design block, we have now introduced a similar concept for the shape of a block.

You use the new createShape, getShape and setShape APIs in order to define the shape of a design block. Only the new //ly.img.ubq/graphic block allows for its shape to be changed with these APIs.

The new available shape types are:

  • //ly.img.ubq/shape/rect
  • //ly.img.ubq/shape/line
  • //ly.img.ubq/shape/ellipse
  • //ly.img.ubq/shape/polygon
  • //ly.img.ubq/shape/star
  • //ly.img.ubq/shape/vector_path

The following block types are now removed in favor of using a Graphic block with one of the above mentioned shape instances:

  • //ly.img.ubq/shapes/rect
  • //ly.img.ubq/shapes/line
  • //ly.img.ubq/shapes/ellipse
  • //ly.img.ubq/shapes/polygon
  • //ly.img.ubq/shapes/star
  • //ly.img.ubq/vector_path

(The removed type ids use the plural “shapes” and the new shape types use the singular “shape”)

This structural change means that the shape-specific properties (e.g. the number of sides of a polygon) are not available on the design block any more but on the shape instances instead. You will have to add calls to getShape to get the instance id of the shape instance and then pass that to the property getter and setter APIs.

Also remember to change property key strings in the getter and setter calls from the plural shapes/… to the singular shape/… to match the new type identifiers.

Image and Sticker#

Previously, //ly.img.ubq/image and //ly.img.ubq/sticker were their own high-level design block types. They do not support the fill APIs nor the effects APIs.

Both of these blocks are now removed in favor of using a Graphic block with an image fill (//ly.img.ubq/fill/image) and using the effects APIs instead of the legacy image block’s numerous effects properties.

At its core, the sticker block has always just been an image block that is heavily limited in its capabilities. You can not crop it, nor apply any effects to it. In order to replicate this difference as closely as possible in the new unified structure, more fine-grained scopes have been added. You can now limit the adopter’s ability to crop a block and to edit its appearance.

Note that since these scopes only apply to a user of the editor with the “Adopter” role, a “Creator” user will now have all of the same editing options for both images and for blocks that used to be stickers.


The following is the list of changes to the design block scopes:

  • (Breaking) The permission to crop a block was split from content/replace and design/style into a separate scope: layer/crop.
  • Deprecated the design/arrange scope and renamed design/arrange/movelayer/movedesign/arrange/resizelayer/resizedesign/arrange/rotatelayer/rotatedesign/arrange/fliplayer/flip
  • Deprecated the content/replace scope. For //ly.img.ubq/text blocks, it is replaced with the new text/edit scope. For other blocks it is replaced with fill/change.
  • Deprecated the design/style scope and replaced it with the following fine-grained scopes: text/character, stroke/change, layer/opacity, layer/blendMode, layer/visibility, layer/clipping, appearance/adjustments, appearance/filter, appearance/effect, appearance/blur, appearance/shadow
  • Introduced fill/change, stroke/change, and shape/change scopes that control whether the fill, stroke or shape of a block may be edited by a user with an "Adopter" role.
  • The deprecated scopes are automatically mapped to their new corresponding scopes by the scope APIs for now until they will be removed completely in a future update.


While the new unified block structure both simplifies a lot of code and makes design blocks more powerful, it also means that many of the design blocks that used to have unique type ids now all have the same generic //ly.img.ubq/graphic type, which means that calls to the findByType cannot be used to filter blocks based on their legacy type ids any more.

Simultaneously, there are many instances in which different blocks in the scene which might have the same type and underlying technical structure have different semantic roles in the document and should therefore be treated differently by the user interface.

To solve both of these problems, we have introduced the concept of a block “kind”. This is a mutable string that can be used to tag different blocks with a semantic label.

You can get the kind of a block using the getKind API and you can query blocks with a specific kind using the findByKind API.

CreativeEngine provides the following default kind values:

  • image
  • video
  • sticker
  • scene
  • camera
  • stack
  • page
  • audio
  • text
  • shape
  • group

Unlike the immutable design block type id, you can change the kind of a block with the new setKind API.

It is important to remember that the underlying structure and properties of a design block are not strictly defined by its kind, since the kind, shape, fill and effects of a block can be changed independent of each other. Therefore, a user-interface should not make assumptions about available properties of a block purely based on its kind.


Due to legacy reasons, blocks with the kind "sticker" will continue to not allow their contents to be cropped. This special behavior will be addressed and replaced with a more general-purpose implementation in a future update.

Asset Definitions#

The asset definitions have been updated to reflect the deprecation of legacy block type ids and the introduction of the “kind” property.

In addition to the “blockType” meta property, you can now also define the “shapeType” ,“fillType” and “kind” of the block that should be created by the default implementation of the applyAsset function.

  • “blockType” defaults to “//ly.img.ubq/graphic” if left unspecified.
  • “shapeType” defaults to “//ly.img.ubq/shape/rect” if left unspecified
  • “fillType” defaults to “//ly.img.ubq/fill/color” if left unspecified

Video block asset definitions used to specify the “blockType” as “//ly.img.ubq/fill/video“. The “fillType” meta asset property should now be used instead for such fill type ids.

Automatic Migration#

CreativeEngine will always continue to support scene files that contain the now removed legacy block types. Those design blocks will be automatically replaced by the equivalent new unified block structure when the scene is loaded, which means that the types of all legacy blocks will change to “//ly.img.ubq/graphic”.

Note that this can mean that a block gains new capabilities that it did not have before. For example, the line shape block did not have any stroke properties, so the hasStroke API used to return false. However, after the automatic migration its Graphic design block replacement supports both strokes and fills, so the hasStroke API now returns true . Similarly, the image block did not support fills or effects, but the Graphic block does.

List of all Removed Block Type IDs#

  • //ly.img.ubq/image
  • //ly.img.ubq/sticker
  • //ly.img.ubq/shapes/rect
  • //ly.img.ubq/shapes/line
  • //ly.img.ubq/shapes/ellipse
  • //ly.img.ubq/shapes/polygon
  • //ly.img.ubq/shapes/star
  • //ly.img.ubq/vector_path

UI Configuration#

The configuration options for the legacy blocks have also been removed under config.ui.elements.blocks and a new configuration option for the ly.img.ubq/graphic block type have been introduced which will then define which UI controls to enable for graphic blocks (crop, filters, adjustments, effects, blur). This new configuration option follows the same structure as before.

Here is a list of the deprecated block configuration options:

  • //ly.img.ubq/image
  • //ly.img.ubq/fill/video
  • //ly.img.ubq/shapes/rect
  • //ly.img.ubq/shapes/line
  • //ly.img.ubq/shapes/star
  • //ly.img.ubq/shapes/polygon
  • //ly.img.ubq/shapes/ellipse
  • //ly.img.ubq/vector_path


Some of the translation keys related to Scopes and Placeholder-Settings have been also updated:

  • Removed the following keys:
    • scope.content.replace
  • Renamed the following keys:
    • is now scope.layer.flip
    • is now scope.layer.move
    • is now scope.layer.resize
    • is now scope.layer.rotate
  • Added the following keys:
    • component.placeholder.appearance.description
    • component.placeholder.appearance
    • component.placeholder.arrange.description
    • component.placeholder.arrange
    • component.placeholder.disableAll
    • component.placeholder.enableAll
    • component.placeholder.fill.description
    • component.placeholder.fill
    • component.placeholder.general.description
    • component.placeholder.general
    • component.placeholder.shape.description
    • component.placeholder.shape
    • component.placeholder.stroke.description
    • component.placeholder.stroke
    • component.placeholder.text.description
    • component.placeholder.text
    • scope.appearance.adjustments
    • scope.appearance.blur
    • scope.appearance.effect
    • scope.appearance.filter
    • scope.appearance.shadow
    • scope.fill.change
    • scope.layer.blendMode
    • scope.layer.opacity
    • scope.shape.change
    • scope.stroke.change
    • scope.text.character
    • scope.text.edit

Types and API Signatures#

To improve the type safety of our APIs, we have moved away from using the DesignBlockType enum and replaced with a set of types. Those changes have affected the following APIs:

  • CESDK.engine.block.create()
  • CESDK.engine.block.createFill()
  • CESDK.engine.block.createEffect()
  • CESDK.engine.block.createBlur()
  • CESDK.engine.block.findByType()
  • CESDK.engine.block.getType()


The create, findByType, and getType APIs will no longer accept the IDs of the deprecated legacy blocks and will throw an error when those are passed

Code Examples#

This section will show some code examples of the breaking changes and how it would look like after migrating.

/** Block Creation */
// Creating an Image before migration
const image = cesdk.engine.block.create('image');
// Creating an Image after migration
const block = cesdk.engine.block.create('graphic');
const rectShape = cesdk.engine.block.createShape('rect');
const imageFill = cesdk.engine.block.createFill('image');
cesdk.engine.block.setShape(block, rectShape);
cesdk.engine.block.setFill(block, imageFill);
cesdk.engine.block.setKind(block, 'image');
// Creating a star shape before migration
const star = cesdk.engine.block.create('shapes/star');
cesdk.engine.block.setInt(star, 'shapes/star/points', 8);
// Creating a star shape after migration
const block = cesdk.engine.block.create('graphic');
const starShape = cesdk.engine.block.createShape('star');
const colorFill = cesdk.engine.block.createFill('color');
cesdk.engine.block.setInt(starShape, 'shape/star/points', 8);
cesdk.engine.block.setShape(block, starShape);
cesdk.engine.block.setFill(block, colorFill);
cesdk.engine.block.setKind(block, 'shape');
// Creating a sticker before migration
const sticker = cesdk.engine.block.create('sticker');
// Creating a sticker after migration
const block = cesdk.engine.block.create('graphic');
const rectShape = cesdk.engine.block.createShape('rect');
const imageFill = cesdk.engine.block.createFill('image');
cesdk.engine.block.setShape(block, rectShape);
cesdk.engine.block.setFill(block, imageFill);
cesdk.engine.block.setKind(block, 'sticker');
/** Block Creation */
/** Block Exploration */
// Query all images in the scene before migration
const images = cesdk.engine.block.findByType('image');
// Query all images in the scene after migration
const images = cesdk.engine.block.findByType('graphic').filter((block) => {
const fill = cesdk.engine.block.getFill(block);
return (
cesdk.engine.block.isValid(fill) &&
cesdk.engine.block.getType(fill) === '//ly.img.ubq/fill/image'
// Query all stickers in the scene before migration
const stickers = cesdk.engine.block.findByType('sticker');
// Query all stickers in the scene after migration
const stickers = cesdk.engine.block.findByKind('sticker');
// Query all Polygon shapes in the scene before migration
const polygons = cesdk.engine.block.findByType('shapes/polygon');
// Query all Polygon shapes in the scene after migration
const polygons = cesdk.engine.block.findByType('graphic').filter((block) => {
const shape = cesdk.engine.block.getShape(block);
return (
cesdk.engine.block.isValid(shape) &&
cesdk.engine.block.getType(shape) === '//ly.img.ubq/shape/polygon'
/** Block Exploration */