VideoConfiguration

UI customization

Show or hide panels, toolbar buttons, and AI features.

The ui prop hides, reorders, and renames parts of the editor. Every field is optional. Without ui, the editor shows everything in its default order.

Selection and toolbar

On a desktop, one bar above the canvas shows the controls of the selected item. It appears for every type of item: video clip, sound clip, picture, sticker, GIF, shape, text, label, caption track, and several items selected together. The floating pill next to an item on the canvas stays as it was.

The bar works like this:

  • Values on the buttons. A button shows the current value, for example speed 1×, volume 80%, opacity, font size, fade lengths and line width. The Animate button shows what is set, for example In: Fade · Loop: Pulse.
  • More. When the bar is too narrow, the controls at the end of the list move into a short More menu. The editor measures the real width of each button. Copy style and Paste style are always in More.
  • Value controls open in the side panel. Colour, volume, fades, effects and the other value controls open in a panel on the left side, not in a menu that hangs from the bar. The phone uses the same control. One panel is open at a time. It closes when the selection changes, when you press Escape, with its close button, or when a tool from the rail opens in its place. Small controls stay in the bar: the font size field with − and +, the three alignment buttons and the speed list.
  • Your own buttons. customActions appear after the editor's controls. See Custom actions.

With nothing selected, the bar becomes a page bar. It shows the canvas size (it opens the Resize panel), Background (it opens the Background panel), the length of the video, the emoji button, the Save template button when the editor can save templates, and a More menu. More has the same lines as a right-click on the empty canvas, and Background settings…. A viewer sees no page bar.

Set ui.toolbar.hidden to ['controls'] to hide the page-bar extras: Insert Emoji and Save template in the video editor, or Save template and Default locks… in the image editor. The page controls and More remain available. This hides the buttons; it does not revoke editing permissions.

Default lists and ui.selection

The order of the controls for each type of item is a plain list in the editor. It is only the starting view. ui.selection is applied after it and always wins. ui.selection takes the same four fields as the tool rail: order, hidden, labels and display. It now drives the desktop bar as well as the phone's selection bar and the floating pill.

import type { UiConfig } from '@layermetry/media-editor';

const ui: UiConfig = {
  selection: {
    order: ['trim', 'mute', 'replace'], // these come first
    hidden: ['delete'],                 // no Delete button
    labels: { replace: 'Swap file' },   // a new name
    display: { effects: 'icon' },       // a picture only
  },
};
  • order puts the listed ids first, in your order. This is true even for a control that would wait behind More. The other controls keep their default order after yours.
  • hidden removes the button. The action, its keyboard shortcut and its editing action keep working.
  • labels renames a control. The new name is also the tooltip and the accessible name.
  • display is 'icon', 'label' or 'both' for each id. By default the desktop bar draws Bold, Italic, Underline, Bring forward, Send backward, Delete and Mute as a picture only. Set display to 'label' or 'both' to bring the words back.

The new ids are trim and mute (video and sound clips), replace, copyStyle and pasteStyle. group and ungroup also work for several selected items. The lists for every type of item are in Default lists.

An id that the editor does not know is ignored, and the console prints one warning with the valid ids.

The old ui.toolbar setting

ui.toolbar is still accepted, so a host that uses it keeps working. The bar has no groups any more, so each group id is translated into the controls that the group held, for the item types that showed the group. hidden and order are applied to those controls. Both ui.toolbar and ui.selection are applied. The hidden lists are added together. An id in ui.selection.order comes before the ids that come from ui.toolbar.

A labels setting for a group, or a display of 'label' or 'both', has nothing to change, because there is no heading left. A display of 'icon' already meant "no heading", and it still holds. Your own buttons are the actions group. They always come after the editor's controls, with no heading, so the order, labels and display of actions are not applied. Hiding actions still works.

The editor prints one console warning that starts with [MediaEditor] ui.toolbar:. It names the group ids that were translated and the settings that have no effect, and it tells you to use ui.selection instead.

The text group held font, textAlign, rewriteWithAi and effects. This example shows the old setting and the same choice written for ui.selection:

const ui: UiConfig = {
  // Old: hides the Text group. Works, with one console warning.
  toolbar: { hidden: ['text'] },
};

