Skip to main content
Question

Help Needed: Replicating Selected Figma Element in Frontend

  • November 27, 2024
  • 5 replies
  • 62 views

Eric_S

Hi everyone,

I’m working on replicating Figma elements in a React frontend. The goal is to replicate the exact position, size, and style of the selected element in Figma, using the data sent by the Figma plugin.

What I’ve Done

  • I’m receiving the data from the Figma then try to send it to frontend.
    const selection = figma.currentPage.selection;
    figma.ui.postMessage({ type: "selection-changed", selection});
  • In frontend, try to render with that data.
 useEffect(() => {
    window.onmessage = (event) => {
      const { type, selection} = event.data.pluginMessage;

      if (type === "selection-changed" && selection) {
        setElements(selection);
      }
    };

    return () => {
      window.onmessage = null;
    };
  }, []);

return (
    <div className="work-board">
      <div className="main-board">
        <div className="drop-board">
          {elements.length === 0 ? (
            <p>Select a frame or two to get started</p>
          ) : (
            elements.map((element) => renderVisualElement(element))
          )}
        </div>
...

But that is not rendering.

How can I fix this so that the selected Figma elements render exactly as they appear in Figma?

This topic has been closed for replies.

5 replies

tank666
  • 4873 replies
  • November 27, 2024

How are you trying to render the array of objects you receive in the UI?

figma.com

Eric_S
  • Author
  • 2 replies
  • November 27, 2024

I can implement this by exporting the element using the Figma API. However, the requirement is that we should be able to edit the design without affecting the Figma file. So, I need the data of the selected element in order to replicate it on the frontend and edit it there.

I tried the code below in the Figma plugin, but I’m still encountering an issue. Is there a way to retrieve the data and replicate it? Also, for images, is it possible to get the image URL or the raw data?

const selection = figma.currentPage.selection;

    const serializedSelection = await Promise.all(
      selection.map(async (node) => {
        const element: any = {
          id: node.id,
          name: node.name,
          type: node.type,
          x: node.x,
          y: node.y,
          width: node.width,
          height: node.height,
          visible: node.visible,
          rotation:
            node.type === "FRAME" || node.type === "GROUP"
              ? (node as FrameNode | GroupNode).rotation
              : undefined,
          opacity: "opacity" in node ? node.opacity : undefined,
        };

        // Handle TEXT node properties
        if (node.type === "TEXT") {
          element.characters = (node as TextNode).characters;
          element.fontSize = (node as TextNode).fontSize;
          element.fontName = (node as TextNode).fontName;
          element.textAlignHorizontal = (node as TextNode).textAlignHorizontal;
          element.textAlignVertical = (node as TextNode).textAlignVertical;
          element.lineHeight = (node as TextNode).lineHeight;
          element.letterSpacing = (node as TextNode).letterSpacing;
          element.fills = (node as TextNode).fills;
        }

        // Handle RECTANGLE (and other shapes) node properties
        if (node.type === "RECTANGLE") {
          element.fills = (node as RectangleNode).fills;
          element.strokes = (node as RectangleNode).strokes;
          element.strokeWeight = (node as RectangleNode).strokeWeight;
          element.strokeAlign = (node as RectangleNode).strokeAlign;
          element.cornerRadius =
            "cornerRadius" in node ? (node as RectangleNode).cornerRadius : 0;
          element.dashPattern = (node as RectangleNode).dashPattern;

          // Handle IMAGE fill if available
          const fills = (node as RectangleNode).fills;
          if (Array.isArray(fills) && fills.length > 0) {
            const imageFill = fills.find((fill) => fill.type === "IMAGE");
            if (imageFill) {
              const image = figma.getImageByHash(imageFill.imageHash);

...

tank666
  • 4873 replies
  • November 27, 2024

If you got all the required properties of the object and wrote a function to convert it to React elements, then everything should be fine.

As for the code snippet you provided, I would get all the properties using a recursive function using loops.

You can get the URLs of the images using the REST API. The raw data can be obtained using the exportAsync function I mentioned above.


Eric_S
  • Author
  • 2 replies
  • November 28, 2024

To use Figma API, I need fileId, right?
But, in Figma plugin, how can I get fileId?
figma.fileKey is returning undefined.


tank666
  • 4873 replies
  • November 29, 2024

If you mean REST API, then yes, some endpoints require a file key, including the GET image and GET image fills endpoints. But if you want to get JSON of the object, you can use exportAsync function from Plugin API.