NarraLeaf

Custom Fonts

There are two separate font layers: regular player UI inherits CSS, while dialog and choice text can also receive explicit defaults from Texts and Item.

1. Load the font

Prefer WOFF2 for web delivery and keep a system fallback.

@font-face {
    font-family: "GameText";
    src: url("/fonts/game-text.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

.game-player {
    font-family: "GameText", system-ui, sans-serif;
}

In Next.js, next/font/local is another good option. Apply its generated class to the same Player boundary.

2. Apply it to the player

<GameProviders>
    <Player
        story={story}
        className="game-player"
        onReady={({ liveGame }) => liveGame.newGame()}
    />
</GameProviders>

This covers pages, buttons, and UI that inherit font-family.

3. Set dialog defaults

Since NarraLeaf 0.10, dialog font defaults are component props. They are no longer part of GameConfig.

import { Dialog, Nametag, Texts } from "narraleaf-react";

export function GameDialog() {
    return (
        <Dialog className="game-player rounded-xl bg-black/75 p-6">
            <Nametag color="#fbbf24" />
            <Texts
                defaultColor="white"
                fontFamily="GameText, system-ui, sans-serif"
                fontSize={22}
                fontWeight={400}
                fontWeightBold={700}
            />
        </Dialog>
    );
}

Sentence and Word styles still take priority over these defaults.

4. Set choice defaults

Custom menus set typography on each Item.

<Item
    defaultColor="white"
    fontFamily="GameText, system-ui, sans-serif"
    fontSize={20}
    fontWeight={400}
    fontWeightBold={700}
/>

Checks

  • Confirm the font URL returns 200 and is not blocked by CORS.
  • Check normal and bold weights; browsers synthesize missing weights.
  • Keep font-display: swap so text does not stay invisible while loading.
  • Test Chinese, Japanese, and Korean glyph coverage when the game uses those scripts. A Latin-only font will silently fall back per character.

On this page