Integration Plugins

Integration plugins allow developers to hook into the Figma extraction pipeline with javascript.

Handoff allows users to integrate with particular frontend frameworks. We call these integrations. We currently support bootstrap 5.2 out of the box.

0.5.0 now allows these integrations to hook into the data extraction pipeline and modify the output, and optionally write files to the exported directory. This will allow developers to tailor the Figma data pipeline to their needs.

How to use the Integration Plugin

To use this feature, create a plugin.js in the integration folder of your project. This plugin will have access to any of the core node.js libraries you need. Export a sandbox module like this -

Integration Plugin
1sandbox.exports = { 2 postCssTransformer: (documentationObject, css) => { 3 // Modify the css variables prior to save 4 return css; 5 }, 6};

In this example, the plugin has the full documentation object available, allowing it to query the object and then modify the css variables as needed.

Simple example

Here's a simple plugin example that will read the tokens and write a simple json file with an array of colors in it.

1/** @type {import('handoff-app/client-config').Plugin} */ 2sandbox.exports = { 3 /** 4 * This is a simple example plugin that writes an additional json file to the exported directory 5 * with some simple color data in it. 6 * 7 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 8 * @returns HookReturn[] 9 */ 10 postIntegration: (documentationObject) => { 11 const colors = documentationObject.design.color.map((color) => ({ 12 name: color.name, 13 slug: `${color.group}-${color.machineName}`, 14 color: color.value, 15 })); 16 const data = JSON.stringify(theme, null, 2); 17 return [ 18 { 19 filename: "colors.json", 20 data, 21 }, 22 ]; 23 }, 24};

Full example

Here is a comprehensive plugin.js showing all the options in 0.5.0 -

A full plugin example
1// Core Node Libraries are allowed 2//var path = require("path"); 3//const fs = require("fs"); 4 5/** @type {import('handoff-app/client-config').Plugin} */ 6sandbox.exports = { 7 /** 8 * This fires when the pipeline starts and returns void 9 */ 10 init: () => {}, 11 /** 12 * This hook fires after the scss transformer and returns the scss object, 13 * allowing the plugin to modify the css output 14 * 15 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 16 * @param {import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput} css 17 * @returns import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput 18 */ 19 postCssTransformer: (documentationObject, css) => css, 20 /** 21 * This hook fires after the scss transformer and returns the scss object, 22 * allowing the plugin to modify the scss output 23 * 24 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 25 * @param {import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput} css 26 * @returns import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput 27 */ 28 postScssTransformer: (documentationObject, scss) => scss, 29 /** 30 * This hook fires after the scs type transformer and returns the types object, 31 * allowing the plugin to modify the types output 32 * 33 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 34 * @param {import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput} types 35 * @returns import("handoff-app/figma-exporter/src/transformers/css").CssTransformerOutput 36 */ 37 postTypesTransformer: (documentationObject, types) => types, 38 /** 39 * This fires after the figma extraction and returns void 40 * 41 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 42 * @returns void 43 */ 44 postExtract: (documentationObject) => {}, 45 /** 46 * This fires after the preview is generated and returns the preview object 47 * 48 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 49 * @param {import("handoff-app/figma-exporter/src/transformers/preview").TransformedPreviewComponents} previews 50 * @returns import("handoff-app/figma-exporter/src/transformers/preview").TransformedPreviewComponents 51 */ 52 postPreview: (documentationObject, previews) => previews, 53 /** 54 * This fires after the build is complete and returns void 55 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 56 * @param {import("handoff-app/figma-exporter/src/transformers/preview").TransformedPreviewComponents} previews 57 * @returns void 58 */ 59 postBuild: (documentationObject) => { 60 console.log("custom build hook"); 61 }, 62 /** 63 * This fires after the fonts is complete and returns an array of font names 64 * 65 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 66 * @param {string[]} customFonts 67 * @returns string[] 68 */ 69 postFont: (documentationObject, customFonts) => customFonts, 70 /** 71 * This allows you to modify the webpack config before it is used 72 * 73 * @param {Configuration} webpackConfig 74 * @returns Configuration 75 */ 76 modifyWebpackConfig: (webpackConfig) => { 77 return webpackConfig; 78 }, 79 80 /** 81 * This executes after the integration code is complete, and lets you modify 82 * the application with the fully formed integration in place. 83 * 84 * You can return an array of HookReturn objects to add additional files. 85 * The HookReturn is an object with the following properties: 86 * filename: string; // Relative to the root of your project 87 * data: string; // Data to write to that file 88 * 89 * @param {import("handoff-app/figma-exporter/src/types").DocumentationObject} documentationObject 90 * @returns HookReturn[] 91 */ 92 postIntegration: (documentationObject) => { 93 return []; 94 }, 95};