# To v1.19

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**[#](#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**[#](#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.

## **Shapes**[#](#shapes)

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**[#](#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.

## **Scopes**[#](#scopes)

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/move` → `layer/move` `design/arrange/resize` → `layer/resize` `design/arrange/rotate` → `layer/rotate` `design/arrange/flip` → `layer/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.

## **Kind**[#](#kind)

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.

**Note**

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**[#](#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**[#](#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[#](#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**[#](#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`

## Translations[#](#translations)

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

*   Removed the following keys:
    *   `scope.content.replace`
    *   `scope.design.arrange`
    *   `scope.design.style`
*   Renamed the following keys:
    *   `scope.design.arrange.flip` is now `scope.layer.flip`
    *   `scope.design.arrange.move` is now `scope.layer.move`
    *   `scope.design.arrange.resize` is now `scope.layer.resize`
    *   `scope.design.arrange.rotate` 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**[#](#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()`

**Note**

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**[#](#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 migrationconst image = cesdk.engine.block.create('image');cesdk.engine.block.setString(  image,  'image/imageFileURI',  'https://domain.com/link-to-image.jpg',);
// Creating an Image after migrationconst block = cesdk.engine.block.create('graphic');const rectShape = cesdk.engine.block.createShape('rect');const imageFill = cesdk.engine.block.createFill('image');cesdk.engine.block.setString(  imageFill,  'fill/image/imageFileURI',  'https://domain.com/link-to-image.jpg',);cesdk.engine.block.setShape(block, rectShape);cesdk.engine.block.setFill(block, imageFill);cesdk.engine.block.setKind(block, 'image');
// Creating a star shape before migrationconst star = cesdk.engine.block.create('shapes/star');cesdk.engine.block.setInt(star, 'shapes/star/points', 8);
// Creating a star shape after migrationconst 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 migrationconst sticker = cesdk.engine.block.create('sticker');cesdk.engine.setString(  sticker,  'sticker/imageFileURI',  'https://domain.com/link-to-sticker.png',);
// Creating a sticker after migrationconst block = cesdk.engine.block.create('graphic');const rectShape = cesdk.engine.block.createShape('rect');const imageFill = cesdk.engine.block.createFill('image');cesdk.engine.block.setString(  imageFill,  'fill/image/imageFileURI',  'https://domain.com/link-to-sticker.png',);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 migrationconst images = cesdk.engine.block.findByType('image');
// Query all images in the scene after migrationconst 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 migrationconst stickers = cesdk.engine.block.findByType('sticker');
// Query all stickers in the scene after migrationconst stickers = cesdk.engine.block.findByKind('sticker');
// Query all Polygon shapes in the scene before migrationconst polygons = cesdk.engine.block.findByType('shapes/polygon');
// Query all Polygon shapes in the scene after migrationconst 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 */
```

---



[Source](https:/img.ly/docs/cesdk/vue/to-v1-13-d1ac5d)