Skip to main content

Fonts

Renderer font management mirrors the packs exposed in the editor so that typography stays consistent in the final output.

Resolving editor font IDs​

Each text node stores a fontId. The renderer should translate that into a full font stack and any required external assets:

const FONT_MAP = {
inter: {
stack: "\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
import: "https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
},
georgia: {
stack: "Georgia, serif"
}
};

function resolveFont(node: TextNode) {
const font = FONT_MAP[node.props.fontId ?? "inter"];
return {
stack: font.stack,
importHref: font.import
};
}
  • Default to a safe stack when fontId is missing so legacy documents remain valid.
  • Cache remote font imports and inject them once per rendering pass to avoid duplication.

Inline styles vs MJML​

  • When targeting raw HTML, set style="font-family: ..." directly on elements.
  • For MJML output, create reusable classes (<mj-class>) from the same font stacks and reuse them across components.

Client limitations​

Remember that popular email clients (Outlook desktop, Gmail mobile) selectively block web fonts. Always specify a robust fallback stack and avoid depending on custom font weights that do not have good fallback equivalents.