RVE LogoReact Video EditorDOCS
RVE SDK/Quick Start/Setup Google Fonts

Setup Google Fonts

Load and use Google Fonts in your video editor projects

RVE uses Google Fonts for text overlays. Fonts work in two contexts: the editor (browser) and server-side rendering. The setup uses a proxy route so the large font database (~2MB) stays server-side.

Why a proxy?

Google Fonts need metadata to work - what weights are available, what character sets they support, where to download the actual font files from. For 243 fonts, that metadata adds up to roughly 2MB.

You can't ship 2MB of font data to the browser. It would destroy your page load time. So we split it:

  • Browser gets a tiny list - just font names, enough to show a font picker. This is small and fast.
  • Server holds the full database - all the metadata. When a user picks a font in the editor, the browser asks your server for just that one font's info via /api/fonts/[name]. One small request, on demand.
  • During rendering - when you export a video, the server already has the full database locally. It looks up what the video uses, grabs their metadata, and hands it to the renderer so it can download and render the correct fonts. No extra network calls needed.

The API route is the bridge. It keeps the heavy data on the server and gives the browser exactly what it needs, when it needs it.

How it works

Browser (editor)
├── Uses GOOGLE_FONTS_LIST (lightweight, 243 fonts, names only) for the font picker UI
└── Fetches full font metadata on demand:  /api/fonts/[name]  →  GOOGLE_FONTS_DATABASE (server-only)

Server (rendering)
├── collectFontInfoFromOverlays() scans overlays for fonts used
├── Looks up full metadata from GOOGLE_FONTS_DATABASE
└── Passes fontInfos into inputProps so fonts load during render

The browser never imports the full database. It fetches individual font info via your API route when a user selects a font.

Step 1: Create the font API route

Create app/api/fonts/[name]/route.ts:

import { NextRequest, NextResponse } from 'next/server';
import { GOOGLE_FONTS_DATABASE } from '@reactvideoeditor/react-video-editor/data/google-fonts';

export async function GET(
  _request: NextRequest,
  ctx: { params: Promise<{ name: string }> }
) {
  const fontFamily = (await ctx.params).name;

  const fontInfo = GOOGLE_FONTS_DATABASE.find(
    (font) => font.fontFamily === fontFamily
  );

  if (!fontInfo) {
    return NextResponse.json(
      { error: `Font "${fontFamily}" not found` },
      { status: 404 }
    );
  }

  return NextResponse.json(fontInfo, {
    headers: { 'Cache-Control': 'public, max-age=3600' },
  });
}

This route serves font metadata (weights, styles, unicode ranges, URLs) from the pre-built GOOGLE_FONTS_DATABASE. The database is server-only and must never be imported in browser code.

Step 2: Set up font collection for rendering

If you're using server-side rendering, you need to collect font info from overlays before passing them to the renderer.

Create app/utils/text/collect-font-info-from-items.ts:

import {
  GOOGLE_FONTS_DATABASE,
  type GoogleFontInfo,
} from '@reactvideoeditor/react-video-editor/data/google-fonts';
import {
  type Overlay,
  OverlayType,
} from '@reactvideoeditor/react-video-editor/types';

export const collectFontInfoFromOverlays = (
  overlays: Overlay[]
): Record<string, GoogleFontInfo> => {
  const fontInfos: Record<string, GoogleFontInfo> = {};

  for (const overlay of overlays) {
    let fontFamily: string | undefined;

    if (overlay.type === OverlayType.TEXT) {
      fontFamily = overlay.styles.fontFamily;
    } else if (overlay.type === OverlayType.CAPTION) {
      fontFamily = overlay.styles?.fontFamily || 'Inter';
    }

    if (!fontFamily || fontInfos[fontFamily]) continue;

    const fontInfo = GOOGLE_FONTS_DATABASE.find(
      (font) => font.fontFamily === fontFamily
    );

    if (fontInfo) {
      fontInfos[fontFamily] = fontInfo;
    }
  }

  return fontInfos;
};

Then in your render route, collect and pass the font infos:

import { collectFontInfoFromOverlays } from '@/utils/text/collect-font-info-from-items';

// In your render handler:
const fontInfos = collectFontInfoFromOverlays(inputProps.overlays || []);
const inputPropsWithFonts = {
  ...inputProps,
  fontInfos,
};
// Pass inputPropsWithFonts to your renderer

Step 3: That's it

With the /api/fonts/[name] route in place:

  • The font picker in the editor sidebar works automatically (loads font previews from Google Fonts CDN, fetches full metadata from your route when selected)
  • Font loading is cached client-side to avoid duplicate requests
  • Falls back to Roboto if a font fails to load
  • During rendering, fonts are pre-collected and passed via FontInfoContext so the renderer can load them synchronously

Key files in the package

FilePurpose
data/google-fonts-list.tsLightweight font list (243 fonts, names only) - safe for browser
data/google-fonts.tsFull font database (~2MB) - server-only, never import in browser
utils/text/load-font-from-text-item.tsFont loading logic with caching and Roboto fallback