const sameWithSelection: UiConfig = {
  // New: names the controls. Note that an id applies to every type of item that has it.
  selection: { hidden: ['font', 'textAlign', 'rewriteWithAi', 'effects'] },
};

The right-click menu keeps its words, and the phone's selection bar follows ui.selection as before. See Control customization for all ids and the default lists.

Panels

ui.toolRail changes the tool rail on the left. order moves the tools you list to the top, hidden removes tools, and labels renames them:

import { VideoEditor, type UiConfig } from '@layermetry/media-editor/react';

const ui: UiConfig = {
  toolRail: {
    order: ['text', 'media'],
    hidden: ['stickers', 'templates'],
    labels: { subtitle: 'Subtitles' },
  },
};

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <VideoEditor licenseKey="YOUR_LICENSE_KEY" onClose={() => console.log('The editor was closed')} ui={ui} />
    </div>
  );
}

Tools you do not list in order keep their default order, after the ones you list. The ids of the tool rail are:

IdTool
mediaMedia: upload and stock video, pictures, and audio
subtitleCaptions
textText
brandBrand. Shown only when a brand kit has a logo, a main color, or a text style.
shapesShapes
stickersStickers
effectsEffects. Off the rail by default.
backgroundBackground. Off the rail by default.
templatesTemplates
audioEffectsAudio Effects. Off the rail by default. When you list it, it shows only while a clip with sound is selected.
animationsAnimations. Off the rail by default. When you list it, it shows only while an item is selected.

The AI Assistant button stays at the bottom of the rail. To remove it, see AI features.

With createAutomatedContent, the rail and the compact dock also have Generate, with the id automated. Hide it with ui.features.automatedContent: false.

ui.dock does the same for the dock of the compact layout. Its ids are media, text, brand, elements, templates, captions, effects, background, aiChat, and resize.

An unknown id prints a warning in the console and is skipped. The editor keeps working.

To hide the timeline, for example in an editor that only fills in a template, set ui.chrome.timeline to false:

import { VideoEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <VideoEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        ui={{ chrome: { timeline: false } }}
      />
    </div>
  );
}

Default: every tool in the order of the table, except the four that are off the rail.

Tools that are off the rail by default

Effects, Animations, Audio effects and Background are not on the left rail by default. They do nothing useful when nothing is selected. You reach them from the bar above the canvas: Effects, Animations and Audio effects from the bar of the selected item, and Background from the page bar. Their panels are the same as before.

To put a tool back on the rail, list its id in ui.toolRail.order. The tool then shows in the place where you listed it. A host that already lists every tool sees no change.

<VideoEditor
  licenseKey="YOUR_LICENSE_KEY"
  onClose={() => console.log('The editor was closed')}
  ui={{ toolRail: { order: ['text', 'media', 'effects', 'background'] } }}
/>

The compact dock on a phone is not changed by this.

Brand panel

ui.panels.brand hides the Brand entry, or gives it another name. It takes visible (default true) and label (default Brand):

ui={{ panels: { brand: { label: 'Company brand' } } }}

visible: false removes the entry from the rail and the dock. label changes the name in the rail, the dock, the panel heading, and the tooltip. The entry is shown only when a brand kit has a logo, a main color, or a text style. See Brand kits.

Toolbar buttons

The palette button. showThemeCreator={true} shows a button in the app bar that opens the Customization Studio, a tool for developers. Use it in your development build only. Default: hidden. Only the value true shows it.

The light and dark switch. enableThemeToggle={true} adds it to the app bar. Default: hidden. See Theming.

The right-click menu. ui.generative.contextMenu hides, reorders, or renames its entries by id. false gives the browser's own menu back.

import { VideoEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <VideoEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        showThemeCreator={false}
        ui={{ generative: { contextMenu: { hidden: ['delete'] } } }}
      />
    </div>
  );
}
IdEntry
bringForward, sendBackward, bringToFront, sendToBackChange the layer order
duplicate, copy, paste, delete, selectAllEdit the selection
copyStyle, pasteStyleCopy the look of one item, and give it to others. See Copy style and paste style.
editTextEdit the text of a text item
crop, replaceCrop the item, or replace its picture or video
splitSplit a clip at the playhead
generateCaptionsCreate captions from the speech in a clip
removeBackground, stabilizeMedia server actions. See Video.

