Milton Figma HTML Export Plugin
In the fast-paced environment of the newsroom, it is important that changes are made quickly. Amendments to text, map updates, and new data figures can all be handled within the CMS. However, amendments to custom HTML embeds require developer involvement, which can slow down the process and prevent the creation of custom embeds altogether.
Telegraph Product team wanted to give designers the ability to create their own graphical embeds, without the need for developers. They were looking for a tool that would fit into their existing workflow and would export HTML that could be easily inserted into the site’s CMS.
I began by examining existing solutions, the main one being AI2HTML.
AI2HTML is a plugin for Adobe Illustrator that exports art boards into HTML, but the workflow didn’t fit our needs exactly.
Firstly, AI2HTML was for Illustrator only and the designers used Figma. Second, our content management system did not support embedding external files, so any images or static assets would need to be baked into the exported HTML.
I needed a solution that would fit into the designer’s existing workflow, which meant Figma.
Like Illustrator, Figma has art boards in the form of Frames. Designers already used frames to represent different browser breakpoints. I could take these frames and export them to create a single embed that would responsively scale to the browser’s width.
The key breakthrough was the idea of merging each exported frame’s SVG into a single master SVG. The advantage of this was that common assets, for instance, the largest shared image, could be de-duplicated. CSS media queries could be used to selectively choose which frame to display based on the width of the viewport.
I was aware that Figma had a Plugin API, and I set out to learn what it was capable of. I soon realized that we could create a plugin that met all our requirements.
Figma’s plug-ins are separated into two parts, a backend with access to internal APIs and a frontend responsible for the user interface. Messages are passed between these two halves via the postMessage API. For simple tasks, this method worked well, but it soon proved to be a hindrance. So, I wrote a small helper called postman, which acted as an asynchronous message bus and allowed me to keep the UI state updated while waiting for some of the more long-running backend API calls to finish.
While developing, however, I encountered a rather larger challenge: the recreation of complex text formatting into HTML. To prevent text scaling and improve accessibility, all text elements in the SVG needed to be replaced with HTML. At the time, Figma’s API did not offer a convenient way to extract the styles applied to text elements. A designer could change the colour, font, size of individual letters within a text element, however, the API only supported accessing those styles on a per-character basis.
It was necessary to loop over each character, building up a map of what styles were applied to what character. Then I could use the map to recreate the styles using HTML and CSS.
Another challenge was the export of images. High-resolution images were commonly used by designers, who would shrink them down visually to a fraction of their original size. However, Figma exports SVG embedded images in their original size. This is great for print, not so good for web performance. I needed a way to resize and optimize images for the web, both in terms of size and quality.
I achieved image optimization using the following steps:
- Determine the image format
- Find the largest dimension of all SVG elements using the image
- Check if the image is larger than the largest element, if so…
- Scale down the image to the size of the largest element
- Optimize the image format:
- For JPEGs, set the quality to 75
- Quantize GIFs and PNGs into 175 index colour versions
With image tweaking and other changes, the final file size was small enough to be embedded into the CMS.
Designer’s loved the plugin. It enabled them to focus on their work without constant back and forth with developers to make changes. It also had the added benefit of keeping a link between the embed and original design. Each export contained the URL of the Figma document. Now any future designer can directly go to the original document, make a change, and re-export the HTML.