Brand kits
Give the editor your brand's logo, colors, text styles, and writing rules.
A brand kit is the data of one brand: its name, logo, colors, text styles, and the way it writes. You pass one kit or many in templateMetadata. The editor then offers the brand's colors and text styles in the places where the user picks them, and it adds the brand to AI requests.
This page is about the brand of the design. Theme Studio has a different setting that is also called "Brand color". It sets the colors of the editor's own buttons and panels. See Theming. The two do not affect each other.
Setup
Pass the kits in templateMetadata.brands. Pass activeBrandId to choose the kit that is active when the editor opens:
import { VideoEditor, type BrandKit } from '@layermetry/media-editor/react';
const brands: BrandKit[] = [
{
id: 'northwind',
name: 'Northwind Studio',
logoUrl: 'https://cdn.example.com/northwind-logo.png',
description: 'Boat charters and harbour tours.',
colors: {
primary: '#1F4E79',
secondary: '#F2B134',
palette: { 'Harbour blue': '#1F4E79', 'Buoy yellow': '#F2B134' },
},
textStyles: {
headline: {
textStyleName: 'Headline',
fontFamily: 'Georgia',
fontSize: 96,
fontWeight: 700,
lineHeight: 1.1,
fontStyle: 'normal',
textDecoration: 'none',
},
},
voice: 'warm, plain and precise',
locale: 'en-GB',
},
{ id: 'harbourbrew', name: 'Harbour Brew', colors: { primary: '#6B3E26' } },
];
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<VideoEditor
licenseKey="YOUR_LICENSE_KEY"
onClose={() => console.log('The editor was closed')}
templateMetadata={{ metadata: {}, brands, activeBrandId: 'northwind' }}
onBrandChange={(brandId) => console.log(`Brand: ${brandId}`)}
/>
</div>
);
}Expected result: the tool rail has a Brand entry right after Text, with the name "Northwind Studio" under it. Because two kits are listed, the panel has a menu that switches the kit.
Default: no brand, no Brand entry, and every color picker looks as it did before.
The one-brand form
The form that earlier versions used keeps working. The editor reads colors, textStyles, logoUrl, and description at the top of templateMetadata, the id from metadata.brandId, and the name from metadata.brandName. It treats them as a list of one kit.
templateMetadata={{
metadata: { brandId: 'northwind', brandName: 'Northwind Studio' },
colors: { primary: '#1F4E79', secondary: '#F2B134' },
textStyles: { headline: { textStyleName: 'Headline', fontFamily: 'Georgia', fontSize: 96 } },
logoUrl: 'https://cdn.example.com/northwind-logo.png',
}}A list in brands with at least one entry wins. The one-brand fields next to it are then ignored. Without metadata.brandId, the kit has an empty id. An empty id is never saved with a design, and onBrandChange is not called for it.
Brand kit fields
id and name are the only required fields. Every other field is optional.
| Field | Type | Description |
|---|---|---|
id | string | Your stable id for the brand. activeBrandId, onBrandChange, and a saved design's brandKitId use it. |
name | string | The name that people see. A long name is cut with "…" and shown in full in a tooltip. |
logoUrl | string | An address that the editor can load the logo from. The logo server must allow cross-origin reads. |
description | string | One or two sentences that the Brand panel shows. |
colors | { primary?, secondary?, palette? } | primary and secondary are hex colors. palette is a map from a color name to a hex color. |
textStyles | Record<string, TextStyle> | Named text styles. The fields are the same as in Brand text styles. |
voice | string | How the brand sounds, such as "warm, plain and precise". |
voiceTraits | { name, description?, example? }[] | Detail behind voice. |
tone | { formal?, playful?, bold?, calm? } | Four sliders. Each is a whole number from 1 (not at all) to 5 (very). |
toneByChannel | { channel, tone }[] | The tone for each channel, such as Instagram. |
audience | string | Who the brand speaks to. |
locale | string | A language tag such as 'en-GB'. It sets the spelling of generated text. |
accent | string | The accent for voice-overs, such as "British English". |
pillars | string[] | The themes that the brand talks about. |
guidelines | object | summary, dos, donts, photography, graphics, motion, color, logo, and typography. Each is text, except dos and donts, which are lists of short rules. |
A panel shows only the logo, the colors, the text styles, and the description. The writing fields are never shown. They go to the AI assistant and to the Generate boxes, so that people do not type them again.
Each color must be a hex color: #rgb, #rgba, #rrggbb, or #rrggbbaa. Any other value, such as navy or rgb(31, 78, 121), is left out. The editor uses the same hex value for a click and for an assistant action, and every color action accepts only hex.
Which kits are kept
The editor keeps a kit that has an id and at least one thing it can use. That is a logo, a main color, a text style, or any writing field. A kit that has only a name is left out, and the console shows a warning that starts with [Brand]. A kit without an id, or with an id that is already listed, is left out with a warning too.
A kit that has only writing fields is kept, and it reaches the assistant and the Generate boxes. It has no Brand entry, because its panel would be empty.
Names on screen
With a name, the editor shows the name, such as "Brand: Northwind Studio". A kit without a name shows its id when two or more kits are listed, so that people can tell them apart. A single kit without a name shows only "Brand", and no id.
Choosing the active kit
When the editor opens, it picks the active kit in this order:
- The
brandKitIdsaved in the design, if you still list that kit. - Your
activeBrandId, if you list that kit. - The first kit in the list.
If you pass a different activeBrandId later, the editor switches to that kit, if it is listed. A new templateMetadata object with the same ids changes nothing, so a React page that writes templateMetadata={{ ... }} inline does not undo a switch that the user made.
When the user opens a saved design from the Templates panel, the design's kit becomes active, if it is listed.
Force one brand
To make the editor use one brand and offer no choice, pass only that brand. The menu appears from two kits, so a list of one kit has no menu.
templateMetadata={{ metadata: {}, brands: brands.filter((kit) => kit.id === currentCustomerBrandId) }}A saved design from another brand then does not change the kit, because the editor does not list that kit.
Brand change events
onBrandChange(brandId) is called when the editor opens with a kit, and again on every switch. The argument is the id of the active kit. The custom element sends a brandchange event too, and its detail is the id.
const editor = document.querySelector('media-editor-video');
editor.addEventListener('brandchange', (event) => {
console.log(`brandchange: ${event.detail}`);
});A switch does not change the design. It is not an undo step, and it does not mark the design as unsaved. If your function throws an error, the console shows it and the editor continues.
Saved designs
A saved design remembers its kit as template.brandKitId. Both ways of saving write it, the Save button and the draft that the AI assistant makes. The editor gives it back when the design opens. It is never written into your metadata.
The editor leaves brandKitId out when the active kit has an empty id. It ignores a saved id that you no longer list.
Brand panel
The Brand panel is in the tool rail right after Text. On a phone, the dock tile says "Brand", and the first line of the sheet names the brand. With two or more kits, the panel heading has a menu that switches the kit.
The panel shows these parts, in this order. It leaves out a part that the kit does not have.
| Part | What it does |
|---|---|
| The brand line | Shows "Brand: " and the name. It is read-only. |
| Colors | A click sets the color of every selected text and shape. |
| Text styles | A click styles the selected text. With nothing selected, it adds new text in that style. |
| Logo | Shows the logo. Add to design adds it to the video as a picture. |
| Description | The description of the brand, cut to two lines. |
A color click goes to every selected text and shape, in one step for the texts and one step for the shapes. When text and a shape are selected together, Undo takes two steps in this version. A picture, a clip, a caption, or the background is not changed, and a message next to the colors says so.
A text style click uses the same action as the AI assistant, textApplyStyle. It sets the font, size, weight, italic, underline, and line height that the style names. It sets each value and never switches one. A bold text box stays bold when it gets a bold style. New text in a style is one undo step.
The panel waits until the brand font has loaded before it styles the text, so the text box has the right size. Your page must load the font, as for Brand text styles.
Brand styles in the Text panel
The Text panel has a Brand styles card with the same text styles and, with two or more kits, the same menu. The card is not shown when the active kit has no text styles.
Brand colors in color pickers
Every color picker has a Brand colors row with the name of the brand and one dot for each color of the kit. The row is not shown when the kit has no colors. The kit menu is not in the pickers. It is only in the panel heading, the first line of the phone sheet, and the Brand styles card.
Hide or rename the panel
ui.panels.brand hides the Brand entry in the rail and the dock, or changes its name:
<VideoEditor
licenseKey="YOUR_LICENSE_KEY"
onClose={() => console.log('The editor was closed')}
templateMetadata={{ metadata: {}, brands }}
ui={{ panels: { brand: { label: 'Company brand' } } }}
/>| Key | Type | Default | Description |
|---|---|---|---|
visible | boolean | true | false hides the Brand entry, the panel, and the Brand styles card. |
label | string | Brand | The name in the rail, the dock, the panel heading, and the tooltip. |
ui.toolRail.hidden and ui.dock.hidden with the id brand hide the entry as well. See UI customization.
Generate with brand
When the editor has an active kit, each Generate box shows a Use brand switch. The switch adds a few brand words after the person's own words. Under the switch is one chip for each part of the brand that the request uses, such as Colors, Look, Voice, Tone, or Dos and don'ts. A chip that is turned off is missing from the prompt and from the data that goes to your server.
Above the Generate button, one line shows what will be added, for example "Added to your request: voice, tone, dos and don'ts, spelling (185 characters)". It opens to the exact words.
The row appears only when all four of these are true:
- The editor has an active kit.
- The editor has an AI service.
- You did not set
ai.brandtofalse. - The kit has something for this kind of request. If it has nothing, the row is hidden and the box is as it was before.
The switch and the chips are remembered for each kind and each kit while the editor is open. They are not saved in the design.
What each kind gets
"Words" is the text added to the prompt. "Data" is what input.brand carries.
| Kind | Words added | Data in input.brand |
|---|---|---|
image | The colors, and the look from guidelines.photography. | colors, visualStyle |
sticker | The colors, and the look from guidelines.graphics. | colors, visualStyle |
svgPath | The colors. | colors |
video | The colors, the look, and the camera motion. | colors, visualStyle, motion |
imageToVideo | The motion, only when the person typed something. | motion |
imageEdit | The colors and the look. The switch starts off. | colors, visualStyle |
text | The voice with the brand name, the tone in words, the audience, up to 3 dos and 3 don'ts, and the spelling from locale. | voice, tone, audience, dos, donts, locale |
textRewrite | The same as text. The words go into instruction, never into text. | The same as text |
voice | Nothing. The words are spoken exactly as typed. | accent, locale |
music | Mood words from the tone traits at level 3 or higher. | tone |
soundEffect | No row. | Nothing |
Rules that always hold
- The brand words come after the person's own words, after one blank line. For a sticker, the words come after the filled sticker template, so they never land inside the subject.
- A picture prompt never carries the brand name or the dos and don'ts.
- Voice-over words are never changed.
- A color is written as a name and a code, such as "Harbour blue (#1F4E79)". The name comes from
colors.palette. Without a name, only the code is written. - Every kit field is cleaned before use. Each line break and control character becomes a space, so a field cannot start a new paragraph in the prompt. A field is cut to 160 characters (the look and the motion) or 80 characters (voice, audience, accent, a color name, and one rule).
- The whole addition has at most 300 characters for pictures, clips, and music, and at most 600 characters for text. A part that does not fit is left out, and so is every part after it. It is left out of the words and of the data, and the line above Generate names it.
Settings: ai.brand
ai.brand changes how the feature works. Its value is false or an object:
<VideoEditor
licenseKey="YOUR_LICENSE_KEY"
onClose={() => console.log('The editor was closed')}
templateMetadata={{ metadata: {}, brands }}
ai={{
endpointUrl: '/api/ai',
brand: { addToPrompt: false, operations: { imageEdit: true, music: false } },
}}
/>| Setting | Default | Description |
|---|---|---|
ai.brand = false | Brand is on | Removes the switch from every box. Nothing is added to any prompt, and input.brand is never sent. |
ai.brand.addToPrompt | true | false keeps the switch and sends input.brand, but adds no words to the prompt. The line above Generate then says "Your words are sent as typed. The brand facts go with the request for the server to use." |
ai.brand.operations | On for every kind except imageEdit | Sets, for each kind, whether the switch starts on. The person can still change it in the box. |
The editor refuses these values and names the setting in the error: operations.soundEffect or operations.captions, because those never use a brand; an unknown key, such as ai.brand.addToPrompts; true; and any other value that is not true or false.
Your own server: input.brand
With a brand, the request to your server carries input.brand. A server that words its own prompts can read it and can remove the added words with an exact match on addedToPrompt:
{
"type": "text",
"prompt": "A headline\n\nWrite in a warm, plain and precise voice.",
"input": {
"operation": "text",
"prompt": "A headline\n\nWrite in a warm, plain and precise voice.",
"brand": {
"kitId": "northwind",
"name": "Northwind Studio",
"addedToPrompt": "\n\nWrite in a warm, plain and precise voice.",
"used": ["voice"],
"voice": "warm, plain and precise"
}
}
}The example is shortened, and the real words of addedToPrompt are longer. The fields of input.brand are:
| Field | Type | Description |
|---|---|---|
kitId, name | string | The id and the name of the kit. |
addedToPrompt | string | The exact words added, with the blank line before them. It is '' when nothing was added. |
used | string[] | The parts used: colors, visualStyle, motion, voice, tone, audience, rules, spelling, accent, mood. |
colors | { role, hex, name? }[] | The colors used. |
voice, audience, locale, accent, visualStyle, motion | string | The parts used. |
tone | { formal?, playful?, bold?, calm? } | The tone sliders. |
dos, donts | string[] | The rules used. |
input.brand is missing when no brand is active, when ai.brand is false, and for sound effects. A part that the person turned off is missing from input.brand too.
The name brand is reserved. A model field cannot use it, and a brand key that arrives with the model settings is removed before the editor adds its own. See Custom AI endpoint.
AI assistant
The assistant receives the active kit. At the start of every chat turn, when you passed brands, the editor sends one flat kit: the metadata strings you passed, the colors, the text styles, and the writing fields of the active kit. It does not send the other kits, activeBrandId, or a logo given as a data: address. It sends nothing when no kit is usable.
The one-brand form is sent as it was before. The built-in chat panel and runChatTurn both behave this way. The assistant uses the same actions as a click in the Brand panel, including textApplyStyle. See AI assistant.
Configuration
| Name | Type | Default | Description |
|---|---|---|---|
templateMetadata.brands | BrandKit[] | none | The brand kits. |
templateMetadata.activeBrandId | string | first kit | The kit that is active when the editor opens, unless the design saved its own. |
onBrandChange | (brandId: string) => void | none | Called when the editor opens and on every switch. |
ui.panels.brand | { visible?, label? } | visible, Brand | Hides or renames the Brand entry. |
ai.brand | false or { addToPrompt?, operations? } | on | Controls Use brand in the Generate boxes. |