Dynamically load font inside Plugin UI

Hello !
In my last post I was answered that I can’t trigger Figma’s UI from my plugin’s UI and can’t render (reuse) built-in components in my plugin, but need to code them from scratch.
What about fonts ?
I need to have preview for a new text style (my plugin creates text styles), so I need to dynamically load font for this preview inside plugin’s UI.

Or also I need to have the same fonts list like in Figma, where every row with font name has also same font family.
Can I do this ? Or I need manually load always fonts with and some cdn ?

There are several ways here:

  1. Load fonts or font previews from the CDN (if they are there);
  2. Specify font-family in CSS to render local fonts;
  3. Create a TextNode with the desired font, export it as an image (JPG, PNG or SVG) and send it to the UI.

Thanks for answer.
What about 3rd approach ? Are there any practices, how to do it ? Maybe hide it while doing font or what ?

In principle, I almost completely described it. Just after export, delete the TextNode created by the plugin.

Just try all three methods and choose the most suitable one or a combination of them.

I guess, 1-2 approaches are not efficient, because there are hundreds of fonts in Figma, but locally I have very few of them on my Windows PC. Also I can’t manually load all these hundreds of fonts via CDN ))
But what if plugin crashes, for example… Need to catch such cases and remove temporal text nodes before exit, right ?

And also:
where would u advice to export such temporary text node image ?
I am developing plugin via React, so I have to export it as bytes, pass wia postMessage to UI (as base64 probably) - and there paste to src of <img/>, right ?

If you want to use the 3rd method to load thousands of fonts at once, then it will be even worse than the first two methods. Because when you load a font, it is imported into a file and stored in memory, which can lead to the file running out of memory (2GB limit). So, experiment with different approaches.

Just like with any other software, you need to anticipate the presence of various errors by catching and resolving them. So deleting temporary nodes on error seems pretty good from a UX perspective.

Also check out these docs:

You can send both bytes (Uint8Array) and encoded images to Base64. In the first case, you need to process these bytes so that they can be used as an image. In the second, as you described, you can immediately pass a Base64 string as the img src value. As with everything else, choose the approach that’s right for you.

Here is the documentation for the methods you need:

Also I recommend you look into open source plugins to see how their authors have implemented something similar. Some of them:

1 Like