Figma has at all times inspired collaboration between builders and designers. It strives on an countless treasury of community-made plugins. Want 3D parts? There’s a plugin for that. Want summary SVGs? There’s a plugin for that, too.
That mentioned, the design a part of Figma has at all times been comparatively static — at all times working with unmovable rectangles linked to one another by way of predefined consumer interactions. However what if I advised you that your designs may out of the blue come to life — that they could possibly be animated, interactive, and even stateful? Then, what would separate idea from implementation?
Figma introduced in June that it’s bringing JavaScript-powered widgets to the desk. Now, designers have can browse and implement logic-driven elements straight in Figma!
Say hey to the Widgets API! You need to know what it’s and how one can use it? That’s precisely what we’re going to do collectively on this submit.
Figma widgets open up tons of prospects
Think about that you just’re working across the clock along with your companion to design a big restaurant software. You’re each already collaborating on the identical Figma board; each of you’re sharing the very same doc with modifications taking place on the fly.
Absolutely, you already know that collaboration includes extra that simply the design course of:
venture administration,internet hosting polls to collect votes,importing and visualizing mock knowledge,and even perhaps enjoying a multiplayer sport to cool-off after many hours of labor.
We simply require one individual to handle all the things and send-out hyperlinks to different members of the group. However oh, that’s not very environment friendly, is it?
Properly, that’s the place widgets come into play. We will conceivably do all of that — sure, all the things —with out ever leaving Figma.
Listed below are only a few of the methods you may need to use widgets in Figma:
Creating duties for Jira and AsanaCreating points in GitHubDisplaying Dynamic InformationRecording voice memosCreating job listsLosing time Taking part in Tic-Tac-ToeMonitoring actionsCreating timers
The record goes on and on. As you may inform, there’s already a plethora of widgets you can freely use in your paperwork. In reality, you may add Widgets straight to your board from the Widgets menu (Shift+I).
However we’re not right here to learn to use widgets, as a result of that’s simple. Allow us to do what we do greatest: we’re gonna create our personal Figma widget! This one shall be impressed by Chris Coyier’s design quotes web site. We’ll take the API, feed it into the widget, then show random design quotes straight in Figma.
Right here’s what we want
I don’t wish to be the bearer of dangerous information, however to be able to develop widgets, you have to be on Home windows or Mac. Linux customers, I’m sorry, however you’re out of luck. (You possibly can nonetheless use a VM if you wish to observe alongside.)
We’re gonna obtain the Figma Desktop software. The best method to get began is by producing a widget template, straight from the app.
Let’s create a brand new board by opening the widgets menu (Shift+ I), switching to the Improvement tab, and creating a brand new merchandise.
Following that, Figma will immediate you to call the brand new widget and resolve whether or not it’s extra tailor-made in the direction of design boards or FigJam boards too. The previous possibility is ample for the needs of this text.
And the customization doesn’t finish right here; Figma may even provide the possibility to start out with a pre-made counter widget or an iFrame-enabled various that additionally offers you entry to the Canvas and Fetch APIs (in addition to all different browser APIs). We’ll go together with the easy “Empty” possibility, however we’ll finally modify it ourselves to utilize the Fetch API.
You’ll then be prompted to save lots of your new widget venture to a particular listing in your system. As soon as that’s achieved, launch your terminal and direct it to that folder. Don’t run any instructions but — we’ll do this later and purposefully get an error with the purpose of studying extra in regards to the Widgets API.
Designing the widget
We’re pulling the design straight from Chris Coyier’s design quotes web site. So, let’s go there and dive into by firing up DevTools.
The 2 key shortcuts that I’m utilizing listed here are Ctrl+Shift+C (or Cmd+Shift+C) to toggle the “Decide factor” instrument, and Shift+Click on to alter the colour format to HEX code. We’re doing this to study in regards to the colours, fonts, font weights and font sizes utilized in Chris’s web site. All this info is vital to construct a closely-resembling widget in Figma, which shall be our subsequent step! You possibly can seize the designed element and use it in your personal canvas.
I received’t go into a lot element right here as this text’s major subject is constructing widgets by writing code. However I can’t stress sufficient how essential it’s to take excellent care of your widgets’ fashion… CSS-Tips already has a plethora of design-oriented Figma tutorials; you received’t remorse including them to your studying record.
Creating the structure for our widget
With design out of the best way, it’s time to take our programming fingers out and begin constructing the gears of our widget.
It’s very attention-grabbing how Figma interprets its design constructing blocks to React-like elements. Body parts with the auto-layout characteristic, for instance, are represented because the <AutoLayout /> element in code. Along with that, we’ll be utilizing two extra elements: <Textual content /> and <SVG />.
Check out my Figma board… I’m exactly asking you to deal with the article tree. It’s what we want to have the ability to translate our widget design to JSX code.
As you may see, our design quotes widget calls for three elements to be imported. That’s an honest variety of elements contemplating that the full API solely incorporates eight layer-based nodes. However as you’ll quickly see, these modules are greater than ample to craft every kind of layouts.
// code.tsx
const { widget } = figma;
const { AutoLayout, Textual content, SVG } = widget;
And with this, now we have all we have to go forward and construct the skeleton of our widget like we might in React:
operate QuotesWidget() {
const quote = `…`;
const writer = `…`;
return (
<AutoLayout>
<SVG />
<AutoLayout>
<Textual content>{quote}</Textual content>
<Textual content>— {writer}</Textual content>
</AutoLayout>
<SVG />
</AutoLayout>
);
}
widget.register(QuotesWidget);
This code could be very complicated, to say the least. Proper now, we will’t inform the design layers aside. Fortunately, we’re capable of simply clear up this subject by way of using the title property.
<AutoLayout title={“Quote”}>
<SVG title={“LeftQuotationMark”} />
<AutoLayout title={“QuoteContent”}>
<Textual content title={“QuoteText”}>{quote}</Textual content>
<Textual content title={“QuoteAuthor”}>— {writer}</Textual content>
</AutoLayout>
<SVG title={“RightQuotationMark”} />
</AutoLayout>;
And, in fact, we nonetheless can’t see our citation mark SVGs, so let’s work on fixing that. The <SVG/> element settle for a srcproperty that takes the supply code for an SVG factor. There isn’t a lot to say on this one, so let’s hold it easy and bounce straight again to code:
const leftQuotationSvgSrc = `<svg width=”117″ top=”103″ viewBox=”0 0 117 103″ fill=”none” xmlns=”<http://www.w3.org/2000/svg>”>
// shortened for brevity
</svg>`;
const rightQuotationSvgSrc = `<svg width=”118″ top=”103″ viewBox=”0 0 118 103″ fill=”none” xmlns=”<http://www.w3.org/2000/svg>”>
// shortened for brevity
</svg>`;
operate QuotesWidget() {
return (
<SVG title={“LeftQuotationMark”} src={leftQuotationSvgSrc} />
<SVG title={“RightQuotationMark”} src={rightQuotationSvgSrc} />
);
}
I feel we will all agree that all the things is way clearer now! Once we title issues, their goal out of the blue turns into way more apparent to the readers of our code.
Previewing our widget in real-time
Figma affords an important developer expertise when constructing widgets, together with (however not restricted to ) hot-reloading. With this characteristic, we’re capable of code and preview modifications to our widget in real-time.
Get began by opening the widgets menu (Shift+I), switching to the event tab and clicking or dragging your new widget to the board. Unable to find your widget? Don’t fear, simply click on on the three-dot menu and import your widget’s manifest.json file. Sure, that’s all it takes carry it again to existence!
Wait, did you get an error message on the backside of your display screen?
In that case, let’s examine. Click on on “Open console” and browse what it has to say. If the Open console button is gone, there’s an alternate method to open the debugging console. Click on on the Figma emblem, bounce to the widgets class and reveal the event menu.
That error is probably going because of the truth that we haven’t compiled our TypeScript to JavaScript but. We will do this within the command line by working npm set up and npm run watch. (or yarn and yarn watch ). No errors this time!
Yet another impediment you may hit is that the widget fails to re-render any time the code is modified. We will simply power our widget to replace utilizing the next context menu command: Widgets → Re-render widget.
Styling the widget
Because it at present stands, the seems to be of our widgets are nonetheless fairly removed from our ultimate purpose.
So how will we fashion Figma elements from code? Possibly with CSS like we might do in a React venture? Unfavourable. With Figma widgets, all the styling occurs by way of a set of well-documented props. Fortunate for us, these things are named nearly identically to their counterparts in Figma.
We’ll get began by configuring our two <AutoLayout /> elements. As you may see within the infographic above, prop names are fairly descriptive of their goal. This makes it simple for us to leap straight into code and begin making some modifications. I received’t be exhibiting the entire code once more, so please depend on the element names to information you the place the snippets belongs.
<AutoLayout
title={“Quote”}
path={“horizontal”}
verticalAlignItems={“begin”}
horizontalAlignItems={“heart”}
spacing={54}
padding={{
horizontal: 61,
vertical: 47,
}}
>
<AutoLayout
title={“QuoteContent”}
path={“vertical”}
verticalAlignItems={“finish”}
horizontalAlignItems={“begin”}
spacing={10}
padding={{
horizontal: 0,
vertical: 0,
}}
></AutoLayout>
</AutoLayout>;
We simply made a whole lot of progress! Let’s save and bounce again to Figma to see how our widget seems to be like. Keep in mind how Figma reloads widgets mechanically upon new modifications?
However it’s not fairly there but. We should additionally add a background colour to the basis element:
<AutoLayout title={“Quote”} fill={“#ffffff”}>
Once more, check out your Figma board and see how modifications could be mirrored nearly instantly again into the widget.
Let’s transfer alongside this information and magnificence the <Textual content> elements.
After having a look on the Widgets API documentation, it’s once more clear that property names are nearly similar to their counterparts within the Figma app, as could be seen within the infographic above. We’ll even be utilizing values from the final part the place we inspected Chris’ web site.
<Textual content title={‘QuoteText’}
fontFamily={‘Lora’}
fontSize={36}
width={700}
fill={‘#545454’}
fontWeight={‘regular’}
>{quote}</Textual content>
<Textual content title={‘QuoteAuthor’}
fontFamily={‘Raleway’}
fontSize={26}
width={700}
fill={‘#16B6DF’}
fontWeight={‘daring’}
textCase={‘higher’}
>— {writer}</Textual content>
Including state to the widget
Oour widget at present shows the identical quote, however we need to pull from your complete pool of quotes at random. We should add state to our widget, which all React builders know is a variable whose change triggers the re-rendering of our element.
With Figma, state is created with the useSyncedState hook; it’s just about React’s useState, however it requires programmers to specify a distinctive key. This requirement stems from the truth that Figma should sync our widget’s state throughout all purchasers that could be viewing the identical design board, however by way of completely different computer systems.
const { useSyncedState } = widget;
operate QuotesWidget() {
const [quote, setQuote] = useSyncedState(“quote-text”, “”);
const [author, setAuthor] = useSyncedState(“quote-author”, “”);
}
That’s all of the change that we want for now. Within the subsequent part, we’ll work out how one can fetch knowledge from the Web. Spoiler Alert: it’s not so simple as it appears.
Fetching knowledge from the community
Recall when Figma gave us the selection to start out with an iFrame-enabled widget. Though we didn’t go together with that possibility, we should nonetheless implement a few of its options. Let me clarify why we will’t merely name fetch() inside our widget code.
Whenever you use a widget, you’re working JavaScript code by yourself laptop that’s written by another person. Whereas all widgets are totally reviewed by the Figma employees, it’s nonetheless an enormous safety gap as everyone knows how a lot harm could be created by even one line of JavaScript.
In consequence, Figma can’t merely eval() any widget code written by nameless programmers. Lengthy story brief, the group determined that the perfect resolution was working third-party code in a closely-guarded sandbox surroundings. And as you might need guessed, browser APIs are unavailable in such an surroundings.
However don’t fret, Figma’s resolution to this second drawback is <iframe>s. Any HTML code that we write in a file, ideally known as ui.html, could have entry to all browser APIs. You is perhaps questioning how we will set off this code from the widget, however we’ll look into that later. Proper now, let’s bounce again into code:
// manifest.json
{
“ui”: “ui.html”
}
<!– ui.html –>
<script>
window.onmessage = async (occasion) => {
if (occasion.knowledge.pluginMessage.kind === ‘networkRequest’) {
// TODO: fetch knowledge from the server
window.mum or dad.postMessage({
pluginMessage: {
// TODO: return fetched knowledge
}
}, ‘*’)
}
}
</script>
That’s the overall template for widget-to-iframe communication. Let’s use it to fetch knowledge from the server:
<!– ui.html –>
<script>
window.onmessage = async (occasion) => {
if (occasion.knowledge.pluginMessage.kind === ‘networkRequest’) {
// Get random quantity from 0 to 100
const randomPage = Math.spherical(Math.random() * 100)
// Get a random quote from the Design Quotes API
const res = await fetch(`https://quotesondesign.com/wp-json/wp/v2/posts/?orderby=rand&per_page=1&web page=${randomPage}&_fields=title,yoast_head_json`)
const knowledge = await res.json()
// Extract writer title and quote content material from response
const authorName = knowledge[0].title.rendered
const quoteContent = knowledge[0].yoast_head_json.og_description
window.mum or dad.postMessage({
pluginMessage: {
authorName,
quoteContent
}
}, ‘*’)
}
}
</script>
We’re leaving out error-handling to maintain this straightforward and to-the-point. Let’s bounce again into the widget code and see how we entry features outlined within the <iframe>:
operate fetchData() {
return new Promise<void>(resolve => {
figma.showUI(__html__, {seen: false})
figma.ui.postMessage({kind: ‘networkRequest’})
figma.ui.onmessage = async ({authorName, quoteContent}) => {
setAuthor(authorName)
setQuote(quoteContent)
resolve()
}
})
}
As you may see, we’re first telling Figma to show entry to our hidden <iframe> and to set off an occasion with the title “networkRequest”. We’re dealing with this occasion within the ui.html file by checking occasion.knowledge.pluginMessage.kind === ‘networkRequest’, after which posting knowledge again to the widget.
However nothing is going on but… We nonetheless haven’t known as the fetchData() operate. If we name it straight within the element operate, the next error happens within the console:
Can’t use showUI throughout widget rendering.
Figma is telling us to not name showUI straight within the operate physique… So, the place ought to we put it? The reply to that’s one new hook and one new operate: useEffect and waitForTask. You may have already got familiarity with useEffect in case you’re a React developer, however we’re gonna use it right here to fetch knowledge from the server when the widget element mounts.
const { useEffect, waitForTask } = widget;
operate QuotesWidget() {
useEffect(() => {
waitForTask(fetchData());
});
}
However it will lead to yet one more “error” the place our widget will hold re-rendering with a brand new quote, ceaselessly. This occurs as a result of useEffect, by definition, triggers once more at any time when the widget’s state modifications, nay once we name fetchData. And whereas there’s a method to solely name useEffect as soon as in React, it doesn’t work on Figma’s implementation. From Figma’s docs:
Due to How Widgets Run, useEffect ought to deal with being known as a number of occasions with the identical state.
Fortunately, there’s a easy workaround that we will reap the benefits of and name useEffect solely as soon as when the element first mounts, and it’s by checking whether or not or not the state’s values are nonetheless empty:
operate QuotesWidget() {
useEffect(() => {
if (!writer.size & !quote.size) {
waitForTask(fetchData());
}
});
}
You may run right into a scary “reminiscence entry out of bounds” error. It’s fairly widespread to see in plugin and widget growth. Simply restart Figma and it received’t be there anymore.
You might need observed that typically, the quote textual content incorporates bizarre characters.
These are Unicode characters and we should correctly format them in code:
<!– ui.html –>
<script>
window.onmessage = async (occasion) => {
// …
const quoteContent = decodeEntities(knowledge[0].yoast_head_json.og_description);
};
// <https://stackoverflow.com/a/9609450>
var decodeEntities = (operate () {
// this prevents any overhead from creating the article every time
var factor = doc.createElement(“div”);
operate decodeHTMLEntities(str) {
if (str && typeof str === “string”) “[^”]*”
return str;
}
return decodeHTMLEntities;
})();
</script>
And voilà, our widget fetched a model new design quote each single time it’s added to the design board.
Including a property menu to our widget
Whereas our widget fetches a recent quote upon instantiation, it might be way more sensible if we may do that course of once more however with out deleting it. This part shall be brief as the answer is sort of exceptional. With property menus, we will add interactivity to our widget with a single name to the usePropertyMenu hook.
Credit score: Figma Docs.
const { usePropertyMenu } = widget;
operate QuotesWidget() {
usePropertyMenu(
[
{
itemType: “action”,
propertyName: “generate”,
tooltip: “Generate”,
icon: `<svg width=”22″ height=”15″ viewBox=”0 0 22 15″ fill=”none” xmlns=”<http://www.w3.org/2000/svg>”>
<!– Shortened for brevity –>
</svg>`,
},
],
() => fetchData()
);
}
With one easy hook we’re capable of create a button that seems close to our widget when it’s chosen. That was the final piece that we wanted so as to add to be able to full this venture.
Publishing our widget to the general public
There’s not a lot use in constructing a widget if, effectively, nobody makes use of it. And whereas Figma grants organizations with the choice to launch personal widgets for inner use, it’s way more widespread to launch these little applications to the world.
Figma has a fragile widget assessment course of that will take up 5 to 10 enterprise days. And whereas the design quotes widget we constructed collectively is already within the widget library, I’ll nonetheless show the way it received there. Please don’t try and re-publish this widget once more as that may solely lead to removing. However in case you gave it some important alterations, go forward and share your personal widget with the neighborhood!
Get began by clicking the widgets menu (Shift+I) and switching to the Improvement tab to view our widget. Click on on the three-dots menu and press Publish.
Figma will immediate you to enter some particulars about your widget, comparable to a title, description, and a few tags. We’ll additionally want a 128×128 icon picture and a 1920×960 banner picture.
After importing all these property, we nonetheless want a screenshot of our widget. Shut the publishing modal (don’t fear, you received’t lose your knowledge) and right-click on the widget to disclose an attention-grabbing context menu. Discover the Copy/Paste asclass and choose Copy as PNG.
With that achieved, let’s return to the publishing modal and paste the widget’s screenshot:
Scroll down and at last publish your modal. Have a good time! 🎉
Figma will attain out to you in a few days in regards to the standing of your modal’s assessment. Within the case of a rejection, you’ll be given the alternative to make modifications and submit once more.
Conclusion
We simply constructed a Figma widget from scratch! There are a lot of issues not lined right here, comparable to click on occasions, enter varieties, and way more. You possibly can dig into the complete supply code for the widget in this GitHub repo.
To those that aspire to take their Figma expertise to larger ranges, I counsel exploring the Widgets neighborhood and utilizing what catches your eye as inspiration. Maintain constructing extra widgets, hold sharpening your React expertise, and earlier than you even notice it, you’ll be instructing me how one can do all this.
Additional sources
I needed to confer with a number of documentation whereas I used to be making this widget. I believed I’d share what I discovered to assist probably the most.
Construct extra widgets:
Greatest practices for constructing widgetsOfficial Figma widget examples, with code
Study widgets in larger depth:
All widget hooksAll widget elementsHow widgets run behind the scenes
Widgets vs. plugins
Widgets vs PluginsIntroduction to Figma PluginsHow plugins run behind the scenes
Constructing Interactive Figma Widgets initially printed on CSS-Tips, which is a part of the DigitalOcean household. You must get the publication.
Subscribe to MarketingSolution.
Receive web development discounts & web design tutorials.
Now! Lets GROW Together!