The item menu in the compact layout. A selected item shows a small menu of its most important actions. itemActions changes it for each kind of item: replace sets the whole list, add appends actions, and remove drops them. false removes the menu.

import { VideoEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ width: 390, height: 844 }}>
      <VideoEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        // The small menu next to a selected text item: only these two actions.
        itemActions={{ text: { replace: ['textColor', 'fontSize'] } }}
      />
    </div>
  );
}

The kinds of item are video, image, gif, sticker, text, shape, label, and subtitle. The menu always keeps the full set of actions in the bar at the bottom of the screen.

KindDefault actions
video, imagebringForward, sendBackward, crop, opacity
gif, stickerbringForward, sendBackward, opacity
textbringForward, sendBackward, textColor, fontSize, textAlign
shapebringForward, sendBackward, fill, stroke
labelbringForward, sendBackward, editText, textColor
subtitlebringForward, sendBackward, subtitleStyle

The menu shows four actions. More actions go behind a ⋯ button.

Color controls

Color controls show the current color, your brand colors and 16 default colors. Use the same control for text and label colors, shape fill and stroke, text outline and shadow, caption colors. Open Custom color for the color square, hue strip and HEX, R, G and B fields. The control stays inside the panel or phone sheet.

Palette rowColors
Primary#FFFFFF, #000000, #FF0000, #FFFF00, #00FF00, #00FFFF, #0000FF, #FF00FF
Drawing#A3A3A3, #FF6B6B, #FFC53D, #3DDC84, #26D0CE, #4D96FF, #B197FC, #F783AC

A steady 3 px line under a toolbar color icon shows its stored color. Mixed colors show a gray dashed line. Your icon, label and display settings still apply. Dragging an item color previews it live. Releasing it saves one change, so one Undo restores the previous color. Escape cancels an unfinished item preview. Selected words in an open text box receive colors through the text editor.

The video color controls save opaque hex colors.

Generate from the bar

With nothing selected, open More and choose Generate text… or Generate image here…. These open the Text panel or the Photo tab of Media, with its Generate form already open. With an item selected, Rewrite with AI, Edit with AI and Make video open the form in the left panel. For Rewrite with AI and Edit with AI, the selected suggestion previews on the existing item; closing the box keeps it. New-item operations add a separate item through their add action.

For an existing-item edit, closing with ✕ or Escape keeps the selected card. Selecting another item or opening another panel also ends the edit and keeps that choice as one Undo step. Choose Original first to keep the current item unchanged. A new result needs Add to canvas, Add to timeline or Set as background. Only one panel is open at a time.

When the required panel is unavailable or hidden by ui.panels, ui.toolRail or ui.dock, the form opens under the bar. Panel placement also respects ui.generative. The floating pill, Cmd+K and the panels’ own Generate buttons keep their existing behavior.

Copy style and paste style

Copy style takes the look of one item. Paste style gives that look to one or more other items. Both are in the More menu of the bar above the canvas, in the right-click menu, and on the keyboard. The ids are copyStyle and pasteStyle, so ui.selection and ui.generative.contextMenu can hide, move or rename them.

PlatformCopy stylePaste style
MacCmd + Option + CCmd + Option + V
Windows and LinuxCtrl + Alt + CCtrl + Alt + V

The editor matches the physical key, because Option + C types the character "ç" on a Mac. On Windows, AltGr is not treated as a shortcut, so it still types its character. If you hold the keys, the style is pasted once.

Copy style needs exactly one selected item that has a style. A sound clip or a caption track has none, and the editor says "This item has no style to copy". Paste style needs a copied style and at least one selected item. The copied style stays while the editor is open.

What is copied depends on the type of the item:

ItemWhat is copied
TextFont, size, weight, italic, underline, colour, alignment, letter spacing, line height, outline and shadow
ShapeFill, outline colour and outline width
Picture, video clip, GIF, stickerThe filters and adjustments of the Effects panel, and the mask
Every item that has transparencyThe transparency (not sound clips and not caption tracks)

