Video

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.

FieldTypeDescription
idstringYour stable id for the brand. activeBrandId, onBrandChange, and a saved design's brandKitId use it.
namestringThe name that people see. A long name is cut with "…" and shown in full in a tooltip.
logoUrlstringAn address that the editor can load the logo from. The logo server must allow cross-origin reads.
descriptionstringOne 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.
textStylesRecord<string, TextStyle>Named text styles. The fields are the same as in Brand text styles.
voicestringHow 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.
audiencestringWho the brand speaks to.
localestringA language tag such as 'en-GB'. It sets the spelling of generated text.
accentstringThe accent for voice-overs, such as "British English".
pillarsstring[]The themes that the brand talks about.
guidelinesobjectsummary, 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:

  1. The brandKitId saved in the design, if you still list that kit.
  2. Your activeBrandId, if you list that kit.
  3. 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.

PartWhat it does
The brand lineShows "Brand: " and the name. It is read-only.
ColorsA click sets the color of every selected text and shape.
Text stylesA click styles the selected text. With nothing selected, it adds new text in that style.
LogoShows the logo. Add to design adds it to the video as a picture.
DescriptionThe 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' } } }}
/>
KeyTypeDefaultDescription
visiblebooleantruefalse hides the Brand entry, the panel, and the Brand styles card.
labelstringBrandThe 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.brand to false.
  • 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.

KindWords addedData in input.brand
imageThe colors, and the look from guidelines.photography.colors, visualStyle
stickerThe colors, and the look from guidelines.graphics.colors, visualStyle
svgPathThe colors.colors
videoThe colors, the look, and the camera motion.colors, visualStyle, motion
imageToVideoThe motion, only when the person typed something.motion
imageEditThe colors and the look. The switch starts off.colors, visualStyle
textThe 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
textRewriteThe same as text. The words go into instruction, never into text.The same as text
voiceNothing. The words are spoken exactly as typed.accent, locale
musicMood words from the tone traits at level 3 or higher.tone
soundEffectNo 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 } },
  }}
/>
SettingDefaultDescription
ai.brand = falseBrand is onRemoves the switch from every box. Nothing is added to any prompt, and input.brand is never sent.
ai.brand.addToPrompttruefalse 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.operationsOn for every kind except imageEditSets, 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:

FieldTypeDescription
kitId, namestringThe id and the name of the kit.
addedToPromptstringThe exact words added, with the blank line before them. It is '' when nothing was added.
usedstring[]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, motionstringThe parts used.
tone{ formal?, playful?, bold?, calm? }The tone sliders.
dos, dontsstring[]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

NameTypeDefaultDescription
templateMetadata.brandsBrandKit[]noneThe brand kits.
templateMetadata.activeBrandIdstringfirst kitThe kit that is active when the editor opens, unless the design saved its own.
onBrandChange(brandId: string) => voidnoneCalled when the editor opens and on every switch.
ui.panels.brand{ visible?, label? }visible, BrandHides or renames the Brand entry.
ai.brandfalse or { addToPrompt?, operations? }onControls Use brand in the Generate boxes.

Troubleshooting

Additional resources

On this page