My App

Parser

Parse Figma API data to JsonForms schemas

Introduction

The Figma Forms Parser is a tool that converts Figma API data into an extended version of the JsonForms schema. This allows users to design forms visually in Figma, then integrate them seamlessly into their applications using the Figma Forms Renderer components.

Installation

npm i @uj-vilag/figma-forms-parser

Prerequisites

Design your form

Design your form in Figma using the template.

Generate Figma API token

Follow the instructions here to generate a personal access token. Only the file_content:read scope is required.

Get Figma file key & node ID

Open your Figma file, select the section containing your form, and copy the file key and node ID from the URL. The URL format is: https://www.figma.com/design/{fileKey}/your-project?node-id={nodeId}

Fetch the file data

Call the Figma API's /files/{fileKey}/nodes endpoint to get the file data: https://api.figma.com/v1/files/{fileKey}/nodes?ids={nodeId}
Make sure to include your personal access token in the X-Figma-Token header.

Figma API reference

API call example

callFigmaApi.ts
import type { GetFileNodesResponse } from "@figma/rest-api-spec";

export async function callFigmaApi(
  nodeId: string
): Promise<GetFileNodesResponse> {
  const token = env.FIGMA_TOKEN; // Saved in environment variables
  const fileKey = env.FIGMA_FILE_KEY; // Saved in environment variables

  if (!token || !fileKey || !nodeId) {
    throw new Error(
      "Missing FIGMA_TOKEN, FIGMA_FILE_KEY or FORM_NODE_ID in environment"
    );
  }

  const url = `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${nodeId}`;

  let response: Response;
  try {
    response = await fetch(url, {
      headers: {
        "X-Figma-Token": token,
      },
    });
  } catch (err) {
    throw new Error(`Failed to fetch Figma API: ${(err as Error).message}`);
  }

  if (!response.ok) {
    throw new Error(
      `Figma API error: ${response.status} ${response.statusText}`
    );
  }

  const figmaResponse = (await response.json()) as GetFileNodesResponse;
  return figmaResponse;
}

Use the GetFileNodesResponse type from @figma/rest-api-spec to type the response. This package is installed alongside the parser.

Usage

The package exports two main functions:

  • getSectionNode: Extracts the relevant section node from the Figma API response.
  • parseFigmaForm: Parses the section node into a JsonForm object. Pass { includeFieldsetStyles: true } as the second argument to keep the fieldset styles inherited from Figma (omitted by default).
  • collectFormKeys: Lists every key that ends up in the form state, with its element type, page, label, parent control and selectable option ids. Run it after resolveIdentifiers to get the identifier-based keys. Pass { keysOnly: true } to get a plain array of keys instead.
getFigmaForm.ts
import { parseFigmaForm, getSectionNode } from "@uj-vilag/figma-forms-parser";
import type { JsonForm } from "@uj-vilag/figma-forms-types";
import type { GetFileNodesResponse } from "@figma/rest-api-spec";

export async function getFigmaForm(): Promise<JsonForm> {
  const formNodeId = env.FORM_NODE_ID; // Saved in environment variables
  const nodeId = formNodeId.replace("-", ":");
  let figmaResponse: GetFileNodesResponse;
  try {
    figmaResponse = await callFigmaApi(nodeId);
  } catch (err) {
    throw new Error(`Invalid JSON from Figma API: ${(err as Error).message}`);
  }

  const formSection = getSectionNode(figmaResponse, nodeId);
  const form = parseFigmaForm(formSection);
  return form;
}

The nodeId in the Figma file URL uses a dash (-), but the API and the response requires a colon (:). Replace the dash with a colon before calling the API.

Done!

The JsonForm object is now generated and is ready to be used with the Figma Forms Renderer components! You can save it to your database or use it directly in your application and get real-time updates when you change the design in Figma.

Recommendations

Copying and pasting the node ID from the Figma URL is the simplest way to get started, but using the Figma API to get them programmatically is a better approach in an automated workflow.

Consider using the Figma API's /files/{fileKey} endpoint with the depth query parameter to list only the first few levels of the file structure. This way you can find the node IDs of all your forms without manually opening each one in Figma.

Figma API reference

On this page