Skip to main content

Embedding the Customizer

The Customizer is a web app you embed in an iframe. It loads a recipe and lets a shopper edit the graphics on that garment. The garment comes from the recipe: brand, number, size, and color. The recipe has the same shape as a product-image-generator request. Save & Exit shows a signed recipe URL inside the frame and does not notify the parent. The frame listens for parent messages only when parent_origin is set, and then replies only with the result of adding a logo. For a view-only recipe embed, use Embedding the Viewer.

<iframe
src="https://customizer.seddi.app/?api_key=API_KEY&recipe_url=https%3A%2F%2Fstorage.googleapis.com%2Fbucket%2Frecipe.json&logos=true"
title="Seddi Customizer"
style="width: 100%; height: 100%; border: 0;"
allow="clipboard-write"
></iframe>

Give the iframe a real height. The app fills its frame.

api_key is a query parameter, so it is visible in the iframe URL and to anyone who can see that URL.

Recipe URL​

recipe_url is the URL-encoded https address of the recipe JSON. Do not combine it with brand, style_number, colorway, or mockup_id.

The URL must be https on port 443, with no username or password, and a public host. localhost and private addresses are rejected. Seddi downloads the file itself and does not send the caller's API key or other credentials to that host.

logos[].transform.rotation is clockwise degrees and is kept on save. The editor does not show a rotation control.

A load calls POST /customizer-scene-generator/v1. The API key must allow that path. Adding or replacing a graphic also calls POST /logos-for-generators/v1, so the key must allow that path too.

Query parameters​

ParameterValuesDefaultEffect
api_keystring—Required. Sent as x-api-key on every API request from the frame.
recipe_urlURL-encoded https URL—Required. Public https URL of the recipe on port 443, with no userinfo.
logostruehiddenShows the graphics panel. Any other value leaves the viewer alone.
unitsimperial, metricimperialSize labels in the graphics panel. Recipe geometry stays in meters.
idlestatic, rotatestaticrotate turns the garment when the viewer is idle.
controls_layouttl, tr, bl, brtlCorner for the viewer controls: top-left, top-right, bottom-left, or bottom-right.
controls_styleURI-encoded JSONunsetColors for the viewer controls. Invalid JSON is ignored.
parent_originoriginunsetOpt in to parent messages. Scheme, host, and port only, such as https://shop.example. Without it the frame does not listen.

controls_style accepts #rgb or #rrggbb for these keys:

KeyAliasWhat it colors
ttextColorControl text
bgbackgroundColorControl background
bdborderColorControl border
controls_style=%7B%22bg%22%3A%22%23111827%22%2C%22t%22%3A%22%23ffffff%22%2C%22bd%22%3A%22%23334155%22%7D

That value is {"bg":"#111827","t":"#ffffff","bd":"#334155"}.

Parent messages​

Set parent_origin to the origin of the page that owns the iframe. The frame registers a message listener only when that value is an origin. A message is applied when event.origin equals parent_origin and the sender is the parent window.

seddi.customizer.setOptions changes viewer chrome without reloading. Omit a field to leave it as it is. Invalid values are ignored. controls_style: null clears a previous style.

iframe.contentWindow.postMessage(
{
type: 'seddi.customizer.setOptions',
units: 'metric',
controls_layout: 'br',
controls_style: { bg: '#111827', t: '#ffffff', bd: '#334155' },
},
'https://customizer.seddi.app',
);

units is imperial or metric. controls_layout is tl, tr, bl, or br. controls_style uses the same color keys as the query parameter.

seddi.customizer.addLogo adds a graphic from a public https URL. The frame processes it with POST /logos-for-generators/v1, places it on the best open region, and selects it. The logo is drawn even when the graphics panel is hidden. Optional requestId is echoed on the reply.

iframe.contentWindow.postMessage(
{
type: 'seddi.customizer.addLogo',
sourceUrl: 'https://cdn.example/art.png',
requestId: 'logo-1',
},
'https://customizer.seddi.app',
);

The frame posts the result to the parent, with parent_origin as the target:

{ type: 'seddi.customizer.addLogoResult', requestId: 'logo-1', ok: true, logoId: '...' }
{ type: 'seddi.customizer.addLogoResult', requestId: 'logo-1', ok: false, error: '...' }

The add fails when the URL is not https, api_key is missing, the style is still loading, no logo region is available, or logo processing fails. In recipe mode, Save & Exit includes the added logo through its sourceUrl.

Enter an API key and an https recipe URL to load the frame. parent_origin is this page's origin. Metric, Imperial, and the corner buttons post seddi.customizer.setOptions and stay marked after a click. Add logo posts seddi.customizer.addLogo and waits for the frame reply, which appears under the buttons.

Graphics, colorways, and save​

logos=true opens the graphics panel. Without it, the frame is a viewer only. The shopper can move, resize, align, rotate, reset, set technique, and recolor a graphic, and can add, replace, or remove one.

The panel has a colorways tab. Switching colorways calls POST /customizer-colorway-switch/v1. The key must allow that path. The colorway-switch session lasts 30 minutes by default. A deployment can change that. After it expires, switching colorways fails.

Save & Exit posts the edited recipe to POST /customizer-recipes/v1 and then shows the signed recipeUrl and its expiry in the frame. That URL lasts 30 minutes by default, and a deployment can change that. The frame shows the expiry it received. The shopper copies that URL. Save & Exit does not notify the parent. After a successful save the graphics panel closes for that session.

The key must allow /customizer-recipes/v1 for Save & Exit. Add and Replace ask for an https:// image URL, send it to POST /logos-for-generators/v1, and write that URL into the saved recipe.