Not copied yet: the coloured plate behind a text and its colour gradient, the corner rounding of a shape, and the outline of a picture.

A plain source clears italic, underline, shadow, filters and the mask instead of keeping the target’s old style. A paste is one Undo step, even when it changes several items. Parts that do not apply to the target are skipped. The editor shows one short message for the paste. If every selected item is locked, it says "The selected items are locked." If cropping alone is locked, it says "The mask was left as it was, because cropping is locked."

Full-screen player

The timeline has a Full screen button, and the F key does the same. Set ui.features['player.fullscreen'] to false to remove both. Default: on. See Full-screen player for what it shows.

<VideoEditor
  licenseKey="YOUR_LICENSE_KEY"
  onClose={() => console.log('The editor was closed')}
  ui={{ features: { 'player.fullscreen': false } }}
/>

The image editor has no player and ignores this switch.

Recording

The voiceover recorder and the camera recorder are on by default. Each switch in ui.features removes one control:

import { VideoEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <VideoEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        ui={{ features: { 'recording.camera': false, 'recording.takes': false } }}
      />
    </div>
  );
}
SettingWhat it does
ui.features['recording.microphone']: falseRemoves Record voiceover from Media > Audio, and Re-record part from a sound clip's bar on a phone.
ui.features['recording.camera']: falseRemoves Record with camera from Media > Video.
ui.features['recording.countdownChoice']: falseRemoves the Countdown choice. The recorder uses recording.countdownSeconds, or 3 seconds.
ui.features['recording.inputLevel']: falseRemoves Automatic level and the Level slider. The browser's automatic level is used.
ui.features['recording.cleanUp']: falseRemoves Clean up noise. The recorder uses recording.cleanUpNoise.
ui.features['recording.takes']: falseThe recorder keeps one take at a time. Record again replaces it.
ui.features['recording.script']: falseRemoves the Script section and the prompter.
ui.features['recording.captions']: falseRemoves Generate captions from the recorder.
ui.features['recording.punchIn']: falseRemoves Replace part of the selected clip from the recorder, and Re-record part from a sound clip's bar on a phone.

See Microphone recording for the recorder, and recording for its defaults.

The image editor accepts the same switches and ignores them.

Two switches change the box for AI music and sound effects:

SettingWhat it does
ui.features['aiSound.length']: falseRemoves the Length row. Music then asks for the length of the video, or 30 seconds on an empty timeline. A sound effect lets the model decide.
ui.features['aiSound.instrumental']: falseRemoves the Instrumental switch. Music is then always made without singing.

The image editor accepts these two switches too, and ignores them. It has no music.

AI features

AI controls appear only when you pass ai. Inside ai, a capability set to false is hidden everywhere. ui then decides where the remaining controls appear:

import { VideoEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <VideoEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        ai={{ endpointUrl: 'https://api.example.com/ai', video: false }}
        ui={{
          features: { 'ai.chat': false },
          generative: {
            actions: { image: { label: 'Create a picture', surfaces: ['panel'] } },
          },
        }}
      />
    </div>
  );
}
SettingWhat it does
ui.features['ai.chat']: falseRemoves the AI assistant.
ui.features['ai.generate']: falseRemoves every generate control. Same as ui.generative.enabled: false.
ui.generative.actions.<capability>.enabled: falseHides one capability.
ui.generative.actions.<capability>.surfacesThe places where the control may appear. [] leaves it in the assistant only.
ui.generative.actions.<capability>.labelRenames the control.
ui.generative.actions.<capability>.presetsReplaces the suggestion buttons. [] removes them.

The capabilities are text, textRewrite, image, imageEdit, svgPath, video, imageToVideo, captions, voice, music, and soundEffect. music and soundEffect appear in the panel and shortcut places only. The places are:

PlaceWhere the control appears
panelAt the top of a panel: Text, Media, Shapes, or Captions
selectionOn the selected item
contextMenuIn the right-click menu of an item
emptyCanvasIn the right-click menu of the empty canvas
shortcutUnder Cmd+K on a Mac, or Ctrl+K

ui can only take controls away. It never shows a control that your AI provider cannot serve.

Default: every AI control that your ai setting can serve, in its default places.

See AI providers for ai.

On this page