Image

Text

Add, style, and generate text.

Text boxes hold the words of a design. The user picks the font, size, color, and alignment, styles single words, and adds outline, shadow, and gradient. Ready-made text templates and AI help write the words.

Setup

Text works with no setup. Three props add more:

src/App.tsx
import { ImageEditor } from '@layermetry/media-editor/react';

export default function App() {
  return (
    <div style={{ position: 'fixed', inset: 0 }}>
      <ImageEditor
        licenseKey="YOUR_LICENSE_KEY"
        onClose={() => console.log('The editor was closed')}
        // The whole Google Fonts catalog in the font list, from your own server.
        googleFonts={{ endpointUrl: '/api/fonts' }}
        // Your brand's text styles.
        templateMetadata={{
          metadata: {},
          textStyles: {
            headline: {
              textStyleName: 'Brand headline',
              fontFamily: 'Montserrat',
              fontSize: 64,
              fontWeight: 700,
              lineHeight: 1.1,
              fontStyle: 'normal',
              textDecoration: 'none',
            },
          },
        }}
        // AI text generation and rewriting.
        ai={{ endpointUrl: 'https://api.example.com/ai' }}
      />
    </div>
  );
}
OptionPropPage
The whole Google Fonts cataloggoogleFontsFonts
Your brand's text stylestemplateMetadata.textStylesBrand text styles
Host text templatestextTemplatesText templates
AI text generation and rewritingaiAI 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.

Double-click a text box to type in it. Enter ends the editing, and Shift+Enter starts a new line. Esc, or a click outside the box, also ends the editing.

When a text box is selected, the toolbar above the page shows:

GroupControls
TextRewrite with AI, font, align left, center, and right
FormatBold, italic, underline, text color
StyleFont size, from 1 to 999, and Text styles
ControlsBring to front, send to back, delete, transparency

Fonts

Select a text box and press the font button in the toolbar. The Font panel lists font families by category, with a search field. Open a family to choose a weight or italic.

The font chooser beside the selected poster headlineView full size

Without the whole catalog, the panel lists 25 popular families: Roboto, Open Sans, Lato, Montserrat, Poppins, Inter, Nunito, Work Sans, Oswald, Merriweather, Playfair Display, Lora, PT Serif, Libre Baskerville, Bebas Neue, Anton, Righteous, Alfa Slab One, Pacifico, Satisfy, Dancing Script, Caveat, Roboto Mono, Source Code Pro, and JetBrains Mono.

The panel 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:

SettingWhere 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 panel 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 panel closes before the answer arrives:

import { ImageEditor, 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 }}>
      <ImageEditor
        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 panel 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.

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

templateMetadata.textStyles appears in Brand styles below the AI control when a brand is active. With no text selected, choosing one adds text in that style; with text selected, it applies the style.

templateMetadata={{
  metadata: {},
  textStyles: {
    headline: {
      textStyleName: 'Brand headline',
      fontFamily: 'Montserrat',
      fontSize: 64,
      fontWeight: 700,
      lineHeight: 1.1,
      fontStyle: 'normal',
      textDecoration: 'none',
    },
  },
}}
FieldTypeDescription
textStyleNamestringThe name in the panel.
fontFamilystringA font family. Your page must load a font that is not in Google Fonts.
fontSizenumberThe size in pixels.
fontWeightnumberFor example 400 or 700.
lineHeightnumberThe line height, as a multiple of the size.
fontStylestring'normal' or 'italic'.
textDecorationstring'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. Pass the kit's styles in brands[].textStyles instead of textStyles. A kit with several brands shows the styles of the active brand only.

metadata is required in templateMetadata. It adds your own fields to saved templates. See Saving and loading.

Letter case

When text is selected, the Styles section offers ABC (uppercase), abc (lowercase), and Abc (capitalize). The words themselves are changed.

Rich text

A single word or letter can have its own style. Double-click a text box, select part of the text, and press Bold, Italic, Underline, or the text color, or change the font size.

A selected two-line heading on an editorial poster, with text formatting controlsView full size

When part of the text is selected, the tooltips of these buttons end in "selected text". The font, the alignment, and the text styles always apply to the whole text box. A new font size applies to whole lines, so that each line has one size.

When the whole selection already has a style, the button removes it. Otherwise, it adds the style to all of the selection.

Outline and shadow

Select a text box and open the Effects panel. Outline draws a line around the letters. Shadow / Glow draws a soft color behind them.

ControlRangeWhen switched on
Outline colorany colorblack
Outline width0 to 103
Shadow colorany colornone
Shadow Blur0 to 400
Shadow Offset X, Shadow Offset Y-40 to 400
Shadow Opacity0 to 11

The presets at the top set several values at once:

PresetResult
NeonA pink glow: color #ff4fc3, blur 22, no offset.
OutlineA black outline, width 3.
Drop ShadowA black shadow, blur 4, 5 pixels right and down.
GradientA yellow-to-orange gradient. See Gradient text.
Clear effectsRemoves outline, shadow, gradient, letter spacing, and line height.
The Neon effect selected for the editorial poster headlineView full size

The same panel sets Letter Spacing, from -5 to 40, and Line Height, from 0.5 to 3.

Gradient text

The Gradient switch in the Effects panel fills the letters with a color gradient, from the Start color at the top to the End color at the bottom. The default colors are #fbbf24 and #f97316.

The gradient is linear and runs from top to bottom, over the height of one line.

Text 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.

AI text generation

The Text panel’s Generate with AI button 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

PropTypeDefaultDescription
textTemplatesAITextTemplatesSettingsnoneAdds 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 familiesWhere the Font panel gets the whole Google Fonts catalog. Without the catalog, 25 popular families are listed.
googleFontsApiKeystringnoneDeprecated. Sends your Google key from the browser. Use googleFonts.
templateMetadata.textStylesobjectnoneYour brand text styles, shown in Brand styles when a brand is active.
aiobjectnoneThe AI provider for text, text rewriting and text-template generation.
ai.text, ai.textRewrite, ai.textTemplatefalse or objectoperation-dependentConfigure or disable each operation. Hosted text-template generation is off unless you explicitly set ai.textTemplate.
typographyobjectnoneThe fonts of the editor's own buttons and panels, not of the design. See Theming.

Events

Text has no events of its own. The words are part of the design, and they reach you in the exported file through onExport. See Events.

Troubleshooting

Additional resources

On this page