Skip to content

Importing icons from Figma

This function is part of import functions in Iconify Tools.

Function importFromFigma() imports SVG files from a Figma file.

It creates IconSet instance, which can be exported to various formats.

Requirements

To import Figma file, you need to have:

Limitations

Import function has few limitations on Figma document structure:

Icon must be one of the following Figma node types:

  • Frame
  • Component
  • Instance of a component

Parent layers can only be the following Figma node types:

  • Page (in some Figma documentation it is called Canvas)
  • Frame
  • Group

Icons cannot be:

  • Placed inside components or component instances
  • Shapes without frame or component container

Icons cannot contain:

  • Raster images
  • Text. Convert text to shapes

Usage

Function has the following parameter:

  • options, object. Options.

Function returns:

  • FigmaImportResult object on success.
  • "not_modified" string if file has not been modified since last run (can be returned only if ifModifiedSince option is set).

In case of error, import might throw an exception, which you can catch using try and catch.

Function is asynchronous. That means you need to handle it as Promise instance, usually by adding await before function call.

Options

Options object has many properties, most are not required.

Required options used in all parts of import process are:

Required option used when traversing document:

  • iconNameForNode, function. Callback that checks if node is an icon.

Required option used when generating icon set:

  • prefix, string. Prefix for imported icon set. It is used in IconSet instance when exporting to IconifyJSON.

Other options are split in several groups:

Cache options

These options are for caching data:

  • cacheDir, string. Directory where cache should be stored. Use it to avoid retrieving same files every time you run your script.
  • cacheAPITTL, string. TTL for API queries cache, in seconds. Used only if cacheDir is set, default value is 3 days.
  • cacheSVGTTL, string. TTL for SVG cache, in seconds. Used only if cacheDir is set, default value is 30 days.

If you are expecting to run your script more than once, it is a good idea to cache API responses to avoid retrieving the same data multiple times. Set cacheDir to a writable directory.

TTL options usually do not need changing from default values. Each SVG has unique link, so if icon changes, it will have new cache file, so TTL for icons can be high.

If you set cache options, also consider setting ifModifiedSince option to true. This will tell import function to retrieve shallow copy of document from Figma, bypassing cache, then comparing if document in Figma has been updated since last cache. If document has been updated, function will clear cache.

jsconst options = {
   // ... other options here
   cacheDir: 'cache/api',
   ifModifiedSince: true,
};

Options for retrieving Figma document

These options are used when retrieving document:

  • version, string. Document version. Set it to parse specific version of document.
  • ifModifiedSince, string|Date|true. If set, function will check if document has been updated.

ifModifiedSince

Option ifModifiedSince is used when you want to retrieve data only if icon set has been updated.

Value can be one of the following:

  • Last modification time as string. You can get it from lastModified property of parse result.
  • Last modification time as Date.
  • true. This is special value, it compares time to time stored in cached data (see cacheDir option above).

If Figma document has not been modified, function will return string "not_modified".

If option is not set, function cannot return "not_modified".

Options for finding icons in Figma document

Function cannot reliably detect which element is an icon and which is not.

These options tell function where to look for icons:

  • ids, string[]. Array of node IDs to check. Useful if you know your document structure and want to limit Figma API query to specific nodes.
  • depth, number. Depth of nodes tree to retrieve from API. See below.
  • pages, string[]. List of page names that should be checked for icons.
  • filterParentNode, function. Callback to filter parent nodes. Alternative to pages property, but also checks child nodes, such as frames and groups.
  • iconNameForNode, function. Required. Callback that checks if node is an icon.

depth

Option depth tells function how deep it should scan Figma document. Scanning large documents results in slow parsing, so it is recommended to set this option.

Value is number of layers to reach icons.

For example, if icons are placed directly on page without parent group, depth value is 2.

Figma tree depth: 2

If icons are placed using the following tree:

  • Page.
  • Container frame or group.
  • Icon frame or component or component instance.

Then depth value is 3.

Figma tree depth: 3

pages

Option pages tells function which pages of Figma document contain icons. Value is list of page titles.

Example:

jsconst options = {
   // ... other options here
   pages: ['Icons'],
};

If you set option pages, option filterParentNode is ignored.

filterParentNode

Option filterParentNode is a callback function that filters potential parent nodes.

If possible, it should be used to filter parent nodes, otherwise parser might unexpectedly find and export nodes that match icon, but are on wrong page, that you forgot about.

It is an alternative to pages option. This option is ignored if pages option is set.

Callback has the following parameters:

  • node, FigmaParentNodeData. Node to check.
  • document is Figma document structure, as returned by Figma API. TypeScript interface for document is limited because currently Figma does not provide typings for API responses.

Callback should return:

  • true if node is a valid parent node.
  • false if node should be ignored.

Callback can be asynchronous.

Example:

jsconst options = {
   // ... other options here

   // 3 levels: page 'Icons' -> frame 'Regular -> icon
   depth: 3,

   // Import icons only from 'Icons' -> 'Regular'
   filterParentNode: (nodes) => {
       switch (nodes.length) {
           case 1: {
               // Page: 'Icons'
               const node = nodes[0];
               return node.name === 'Icons';
           }

           case 2: {
               // Frame: 'Regular'
               const node = nodes[1];
               return node.name === 'Regular';
           }
       }
       return false;
   },
};

iconNameForNode

Option iconNameForNode is a callback that checks if node is an icon.

Function should return:

  • string icon name if icon should be exported from node. Name is used when adding icon to IconSet instance.
  • null if node is not a valid icon.

