Skip to main content
Question

How to export assets via plugin api?

  • February 8, 2023
  • 6 replies
  • 1986 views

Iuri_Fazli

Hi to all, is it possible to export assets from figma like images, svg?. I need a zip archieve of this files. thanks!

6 replies

Gleb
  • Power Member
  • 4706 replies
  • February 8, 2023

Have you tried searching for existing solutions and plugins API documentation?


Josh_Kulpa
  • New Member
  • 3 replies
  • February 26, 2025
Gleb wrote:

Have you tried searching for existing solutions and plugins API documentation?

I certainly have, and I am no closer to determining how to make this work. What’s worse, is that the plugin API fails completely silently - I can’t even get it to throw errors with extensive error checking. 

Do you have any actual solutions, or are you just going to give another glib response?


tank666
  • 4854 replies
  • March 2, 2025

@Josh_Kulpa, what kind of help do you want? It's not clear from your description what you did. If you provide enough information, including the code you're using/wrote, you'll be more likely to get a concrete answer. And on topic, to export nodes use the exportAsync method, and to pack them into a ZIP archive you can use a library like JSZip.


Josh_Kulpa
  • New Member
  • 3 replies
  • March 5, 2025

 

tank666 wrote:

@Josh_Kulpa, what kind of help do you want? It's not clear from your description what you did. If you provide enough information, including the code you're using/wrote, you'll be more likely to get a concrete answer. And on topic, to export nodes use the exportAsync method, and to pack them into a ZIP archive you can use a library like JSZip.

 

I would like a functioning code example of how to export a frame as .svg and/or .pdf using the plugin API.

Currently, there is no such code example anywhere I can find - not the documentation, not in the community, and not anywhere else.

Here’s the code I put into my test plugin. Any help would be immensely appreciated:

 

const axios = require('axios')
const { performance } = require('perf_hooks')
const fs = require('fs')
const blobStream = require('blob-stream');
const PDFDocument = require('pdfkit')
const SVGtoPDF = require('svg-to-pdfkit');


let axiosInstance = axios.create({
    baseURL: "https://api.figma.com/v1/",
    headers: {
        "X-Figma-Token": process.env.ACCESS_TOKEN
    }
})

const pdfCreator = {
    async getFilePages(key) {
        let start = performance.now()
        let response = await axiosInstance.get(`files/${key}`)
        let end = performance.now()


        console.log(`Got file pages in ${end - start} ms`)

        return this.sortFrames(response.data.document.children[0].children
            .filter(layer => layer.type === "FRAME"))

    },
    sortFrames(pages) {
        let lines = []
        let sortedByHeight = pages.sort((a, b) => a.absoluteBoundingBox.y - b.absoluteBoundingBox.y)
        let finalArray = []
        for (let page in sortedByHeight) {
            let pageItem = sortedByHeight[page]
            let nextPageItem = sortedByHeight[parseInt(page) + 1]
            if (nextPageItem) {
                let seuil = pageItem.absoluteBoundingBox.height / 2

                if (Math.abs(nextPageItem.absoluteBoundingBox.y - pageItem.absoluteBoundingBox.y) <= seuil) {
                    if (lines.length == 0) {
                        lines.push(pageItem)
                    }
                    lines.push(nextPageItem)
                } else {
                    if (lines.length > 0) {
                        let index = sortedByHeight.findIndex((el) => { return el.id === lines[0].id })
                        let sortedLine = lines.sort((a, b) => a.absoluteBoundingBox.x - b.absoluteBoundingBox.x)
                        sortedByHeight.splice(index, lines.length)
                        sortedByHeight.splice(index, 0, ...lines);
                        lines = []
                    }
                }
            }
        }
        return sortedByHeight
    },
    async exportPages(pages, key) {
        let response = await axiosInstance.get(`images/${key}`, {
            params: {
                ids: pages.map(page => page.id).join(','),
                format: "svg"
            }
        })

        for (let page of pages) {
            page.imageUrl = response.data.images[page.id]
        }



        return "ok"
    },
    async getImagesContent(pages) {
        let start = performance.now()
        let imagesPromises = []
        for (let page of pages) {
            let imagePromise = this.getImageContent(page)
            imagesPromises.push(imagePromise)
        }
        await Promise.all(imagesPromises)
        let end = performance.now()
        console.log(`Got images content in ${end - start} ms `)
        return "ok"
    },
    async getImageContent(page) {
        let response = await axios.get(page.imageUrl)
        page.svgContent = response.data
        return "content"
    },
    async createPdf(pages, res) {
        const options = {
            assumePt: true
        }

        let doc = new PDFDocument({ compress: false, size: [pages[0].absoluteBoundingBox.width, pages[0].absoluteBoundingBox.height] })
        let stream = doc.pipe(res);
        SVGtoPDF(doc, pages[0].svgContent, 0, 0, options);
        pages.shift()
        for (let page of pages) {
            doc.addPage({ size: [page.absoluteBoundingBox.width, page.absoluteBoundingBox.height] })
            SVGtoPDF(doc, page.svgContent, 0, 0, options);
        }


        doc.end();
    }
}

module.exports = pdfCreator

 


tank666
  • 4854 replies
  • March 9, 2025

@Josh_Kulpa, are you sure you need to use the Plugin API? From the code you provided, I see that you used the REST API endpoints.

It's really weird that you didn't find any code examples for exporting nodes anywhere, because I found everything on GitHub. Here are some:


Josh_Kulpa
  • New Member
  • 3 replies
  • March 12, 2025
export interface ExportableBytes {
  name: string;
  setting: ExportSettingsImage | ExportSettingsPDF | ExportSettingsSVG;
  bytes: Uint8Array;
}

async function main(nodes): Promise<string> {
  if (!hasValidSelection(selection)) return Promise.resolve("Nothing selected for export")

  let exportableBytes: ExportableBytes[] = []
  for (let node of nodes) {
    let { name, exportSettings } = node
    if (exportSettings.length === 0) {
      exportSettings = [{ format: "PNG", suffix: '', constraint: { type: "SCALE", value: 1 }, contentsOnly: true }]
    }

> for (let node of nodes) {

> let {name, exportsettings } = node

Does this code mean that the export settings have to be provided by the user in the GUI, rather than setting them programatically? 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings