Fonts and rendering

Languages and emoji

Try it in the demo →

A design font rarely has every character people type. In the default vector mode, a character the font lacks is drawn from Google's Noto fonts, and an emoji from our Noto emoji set. Those characters are measured, wrapped and printed like the rest of the text, so they look the same in every browser and in print. There is nothing to set up.

Characters a font lacks

Type Japanese into a box set in Poppins, which has no Japanese letters, and the Japanese is drawn from Noto Sans JP. The font of the box does not change, and choosing another font for the text keeps the missing characters drawn.

Characters Drawn from
Accented letters and other alphabets the font lacks Noto Sans, at the text's weight and italic
Symbols Noto Sans Symbols 2, then Noto Sans Symbols
Korean Noto Sans KR
Japanese Noto Sans JP
Chinese Noto Sans SC, or Noto Sans JP when the text also has Japanese kana

Only the missing characters are downloaded, as small subsets of each font. box.fontsReady() waits for them, including characters a merge field or an edit brings in later.

Emoji

An emoji is drawn from our hosted Noto emoji set: one image per emoji, fetched only for the emoji a document uses. An emoji the set does not have is drawn the standard Unicode way, as its parts side by side, and anything still missing as a box. The editor shows the same result that prints.

To serve the emoji yourself, host a copy of the same files (one SVG per emoji, named emoji_u<code points>.svg) and point to its folder:

import { configureRichText } from "@mycreativeshop/rich-text"; // on Konva: "@mycreativeshop/rich-text/konva"

configureRichText({ emoji: { baseUrl: "https://cdn.example.com/emoji" } }); // no trailing slash

In an environment with no Image (a server), also pass loadImage: (svgText) => ..., which returns something a canvas can draw.

Let the browser draw them instead

configureRichText({ emoji: null }); // the browser draws emoji
configureRichText({ fallbackFonts: false }); // the browser draws characters the font lacks

The browser draws those characters from the fonts on the device, so they can look different, and break lines differently, from one device to another and in print.

To serve the fallback fonts from your own host, give fallbackFonts a cssUrl function. It receives a FallbackFontRequest - the Noto family, the weight, whether the text is italic, whether the family has weight and italic axes, and the exact characters needed - and returns the address of a stylesheet for it.

configureRichText({
  fallbackFonts: { cssUrl: (request) => `https://fonts.example.com/css2?family=${encodeURIComponent(request.family)}&text=${encodeURIComponent(request.chars)}` },
});

These settings apply to vector mode. In native mode the browser draws all text, these characters included (see Vector text).

Limits

Limit: Right-to-left text (Arabic, Hebrew) is not supported yet. Its letters are shaped, but each line is laid out left to right. See Coming soon.

Limit: Scripts the Noto fonts above do not cover, such as Devanagari and Thai, and color fonts are drawn by the browser rather than as vector shapes. They look right on screen, but are not guaranteed to match pixel for pixel across browsers and in print.

In the API reference