How to properly load fonts via figma.loadFontAsync?

When I try to load bold fonts I get this error:

Uncaught (in promise) Error: in set_characters: Cannot write to node with unloaded font "Inter Regular". Please call figma.loadFontAsync({ family: "Inter", style: "Regular" }) and await the returned promise first.
    at TextNode.set_characters [as characters] (eval at <anonymous> (eval at createScopedEvaluatorFactory (7d5ef243-04e5-40fb-8232-bb47f610f5b4:1:6906)), <anonymous>:23:21)
    at ./src/plugin/controller.ts.figma.ui.onmessage (controller.ts:50:1)

This is strange because I am not trying to load “Inter Regular” and you can clearly see that I am trying to load “Inter Bold”.

This is the line of code at issue:

  if (message.type === 'addFormMultiStepLogo') {
    const baseFrame = findBaseFrame(message.baseFrameId);

    const logoBaseFrame = createFrameAndAppendTo(baseFrame, {
      name: 'Logo Base Frame',
      layoutMode: 'HORIZONTAL',
      counterAxisAlignItems: 'CENTER',
      counterAxisSizingMode: 'AUTO',
      layoutAlign: 'STRETCH',
      layoutPositioning: 'AUTO',
      primaryAxisAlignItems: 'CENTER',
      primaryAxisSizingMode: 'FIXED',
      itemSpacing: 15
    });

    baseFrame.appendChild(logoBaseFrame);

    const logoSymbol = figma.currentPage.findOne(
      node => node.type === 'FRAME' && node.name === 'Logo Symbol'
    ) as FrameNode;

    const logoSymbolInstance = logoSymbol.clone();

    const logoTitle = figma.createText();    

    [logoSymbolInstance, logoTitle]
      .forEach((child) => child && logoBaseFrame.appendChild(child));

    try {
      await figma.loadFontAsync({ // <--- THE FONT IS LOADED HERE
        family: 'Inter',
        style: 'Bold'
      });

    } catch(err) {
      console.error(`Error: ${err}`);

    }

    if (logoTitle) {
      logoTitle.characters = message.title.toUpperCase() // <--- THIS LINE HERE
      logoTitle.fontSize = 19;
    }
  }

I await the promise as instructed but I keep getting the same error.

If I do this:

    try {
      await figma.loadFontAsync({
        family: 'Inter',
        style: 'Regular' // <--- "Regular" instead of "Bold"
      });

    } catch(err) {
      console.error(`Error: ${err}`);

It works as expected. But if I replace “Regular” with “Bold” again I will encounter the same error. I suspect it to work if I use setRangeFontName after the font (Inter Regular) is loaded and set the style to “Bold”.

You load the font but you don’t set it to the text block. This is why it’s asking you to load Inter Regular — the current font on the text block at the time of setting characters. If you apply the loaded font to the text node first via textNode.fontName = ... and then set characters, it should work. TextNode | Plugin API

1 Like

Could you demonstrate what you mean by setting it to the text block?

Is this what you mean:

    try {
      await figma.loadFontAsync({
        family: 'Inter',
        style: 'Bold'
      });

    } catch(err) {
      console.error(`Error: ${err}`);

    }

    const logoTitle = figma.createText();    
    logoTitle.fontName = {
      family: 'Inter',
      style: 'Bold'
    };

That worked. Thank you!

Do we need to load the font before we use figma.createText to create a text node?

No, you don’t. Only before you set characters or change other text node properties that change how text looks.