Text
Add, style, and generate text.
Text items show words over the video for a set time. The user chooses the font, the size, the color, an outline, and a shadow, and can style single words.
Setup
Text with no stored font uses Arial, with a sans-serif fallback, in the preview and export.
Text boxes, fonts, styles, effects, and templates work with no setup. Brand text styles come from templateMetadata, and the AI features need an AI provider:
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')}
onExport={(file) => console.log(`Exported ${file.name}`)}
// Brand text styles, shown in Brand styles when a brand is active.
templateMetadata={{
metadata: {},
textStyles: {
headline: {
textStyleName: 'Brand headline',
fontFamily: 'Georgia',
fontSize: 96,
fontWeight: 700,
lineHeight: 1.1,
fontStyle: 'normal',
textDecoration: 'none',
},
},
}}
// AI text generation and AI rewrite: your AI proxy.
ai={{ endpointUrl: 'https://api.example.com/ai' }}
/>
</div>
);
}| Option | Prop | Configuration page |
|---|---|---|
| Brand text styles | templateMetadata.textStyles | Brand text styles |
| Host text templates | textTemplates | Text templates |
| The full Google Fonts list | googleFonts | Fonts |
| AI text generation, AI rewrite | ai | AI providers |
Text panel
The panel is arranged in this order: a selected-text strip; Generate with AI (or Rewrite with AI and + New when text is selected); Brand styles when a brand is active; Add text with Heading, Subheading and Body; Styles with four template previews and See all; and Generated. Sections can be folded. Styles and Generated have full-list routes, and the compact view uses a sheet. The toolbar’s Text styles control opens the panel at Brand styles.
Text boxes
In the Text panel, choose Heading (48 px), Subheading (28 px), or Body text (18 px) under Add text. The new item starts as “Add your heading”, “Add your subheading”, or “Add your text”. When a brand is active, the tiles use its Title, Subtitle and Body styles. The item starts at the playhead and lasts 5 seconds.
The letters of a new text item are 5% of the height of the canvas: 54 pixels on a canvas 1,080 pixels tall. The box is as wide as its words. When the style, the size, the typeface, the weight, or the words change, the box is measured again, so the words keep their lines. After the user drags the width of the box, the width stays where it was put. The saved design marks such a growing box with autoWidth: true.
Double-click the text, or press Edit under it, to change the words. Drag the item to move it, and drag its handles to resize or rotate it.
When a text item is selected, the toolbar above the canvas shows its controls: font, alignment, Rewrite with AI, text effects, bold, italic, underline, color, size, text styles, and animation.
Fonts
Press the font button in the toolbar to choose a font. The picker lists popular Google Fonts, such as Roboto, Open Sans, Lato, Montserrat, Poppins, Inter, Oswald, and Playfair Display. The editor loads the chosen font by itself.
The picker can also list the whole Google Fonts catalog, about 1,500 families, which the user can search. You choose where that list comes from with googleFonts. It takes exactly one of three ways, and none of them puts a Google key in the page:
| Setting | Where the list comes from |
|---|---|
googleFonts={{ hosted: true }} | The Layermetry server, which uses its own Google key. The request carries your licenseKey, and goes to mediaApiUrl when you set one. |
googleFonts={{ endpointUrl: '/api/fonts' }} | Your own server, which holds your Google key. The editor sends GET with no headers. The address can be relative. |
googleFonts={{ requestFn }} | Your own function. The editor makes no request. |
Without googleFonts, the picker uses its built-in families. If you provide both licenseKey and mediaApiUrl, it requests the font list from your media server and falls back to built-in families if that request fails. A setting that names two ways, or none, prints one console line and uses the built-in families.
Your server or your function answers with the same JSON as the Google Fonts Developer API: an items list in which each entry has family, variants, and category. Other fields are ignored. Your function receives an AbortSignal, which fires when the picker closes before the answer arrives:
import { VideoEditor, type GoogleFontsCatalogue } from '@layermetry/media-editor/react';
async function loadFonts(signal: AbortSignal): Promise<GoogleFontsCatalogue> {
// Your own route, which calls the Google Fonts Developer API with your key.
const response = await fetch('/api/fonts', { signal });
if (!response.ok) throw new Error(`The font list failed with status ${response.status}`);
return response.json();
}
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<VideoEditor
licenseKey="YOUR_LICENSE_KEY"
onClose={() => console.log('The editor was closed')}
googleFonts={{ requestFn: loadFonts }}
/>
</div>
);
}The editor keeps a good answer for as long as the page is open, so opening the picker again makes no second request. The browser downloads each chosen font from Google Fonts, which needs no key.
googleFontsApiKey is deprecated. It still works, but it sends your Google key in a request from the browser, where anyone who opens the page can copy it. When you pass both, googleFonts wins and the key is not sent. On a page that is not on localhost, the editor prints one console warning about the key. If you keep the key, restrict it by HTTP referrer in Google Cloud Console.
A font from a brand style must be loaded by your page, for example with a <link> to Google Fonts or an @font-face rule.
Text styles
The toolbar’s Text styles control opens the Text panel at Brand styles; the separate Text Styles panel has been removed. With text selected, Styles includes size presets (H1 32 px, H2 28 px, H3 24 px, H4 20 px, H5 18 px, Normal 16 px) and case controls (ABC, abc, Abc).
Brand text styles
Pass your brand's text styles in templateMetadata.textStyles, keyed by any name. They appear under Brand styles when a brand is active, and one click applies a style to the selected text:
templateMetadata={{
metadata: {},
textStyles: {
headline: {
textStyleName: 'Brand headline',
fontFamily: 'Georgia',
fontSize: 96,
fontWeight: 700,
lineHeight: 1.1,
fontStyle: 'normal',
textDecoration: 'none',
},
},
}}| Field | Type | Description |
|---|---|---|
textStyleName | string | The name shown in the panel. |
fontFamily | string | A font that your page has loaded, or a system font. |
fontSize | number | The size in pixels, such as 24. Not a CSS string. |
fontWeight | number | The weight, such as 400 or 700. |
lineHeight | number | A multiple of the font size, such as 1.2. |
fontStyle | string | normal or italic. |
textDecoration | string | none or underline. |
With a brand kit, the same styles also appear in the Brand panel and in a Brand styles card at the top of the Text panel. A click styles the selected text, or adds new text in that style when nothing is selected. Each click is one undo step, and a bold text box stays bold when the style is bold. Pass the kit's styles in brands[].textStyles instead of textStyles. A kit with several brands shows the styles of the active brand only.
Letter case
When text is selected, the Styles section offers ABC (uppercase), abc (lowercase), and Abc (capitalize). The words themselves are changed.
Rich text
One text item can mix styles. Double-click the text, select some words, and change their color, size, font, bold, italic, or underline. Only the selected words change.
Outline and shadow
Select a text item and press the text effects button (Ae). The Effects panel opens with the text options:
| Option | Range |
|---|---|
| Presets | Neon, Outline, Drop Shadow. Clear effects removes all. |
| Outline | On or off, with a color and a width from 0 to 10 |
| Shadow / Glow | A color, with blur 0 to 40, offset X and Y −40 to 40, and opacity 0 to 1 |
| Letter spacing | −5 to 40 |
| Line height | 0.5 to 3 |
View full sizeText templates
The Styles section has four template previews and a See all view. The full view includes search and purpose categories (Title, Button, Call to action, Sale, Price, Lower third, Quote, Testimonial, Social handle, Announcement, Countdown and Caption), then style categories (Bold, Elegant, Script, Neon, Outline and More for Gradient, Shadow and Minimal). Brand styles appear first when a brand is active; saved AI-made templates appear first with an AI badge. There is no Label category.
A template is a group of text and simple shapes. With one text selected, it replaces that text, puts the selected words in its main line and keeps their size. With several texts selected, each becomes its own group. A style-locked text cannot be put in a template. With no text selected, the group is added. See Text templates.
Text animation
Select a text item and press Animate to make it enter, exit, or move. See Animations.
AI text generation
The Text panel’s Generate with AI opens one form. Choose Words or Text template; with text selected, those choices read Change the words and Put it in a template. The prompt remains when switching. Selecting a result previews it on the canvas and makes it the current choice. Generate more appends results; Try again replaces them. Add to canvas keeps the form open. See AI providers for the request and Text templates for the typed template format.
AI rewrite
The toolbar’s Rewrite with AI and the text right-click action open the Text panel’s AI form in rewrite mode. The same form can change the selected words or use them in a text template; + New starts a new text item. Selecting a result previews it. Closing with ✕, pressing Escape, or changing selection keeps the choice as one undoable edit.
Configuration
| Prop | Type | Default | Description |
|---|---|---|---|
templateMetadata | object | none | textStyles adds brand styles to Brand styles in the Text panel when a brand is active. |
textTemplates | AITextTemplatesSettings | none | Adds host categories and templates to Styles. Invalid entries are dropped with a console warning. See Text templates. |
googleFonts | { hosted: true }, { endpointUrl }, or { requestFn } | Built-in families | Where the font picker gets the whole Google Fonts catalog. |
googleFontsApiKey | string | none | Deprecated. Sends your Google key from the browser. Use googleFonts. |
ai | object | none | The AI provider for text, rewriting and text-template generation. Configure each operation separately. |
ai.text, ai.textRewrite, ai.textTemplate | false or object | operation-dependent | Configure or disable each operation. Hosted template generation is off unless ai.textTemplate is explicitly set; hosted AI is unavailable in SDK 1.0.0. |
typography | object | none | The fonts of the editor's own panels. It does not change text items. See Theming. |
Events
Text has no events of its own. Text reaches you inside the exported video through onExport, and inside saved designs through onSaveTemplate. See Events.