Breaking the code: How did we build our Figma plugin?
By: Sai Lakshman
Tags: Figma Plugin, Figma, UI, Development, UX

Co-authored by Manik Chugh and Sneh Singh. Illustrations by Aakansha Menon.

Writing UX copies can be a little frustrating and confusing, and sometimes we are unsure about how to get the right word. To crack the code for the UX copies, we at Zeta Design wanted to build a Figma plugin for the larger design community. The plugin is called the Ghost UXWriter and has a set of UX copies cataloged and categorized with a voice and tone variation ranging from plain, casual to playful. The intention to build this Figma plugin originated from our Medium blog post, ‘Designing voice and tone for error messages.’

This plugin can be used by designers, writers, and developers, making it a go-to plugin every time someone wants a hand with UX copywriting.

The journey of building our Figma plugin can be divided into three-phases — writing UX copies, designing the interface, and developing the plugin.This blog will focus on the third phase, the development phase, to unravel the pitfalls and the havens while developing a Figma plugin.

How does the plugin work?

Step 1: Download the plugin from Figma community, search Ghost UXWriter

Step 2: Open the plugin on your artboard

Step 3: Search for your copy or look through the different categories of the copies

Step 4: Select the type of error you are looking for. You will get three different copies for each error

Step 5: Tap on the cards to insert text in your frames

And you are all geared up to make your UX copies more fun and exciting 😎

Ghost UXWriter in action

Currently, in the Ghost UXWriter, we support the following features:

Plugin tutorial, onboarding screens

User login

Seamless Search Engine

Different UX categories with the variation of voice and tone ranging from plain, casual to playful

Easily Insert selected UX copy in artboard

Copy text to clipboard

User Profile

Bookmark favourite copies

Add custom copies as MyCopies

Discovering design

In the initial phase of design, we began with a low-fidelity wireframe to brainstorm the ideas from onboarding users to get them to use the plugin’s main features. Next, we converted them to high-fidelity screen-based designs, covering end-to-end plugin flows with monochromatic colors.

While designing for the Figma plugin frame, we had to solve for the scale of things. We had to create a small screen window that would fit into a large screen device. Our objective was to consume the minimum space of the designer’s artboard and give the majority of the area to their canvas. Hence, we settled onto a 360px width plugin window size and constrained our flows to that.

Ghost UXWriter’s design evolution

Picking the right color

Our initial plugin was designed in monochromatic color, and it was ready to ship. But, we felt the colors reflected an uptight formal-looking product, but that is not what Ghost UXWriter stood for.

The core of Ghost UXWriter lies in being a hospitable, lighthearted, and warm plugin. We restarted with rounds of iterating the color variations, starting from pastel, vibrant to even rich premium colors, we still couldn’t find the perfect color for our product personality. After trying different color sets, we started exploring the gradient’s territory, and then we had our hands on mesh gradients.

We found a perfect match to our product’s personality with that exploration, and without a doubt, we closed on that final iteration with Mesh gradients. The Mesh gradient impacted every product element, starting from updating the logo colors to the Figma community banners and all the promotional content.

And that’s how we closed our plugin designs with all our iterations and explorations. You can find some of the flows here.

Dismantling the code

Our development process

The Figma plugin development ecosystem was uncharted territory for us. On that account, we prepped ourselves with research on all documentation regarding the Figma plugin. It helped us explore the possibilities and limitations with Figma plugins, which would eventually help us build a full-fledged one.

The basic setup

After the deep-dive research, we started building the plugin with the help of Figma’s Setup guide. Following are the initial steps we took to set up the plugin:

Step 1: Install VSCode editor as suggested by Figma for writing code

Step 2: Install NodeJs, NPM package manager, TypeScript to set up a local javascript development environment necessary to build the plugin

Step 3: Install Figma desktop app as development and testing the plugin only happens in the desktop app

Step 4: Navigate to Profile Menu > Plugins > Development > … to browse the plugins

Step 5: Create a new plugin using one of the default templates, select “With UI & browser APIs” for full configuration or load an existing manifest.json file

Step 6: If the plugin is created for the first time, a prompt screen will appear to ‘Save’ the project

Step 7: Open the project folder with VSCode editor or in the terminal navigate to the project folder using “cd folder-path ” and type “code .” to open the project

Step 8: UI.html, Code.ts, and manifest.json are the files responsible for User interface, plugin logic & communication with Figma APIs, and configuration

