---
title: "Specifying personalization data | Customer&#x27;s Canvas Hub"
canonical: "https://customerscanvas.com/docs/hub/dev-center/scenarios/direct-mail/specifying-personalization-data/"
---

# Specifying personalization data

> Customer's Canvas takes the following data params to render personalized templates:

-   [`ItemsData`](#itemsdata): Sets the content and properties of design elements.
-   [`DataSet`](#dataset): Defines which surfaces from the productDefinitions should be rendered and how to apply `itemsData` to them.

## ItemsData

The `itemsData` object allows you to apply properties to all product pages at once and separately on a per-page basis. Also, the `itemsData` object personalizes _in-string_ and _interpolation_ placeholders through the `placeholders` property. This object complies with the following specification.

```js
itemsData: {
    surfaces: {
        [surfaceName: string]: {
            [itemName: string]: itemData;
        }
    },
    [itemName: string]: itemData,
    placeholders: {
        [placeholderName: string]: string;
    }
}
```

Here, `itemData` allows you to configure the following properties.

```js
itemData: {
  image?: string;        // The path to images.
  content?: ItemData;    // The content of placeholders.
  contentResizeMode?: string;    // The image insertion mode.
  contentTransform?: Transforms; // Applied transformations.
  ignoreExistingTransform?: boolean; // Whether to apply transforms to content.
  opacity?: number;      // The opacity of design elements.
  text?: string;         // The content of text elements.
  leading?: number;      // The text leading.
  tracking?: number;     // The text tracking.
  font?: {
    postScriptName?: string; // The postScript name.
    size?: number;           // The font size in points.
    fauxBold?: boolean;      // Whether the faux bold style is applied.
    fauxItalic?: boolean;    // Whether the faux italic style is applied.
    allCaps?: boolean;       // Whether the AllCaps style is applied
  };
  textAlignment?: TextAlignment; // "Left" | "Center" | "Right" | "Justify" | "LastLeft" | "LastRight" | "LastCenter".
  textVerticalAlignment?: TextVerticalAlignment; // "Bottom" | "Center" | "Top"
  isVertical?: boolean;  // Whether the text is vertical.
  underline?: boolean;   // Whether the text is underlined.
  visible?: boolean;     // Whether the element is rendered or not.
  location?: PointF;     // The starting point of the element.
  size?: ItemSize;       // The width and height.
  color?: string;        // The color in a CSS-compatible format.
  borderColor?: string;  // The border color of design elements.
  borderWidth?: number;  // The border width of design elements.
  fillColor?: string;    // The fill color for shapes.
  altColor?: string;     // The alternate color for dashed lines.
  dashWidth?: number;    // The dash width.
  altDashWidth?: number; // The width of alternate dash lines.
  width?: number;        // The width of lines.
  sourcePoint0?: PointF; // The start point of lines.
  sourcePoint1?: PointF; // The end point of lines.
  barcodeData?: IBarcodeData; // The data encoded into barcodes.
  shadow?: ShadowSettings;    // The shadow color.
  stroke?: StrokeSettings;    // The stroke color.
}
```

In `text`, you can pass plain text or an escaped XML string if you need to render tags. Instead, you can pass `formattedText`, which must comply with the format of the [Aurigma Graphics Mill](https://www.graphicsmill.com/docs/gm/advanced-formatted-text.htm) library. For example, `"<p style='first-line-indent:20pt;'>Lorem <span style='bold:true;color:red;'>ipsum</span></p>"`. Note that an invalid format will result in an exception.

When populating image placeholders, you can specify the _image insertion mode_ and transforms that should be applied to the placeholder's content. The `contentResizeMode` property can be either `"fit"`, `"fill"`, or `"original"`. You can apply the following transforms:

```js
Transforms: {
  angle?: number;      // The rotation angle in degrees.
  scaleX?: number;     // The X-coordinate scaling factor.
  scaleY?: number;     // The Y-coordinate scaling factor.
  translateX?: number; // The X-coordinate movement in points.
  translateY?: number; // The Y-coordinate movement in points.
}
```

When `ignoreExistingTransform` is `true`, which is the default value, then the placeholder's content is first resized according to the `contentResizeMode`. After that, transformations defined in the `contentTransform` are applied to the content. When you set `ignoreExistingTransform` to `false`, then the `contentResizeMode` won't be applied even if it is defined, and the content will stretch across the entire placeholder, taking into account its proportions.

To set up the size of design elements, use `ItemSize`. For text elements, this object defines the bounding rectangle.

```js
ItemSize: {
  width: number;
  height: number;
}
```

You can define text properties by using the `StrokeSettings` and `ShadowSettings`. Using `PointF`, you can define item coordinates.

```js
ShadowSettings: {
  angle?: number;
  color?: string;
  distance?: number;
  size?: number;
}
```

```js
StrokeSettings: {
  color?: string;
  lineJoin?: string;
  size?: number;
}
```

All properties of `itemsData` are optional. Through different variations, you can define any design element supported in the Design Editor. The following table details the design elements and their properties that you can pass to the `Preview` and `HiRes` controllers.

| Element Type | Properties |
| :--- | :--- |
| **Images** | location, size, image, opacity, borderWidth, borderColor, visible |
| **Image placeholders** | location, size, image, opacity, borderWidth, borderColor, content, contentResizeMode, contentTransform, ignoreExistingTransform, visible |
| **Barcode placeholders** | color, location, size, barcodeData, opacity, borderWidth, borderColor, visible |
| **Shapes, ellipses, rectangles** | location, size, fillColor, opacity, borderWidth, borderColor, visible |
| **Lines** | color, width, opacity, sourcePoint0, sourcePoint1, visible |
| **Plain text** | location, text, font, underline, color, isVertical, textAlignment, leading, tracking, stroke, shadow, visible |
| **Curved text** | location, size, text, font, underline, color, textAlignment, leading, tracking, stroke, shadow, visible |
| **Bounded text** | location, size, text, font, underline, color, isVertical, textAlignment, textVerticalAlignment, leading, tracking, stroke, shadow, visible |
| **Path-bounded text, auto-scaled text** | location, size, text, font, underline, color, isVertical, textAlignment, leading, tracking, stroke, shadow, visible |

All the numeric values are measured in points. If you do not pass any property that is appropriate to a design element, like `text` for bounded text, then the corresponding value from the design template remains unchanged.

## DataSet

The `dataSet` object allows you to create a new product from the initial `productDefinitions`. When you pass a `dataSet` in the request payload, the `Preview` and `HiRes` controllers only render surfaces listed in the `surfacesData` collection.

```js
dataSet: {
  surfacesData: SurfaceData[];
}
```

`SurfaceData` contains a list of required surfaces and data to personalize these surfaces.

```js
SurfaceData: {
    surfaceBinding: SurfaceBinding;
    data: ItemsData[];
    iterateOverSurfacesFirst?: boolean;
}
```

Here, `data` defines one or more [`ItemsData`](#itemsdata) sets for the personalization. In `surfaceBinding`, you can refer to the required surfaces by either indexes or names.

```js
SurfaceBinding: {
    surfaceNames: string[];
    surfaceIndexes: number[];
}
```

For example, to personalize the `Name` field on the `Front` page and render only this page, you can provide the following input data.

```js
const inputData = {
    "productDefinitions": [{
        "surfaces": { "designFolder": "presentation" }
    }],
    "dataSet": {
        "surfacesData": [{
            "surfaceBinding": {
                "surfaceNames": ["Front"]
            },
            "data": [{
                "Name": {
                    "text": "John Wood",
                    "color": "rgb(255, 0, 0)"
                }
            }]
        }]
    },
    ...
}
```

When you provide a number of data sets to render a number of surfaces, you can use the optional property `iterateOverSurfacesFirst` to specify the rendering order. If this property is `true`, then copies of the surfaces listed in the `surfaceBinding` are rendered in the following order:

1.  Render the first surface with the first data set.
2.  Render the first surface with the second data set.
3.  ... and so on for every data set.
4.  Render the second surface with the first data set.
5.  Render the second surface with the second data set.
6.  ... and so on for every surface and data set.

If `iterateOverSurfacesFirst` is `false` (this is the default value), then the personalization order goes over data sets:

1.  Render the first surface with the first data set.
2.  Render the second surface with the first data set.
3.  ... and so on for every surface.
4.  Render the first surface with the second data set.
5.  Render the second surface with the second data set.
6.  ... and so on for every surface and data set.
