---
title: 'Figma as a CMS: where design and development collide'
description: >-
  Although Figma is mostly used by designers, we tried using it in the
  development process, by transforming Figma into a CMS. Read our blogpost.
language: Dutch
url: >-
  https://www.voorhoede.nl/nl/blog/figma-as-a-cms-where-design-and-development-collide/
---

Blog

# Figma as a CMS; where design and development collide

Door [Bas ](/nl/team/basdegreeuw.md)[Friso](/nl/team/friso.md)

10 February 2022

## Categorieën

* [Headless CMS](/nl/blog/tag/headless-cms.md)

- [Hoe willen wij Figma gebruiken?](#hoe-willen-wij-figma-gebruiken-)
- [Hoe gaan we van Figma als ontwerptool naar een CMS?](#hoe-gaan-we-van-figma-als-ontwerptool-naar-een-cms-)
- [Waarom het werkt](#waarom-het-werkt)
- [Gebruik van de API](#gebruik-van-de-api)

Hoewel Figma voornamelijk door ontwerpers wordt gebruikt, hebben wij geprobeerd het te integreren in het ontwikkelingsproces door Figma om te zetten in een CMS.

Het beheren van grafische middelen in een groot project kan tijdrovend en kostbaar zijn, wat veel opslagruimte en tijd vergt. Het webgebaseerde ontwerptool Figma biedt een geweldige oplossing, mits we hun API op een slimme manier gebruiken.

Vorig jaar zag softwareontwerpbedrijf Figma zijn waardering vervijfvoudigen (!) tot $10 miljard. Hoewel dit hulpmiddel voornamelijk door ontwerpers wordt gebruikt, hebben wij geprobeerd Figma te gebruiken in het ontwikkelingsproces van onze oplossingen. Wij hebben Figma gebruikt als een visueel CMS voor onze eigen applicaties. Hieronder vind je een gids over hoe je dit kunt doen.

Voordat we dieper ingaan op de technische details, laten we beginnen met het interpreteren van de explosieve waardestijging van Figma. Waarom zou je het gebruiken?

* Naarmate Figma groeit in de industrie, is het het ontwerptool die we het vaakst zien bij het ontvangen van visueel en/of interactieontwerp en in termen van iconenbibliotheekbeheer.
* Omdat het gratis is en snel te gebruiken, omdat het cloudgebaseerd is en beschikbaar vanaf elk apparaat of locatie.
* Figma heeft een uitgebreide API die alles dekt, van CRUD-acties op bestanden tot webhooks om op de hoogte te worden gesteld van bijgewerkte bestanden.
* Figma vergemakkelijkt de overdracht van ontwerper naar ontwikkelaar.

## Hoe willen wij Figma gebruiken?

Hoe beheer je visuele middelen in een groeiend webproject? De overdracht tussen ontwerper en ontwikkelaar kan behoorlijk schokkend zijn, vooral met derden die ertussen komen. Tegenwoordig worden de meeste van deze middelen opgeslagen in een contentmanagementsysteem (CMS), wat het bewerken en publiceren van grafische middelen super eenvoudig maakt. Een CMS stelt je doorgaans in staat om tekstgebaseerde inhoud te beheren en mediabestanden te koppelen. Maar recentelijk hadden we onze redacteuren nodig om complexe grafische elementen te beheren. Onze oplossing: **Figma als [headless CMS](https://www.voorhoede.nl/nl/services/headless-cms.md "service pagina headless cms")**.

Bekijk de video hieronder om te zien wat we hiermee bedoelen. Het ontwerp in Figma wordt aangepast en binnen enkele seconden wordt dit nieuwe ontwerp op de hele website weergegeven, zonder elke pagina afzonderlijk te hoeven wijzigen. Op deze manier hebben we Figma omgevormd tot een CMS.

## Hoe gaan we van Figma als ontwerptool naar een CMS?

Zonder in detail te treden over hoe je je projecten moet structureren en welke technologieën je moet gebruiken, heb ik geprobeerd enkele algemene gebruikscases te demonstreren in een eenvoudig project. Laat me je dat eerst laten zien.

[video afspelen](https://vimeo.com/665999956)

[Figma as a CMS Image Demo](https://vimeo.com/665999956)

Laten we stap voor stap door de gebeurtenissen in de video lopen:

* Een Figma-object wordt bewerkt door vormen te verplaatsen en opnieuw te kleuren;
* Een nieuwe bestandversie wordt vrijgegeven. De webhook-trigger wordt ingesteld op 'bestandsversie-update', zodat werk in uitvoering niet wordt gepubliceerd. Zie dit als de "publiceer" knop in je CMS.
* Wacht totdat de server een verzoek van de webhook ontvangt en een build-script uitvoert; en
* Zie de wijzigingen in de browser.

## Waarom het werkt

De Figma HTTP API heeft een export-eindpunt dat tijdelijk een geëxporteerde bron opslaat in hun cloudopslag (een AWS S3-bucket op het moment van schrijven). We kunnen deze tijdelijke opslag gebruiken tijdens ons buildproces om nieuwe grafische middelen bij elke build op te halen en op te slaan in de build-cache, of zelfs een bronnen-cache van cloudopslaglinks beheren die periodiek worden bijgewerkt. Door de nieuwe webhooks van Figma kunnen we deze builds zelfs op bepaalde gebeurtenissen activeren, en het `'FILE_VERSION_UPDATE'`-evenement is perfect hiervoor. Het wordt geactiveerd elke keer dat een nieuwe 'versie' wordt vrijgegeven, waardoor je volledige controle hebt over wat en wanneer wordt bijgewerkt.

We hadden dit in gedachten voor een project dat veel verschillende visuele componenten vereiste, beheerd door verschillende mensen op verschillende locaties. En het werkte perfect met Figma en zijn API. Het voorbeeld is vrij eenvoudig, met een enkele illustratie, maar stel je bijvoorbeeld het beheren van kaarten van binnenruimtes voor.

In deze opzet worden Figma-bestanden tijdens de build gemapt naar een statische map, volgens de naamgeving die in Figma wordt gebruikt.

![Een screenshot van Figma die de map van de illustraties op de voorpagina toont](https://www.datocms-assets.com/6524/1642356069-figma1.png)

Je kunt al zien dat de andere Figma-bestanden verschijnen in mijn bestandstructuur, iconen. Natuurlijk is het beheren van een iconenbibliotheek in Figma en publiceren bij elke nieuwe release ook een zeer nuttige manier om hun API te benutten. Opnieuw zie je de beschikbare gegevens gemapt naar de export.

![Een screenshot van figma met icons mappen](https://www.datocms-assets.com/6524/1642356105-figma2.png)

We kunnen deze SVG's gebruiken om een iconen-spritesheet voor onze applicatie te bouwen, wat er ongeveer zo uit zou kunnen zien:

[video afspelen](https://vimeo.com/666000349)

[Figma as a CMS Icon Demo](https://vimeo.com/666000349)

## Gebruik van de API

Voor de eerder genoemde voorbeelden heb ik een functie gebouwd die SVG's exporteert op basis van zogenaamde `filekey`'s die Figma gebruikt. Het aanroepen van hun`/files` eindpunt als volgt:

*Let op, er is geen bestandversie in dit verzoek gespecificeerd. De nieuwste bestandversies moeten op je serverimplementatie worden beheerd om ervoor te zorgen dat build-triggers anders dan Figma de versie-uitgaveflow van de grafische middelen niet onderbreken.*

```
function getResourcesByFileKey(fileKey, fileName = 'icons') {
    return fetch(`${FIGMA_BASE}/v1/files/${fileKey}?depth=2`, {
        headers: {
            'x-figma-token': X_FIGMA_TOKEN
        }
    }) // Fetches the file object by the fileKey
        .then(res => res.json())
        .then(res => res.document.children.map((child, i) => ({ // Create an array of the top-level frames
            page: child.name,
            nodes: child.children.map(child => ({
                name: child.name,
                id: child.id
            })),
            ...child
        })))
        .then(items => items.map(({page, nodes}) => [ // Use the node ID's of these frames to export them
            fsPromises.mkdir( // First ensure the folder to save it to
                path.resolve(
                    __dirname,
                    `../dist/${fileName}/${page}`),
                {recursive: true}
            ),
            nodes.map(
                node =>
                    fetch(`${FIGMA_BASE}/v1/images/${fileKey}?ids=${node.id}&format=svg&svg_include_id=true`,
                        {
                            headers: {
                                'x-figma-token': X_FIGMA_TOKEN
                            }
                        }) // Fetch every node
                        .then(res => res.json())
                        .then(res => res.images[node.id])
                        .then(async (resource) => {
                            console.log(`🦴Fetching '/${fileName}/${page}/${node.name}.svg'`)
                            return await fetch(resource).then(res => res.text())
                        })
                        .then(data => // Return a promise for the file writes
                            fsPromises.writeFile(
                                path.resolve(
                                    __dirname,
                                    `../dist/${fileName}/${page}/${node.name}.svg`),
                                data.replace(/fill=".*?"/, ''),
                                err => {
                                    if (err) {
                                        console.error(err)
                                    }
                                })
                        )
            )]))
}
```

We eindigen met een array die de pagina's en hun top-level nodes bevat voor het bestand dat we hebben opgegeven. De naam van de top-level node, meestal een frame in Figma, zal de bestandsnaam zijn. `Superheroes.svg` in ons voorbeeld. We kunnen vervolgens door de array lopen en SVG-resources ophalen van hun `/images`endpoint en deze opslaan op ons bestandssysteem.

Met behulp van het `/projects` endpoint kunnen we alle bestanden binnen een project opvragen (bijvoorbeeld een project genaamd “CMS”) en vervolgens `getResourceByFileKey()` aanroepen voor elk bestand dat we in ons project vinden.

```
async function getResourcesFromFigma() {
        const figmaFiles = await fetch(`${FIGMA_BASE}/v1/projects/${FIGMA_PROJECT}/files`, {
            headers: {
                'x-figma-token': X_FIGMA_TOKEN
            }
        })
            .then(res => res.json())
            .then(json => json.files)
        await Promise.all(figmaFiles.map(({key, name}) => module.exports.getResourcesByFileKey(key, name)).flat())
    }
```

Om alle gebeurtenissen met elkaar te verbinden, gebruiken we de nieuwe webhooks van Figma. We registreren een nieuwe webhook bij het opstarten van de server:

```
fetch(`${FIGMA_BASE}/v2/webhooks?team_id=${FIGMA_TEAM}&endpoint=${ENDPOINT}/figma/file_update&passcode=${passcode}&event_type=FILE_VERSION_UPDATE`)
```

Figma zal nu POST'en naar het endpoint dat je hebt opgegeven in het verzoek met de bijbehorende fileKey voor de bijgewerkte bestandversie. We kunnen vervolgens de eerder genoemde functie opnieuw aanroepen met de geleverde fileKey (ik gebruik een eenvoudige Fastify node-server in dit voorbeeld):

```
fastify.post('/file_update', async (request, reply) => {
    if (request.body.passcode === passcode) {
        reply.code(200)
        const {file_name, file_key, timestamp} = request.body
        console.log(file_name, file_key, timestamp)
        if(file_name && file_key && timestamp) {
            await getResourcesByFileKey(file_key, file_name)
        }
    } else reply.code(403)
    reply.send()
})
```

*Let op dat ik geen foutafhandeling heb uitgevoerd; deze code is lang als voorbeeld. **Overweeg je eigen implementatie!***

## Gerelateerde blog posts

* ### [Headless CMS'en gaan de strijd aan: Strapi vs DatoCMS](/nl/blog/headless-cmsen-strapi-vs-datocms.md)
  4 Aug 2023

  Door Remco
* ### [Dropbox Paper als een headless CMS](/nl/blog/dropbox-paper-als-headless-cms.md)
  25 Jan 2019

  Door Jasper
* 19 Nov 2021

  Door Jasper

[← Alle blogposts](/nl/blog.md)

[Terug naar boven](#top)