Callback parameters are:

  • node, FigmaImportNodeData. Information about node.
  • nodes is an object that contains number of nodes and list of nodes that callback has marked as icons.
  • document is Figma document structure, as returned by Figma API. TypeScript interface for document is limited because currently Figma does not provide typings for API responses.

Example of callback:

jsconst options = {
   // ... other options here
   iconNameForNode: (node) => {
       if (
           // Icons are stored after 2 parents: page -> container frame -> icon
           node.parents.length !== 2 ||
           // Icons use frames
           node.type !== 'FRAME' ||
           // Icon should be 32x32
           node.width !== 32 ||
           node.height !== 32
       ) {
           return null;
       }

       // Return node name as keyword for icon
       return node.name;
   },
};

Callback can be asynchronous.

Options for generating SVG

These options are identical to export settings when you export SVG from Figma:

  • includeID, boolean. Set to true to include id attributes for all SVG elements (disabled by default).
  • simplifyStroke, boolean. Simplifies inside/outside strokes and use stroke attribute if possible instead of <mask> (enabled by default).
  • useAbsoluteBounds, boolean. Use the full dimensions of the node regardless of whether or not it is cropped or the space around it is empty. Use this to export text nodes without cropping (disabled by default).

Options for importing icons

Function imports icons to IconSet instance. These options are for customising import:

  • prefix, string. Required. Prefix for icon set. It is used in IconSet instance when exporting to IconifyJSON.
  • beforeImportingIcon, function. Callback to call before importing each icon.
  • afterImportingIcon, function. Callback to call after importing each icon.

Callback functions are identical, the only difference is one is called before importing icon, another one is used after importing icons.

Callbacks have the following parameters:

  • item, FigmaIconNode. Item that is about to be imported or was imported. In beforeImportingIcon callback you can change its contents.
  • iconSet, IconSet. Icon set instance.

Callbacks don't need to return anything.

Callbacks can be asynchronous.

Example

The following example imports simple icon set from Figma, where all icons have color "#2e4454", then replaces color with "currentColor".

example.ts
tsimport { importFromFigma, parseColors } from '@iconify/tools';

/**
* Important: set 'token' option before running this code. Token is mandatory.
*
* You can get your API token from Figma account page. Do not share your API token with anyone!
*/


// Cache directory. Used to avoid retrieving same files multiple times.
const cacheDir = 'cache/quill';

(async () => {
   const result = await importFromFigma({
       // Icon set prefix, used for creating icon set instance.
       prefix: 'quill',

       // Community link: https://www.figma.com/community/file/1034432054377533052/Quill-Iconset
       // Community link does not have document ID and cannot be used. To parse a community file,
       // either copy link from file (if you are author) or duplicate it.

       // Figma document. Get document id by clicking "Share" button when editing it,
       // click "Copy link" and get id from link.
       file: '9lvc7JGhqpNnpF3OK9kjnG',

       // Figma API token. You can get it from your Figma account settings.
       token: '', // process.env.FIGMA_API_TOKEN,

       // If enabled, will stop import process if Figma document has not been updated since last parse.
       // ifModifiedSince: true,

       // Directory for cache
       cacheDir,

       // Depth of layers tree where icons are located.
       // 2 = page -> icon
       // 3 = page -> frame/group -> icon
       depth: 3,

       // Function to filter parent layers. Used to avoid scanning pages and nodes
       // that do not contain icons for export.
       filterParentNode: (nodes) => {
           switch (nodes.length) {
               case 1: {
                   // Page: 'Icons'
                   const node = nodes[0];
                   return node.name === 'Icons';
               }

               case 2: {
                   // Frame: 'Regular'
                   const node = nodes[1];
                   return node.name === 'Regular';
               }
           }
           return false;
       },

       // Check if node is an icon. Returns icon name on success, null on failure.
       iconNameForNode: (node) => {
           if (
               // Icons are stored after 2 parents: page -> container frame -> icon
               node.parents.length !== 2 ||
               // Icons use frames
               node.type !== 'FRAME' ||
               // Icon should be 32x32
               node.width !== 32 ||
               node.height !== 32
           ) {
               return null;
           }

           // Return node name as keyword for icon
           return node.name;
       },
   });

   /*
   // 'not_modified' can be returned only if 'ifModifiedSince' option was set, so uncomment ifModifiedSince option
   // and this code, otherwise TypeScript will complain that result cannot be 'not_modified'
   if (result === 'not_modified') {
       // This result is possible if ifModifiedSince option is set
       console.log('Not modified');
       return;
   }
   */


   const iconSet = result.iconSet;

   // Check colors in icons
   iconSet.forEachSync((name) => {
       const svg = iconSet.toSVG(name);
       if (!svg) {
           return;
       }

       parseColors(svg, {
           // Change default color to 'currentColor'
           defaultColor: 'currentColor',

           // Callback to parse each color
           callback: (attr, colorStr) => {
               switch (colorStr.toLowerCase()) {
                   case '#2e4454':
                       // Change to currentColor
                       return 'currentColor';

                   case 'none':
                       return colorStr;
               }

               // Should not happen
               console.error(`Unexpected ${attr} "${colorStr}" in ${name}`);
               return colorStr;
           },
       });

       // Update icon in icon set
       iconSet.fromSVG(name, svg);
   });

   // Export icon set in IconifyJSON format
   console.log(iconSet.export());
   console.log('Found', iconSet.count(), 'icons');
})();

Released under the Apache 2.0 License.