If you’re using vanilla javascript to build the project, you’ll only have to work on these files. Alternatively, you can use Webpack module bundler, ReactJs, VueJs, or any other javascript UI framework/library to develop the plugin. These are advanced steps and require further configuration.

We relied on only two files, ui.html and code.ts for the complete project. This can get clumsy when you work on a complex plugin, if you want to break your project into multiple files or components, use a bundler/framework to write your code.

Bridging Google Sheet with code

After setting up the plugin, we went on to work on the Ghost UXWriter. Ghost UXWriter is a content-heavy plugin; therefore, to solve our technical and content-related bottlenecks, we followed a straightforward approach using Firebase for back-end and Google Sheets to host our content. We used vanilla Javascript to build most of our plugin, some TypeScript for working with Figma APIs, plain CSS & HTML for the markup, and inline SVG for media.

Connecting Google Sheets to Firebase

Our development journey started from the Google Sheet, where we first curated our content and later used Apps Script for Google Sheet to store this data in the Firebase’s Firestore NoSQL database. With Google Sheet now synced with the database, content updates happen more seamlessly.

In the initial plugin launch, we avoided overcomplicating the back-end dashboards, therefore Google Sheets became our primary content source and helped the team to actively collaborate on the content.

Jumping through the hoops of authentication

Google authentication in Ghost UXWriter

We wanted to implement a social sign-in for the plugin. There was a hurdle as the Figma plugin doesn’t allow developers to set browser cookies.

Plugins in Figma are loaded in iframe, giving away certain technical limitations. These limitations include the unavailability of browser APIs (majorly cookies and localStorage) to support authentication and analytics services. Therefore, for implementing a social sign-in, additional steps were required. Even though Figma provides figma.clientStorage API, as an alternative to native locaStorage API, it doesn’t suit well for our use case.

TLDR; Most of the authentication and analytics services that rely on browser cookies don’t work because of the Figma plugin development limitations.

To resolve this issue, we performed our authentication by opening a browser tab and sent the user data back to the plugin after a successful login.

Whenever a user clicks on the signup button in the plugin, we register a new reference in the Firestore database to listen for login status actively. A new screen opens up in the browser where authentication is carried out using Firebase auth, and once the authentication is successful, we send back user details to plugin UI. We use unique reference IDs to authenticate these requests between the plugin and browser interface.

These login URLs are also configured with additional restrictions, such as the link is for single use only, reloading the login page will fail the request, and URL with an unregistered reference ID will fail the login attempt. We used strict access rules for our Firestore database and suggested configuring them carefully when you are working with firebase. Below are a few valuable links for working with Firestore rules on your production website.

1. https://fireship.io/snippets/firestore-rules-recipes/

2. https://firebase.google.com/docs/reference/rules/rules.firestore

If you don’t want to depend on Firebase for any of your flows, you can refer to this article on implementing a custom authentication through your server.

The common constraints

Even though there are so many possibilities with Figma APIs for developing plugins, we also encountered few API limitations in our journey. In the Ghost UXWriter plugin, we weren’t able to replace text fields with mixed fonts. This is a Figma API limitation to replace text nodes with mixed types, and we had to notify users about this explicitly. So if you are planning on building a Figma Plugin DYOR (Do own your research) or join the Figma community Slack channel for any queries related to limitations of APIs.

Developmental hurdles and Figma platform limitations

Another major constraint we faced while developing the plugin was that we were unable to see code changes live in real-time. It made the experience quite time-consuming as we had to restart the plugin every time in order to check the output when there was a code change. Since the Figma plugins use web technologies, we built the initial screens and UI that doesn’t rely on Figma APIs using the browser by running a localhost server that watches the code for live changes. This saved us a ton of time in perfecting the plugin UI.

Furthermore, we were also finding it very difficult to debug the plugin for styling and code errors, but now that we have a browser interface, we could quickly check our CSS and rely on the browser’s dev tools for most of the debugging. Despite Figma providing a console and Developer VM option for debugging with Figma, it might look cluttered in the initial phases and is not easy to check styling and live reloads. There’s no other option but to use Developer VM when working with Figma APIs for your plugin. For more information on how plugins run inside Figma, refer here.

🎯 The road ahead

Ghost UXWriter is our first Figma plugin, and the journey to build something new was exhilarating and enthralling. Throughout the plugin development process, we preferred to use plain technologies. It made things more straightforward and easier to learn and understand how to build our first plugin. Currently, we are on the lookout for adding more new features and making UX copies more accessible and humane.

Do check out Ghost UXWriter and tell us how you feel about the plugin in the comments.