Skip to main content
Solved

How to properly load fonts via figma.loadFontAsync?

  • October 18, 2022
  • 5 replies
  • 2165 views

Aric_Jiang

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”.

Best answer by Gleb

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

View original

5 replies

Gleb
  • Power Member
  • 4707 replies
  • October 18, 2022

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


Aric_Jiang
  • Author
  • 9 replies
  • October 18, 2022

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'
    };

Aric_Jiang
  • Author
  • 9 replies
  • October 18, 2022

That worked. Thank you!


Aric_Jiang
  • Author
  • 9 replies
  • October 18, 2022

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


Gleb
  • Power Member
  • 4707 replies
  • Answer
  • October 18, 2022

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


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings