Hi all –
Setting the text of a text node (using the Figma plugin API) is not a straightforward thing.
- The font or style of any character in the string you plan to overwrite cannot be “missing.”
- Every font/style that exists in the current string must be loaded before overwrite
- Font loading is promise-based
The code below loads the necessary fonts before setting a text node’s text and tests for missing fonts. It works, and it’s surprisingly fast given the tedium it puts itself through.
Disclaimer: I’m a designer, so I’m certain this code can be improved. I enthusiastically welcome feedback.
// this function loads fonts and sets text. Throws error if a font is missing.
const setTextOfNode = (textNode: TextNode, text: string) => {
if (textNode.hasMissingFont) {
throw "<missing font error goes here>";
}
const foundFonts = [] as FontName[];
const len = textNode.characters.length;
// check textNode's font & style character by character. It may contain multiple fonts/styles
for (let i = 0; i < len; i++) {
const fontName = textNode.getRangeFontName(i, i + 1) as FontName;
// only add a font to foundFonts if it hasn't been added yet
if (foundFonts.find(f => f.family === fontName.family && f.style === fontName.style) === undefined) {
foundFonts.push(fontName);
}
}
// get an array of loadFontAsync() promises, one for each entry in foundFonts[]
const fontPromises = foundFonts.map(f => figma.loadFontAsync(f));
// text is set only after all fonts are loaded
Promise.all(fontPromises).then(() => {
textNode.characters = text;
});
return textNode;
}
// sample usage
try {
setTextOfNode(myTextNode, "Text to set");
} catch (e) {
// error handling for missing font goes here
}