PDF Server (for Figma templates) STEP 1
Tags: nextjs, figma, chakra, reactpdf
Published: 2020-12-31 13:55:06

---
title: PDF Server (for Figma templates) STEP 1
published: true
description: Next.js app to fill figma PDF designs with custom data
tags: nextjs, figma, chakra, reactpdf
series: ["pdf-server-for-figma-templates"]
---

# Idea

I'm building a SaaS for a client and one part of a critical functionality is the ability to export dynamic reports with all kinds of data in PDFs.
Currently the layouts and styles for PDFs are hardcoded in code and any updates need code changes. But what if a designer could just edit a template in Figma, test it out and voilà the new design is applied in production as well without any code changes.

## How

Using [Next.js](https://nextjs.org/) and [React-PDF](https://react-pdf.org/) to preview / stream the PDF template based on defined properties onto [Figma](https://www.figma.com/) template files

Probably need to implement some definitions to allow automatically repeated components, calculated/dynamic content, custom fonts etc but let's keep it simple for now.

## Let's start up the project

I decided to generate a new boilerplate next.js project using the typescript + chakra example. We can use [Chakra](https://chakra-ui.com/) for any of the UI elements.

```sh
npx create-next-app --example with-chakra-ui-typescript pdf-server
```

## Architecture

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ikrwyerjyv1hrh47b3zr.png)

As you can see we need to install figma-js and react-pdf and start integrating these 2 together to create an api endpoint.

```sh
yarn add @react-pdf/renderer figma-js figma-transformer
```
figma-transformer helps us process the response from figma api by creating .shortcuts in every layer/type.

## utils/getFigmaFile.ts

This allows us to query all the frames in a figma template and their children and properties. Implementing a number of env vars helps us to customize the server depending on the use case. MAX_VECTORS tries to help safeguard the server from loading way too large figma files with vectors which could lead to memory/crash issues.

```js
import * as Figma from 'figma-js'
import { processFile } from 'figma-transformer'

const client = Figma.Client({
  personalAccessToken: process.env.FIGMA_TOKEN
})

export const DEFAULT_FILE = process.env.DEFAULT_FILE || `w4qFtzyCX2fYT3x6CQDFQF`
export const MAX_VECTORS = process.env.MAX_VECTORS || 100
export const ALLOWED_FILES = process.env.NEXT_PUBLIC_ALLOWED_FILES as string
export const allowedFiles = ALLOWED_FILES.length ? ALLOWED_FILES?.split(',') : []

type FigmaOptions = {
  geometry?: 'paths' | ''
}

export const getFigmaFile = async (fileId: string, options?: FigmaOptions) => {
  if (allowedFiles.length && !allowedFiles.includes(fileId)) {
    throw new Error('This file id is not allowed by the server env ALLOWED_FILES')
  }
  const figmaFile = await client.file(fileId, options ?? {
    geometry: 'paths'
  }).then(({ data }) => data )
  console.log('figma children: ', figmaFile.document.children.length)
  const file = processFile(figmaFile)
  console.log('figma processed vectors length: ', file.shortcuts.vectors?.length)
  if (file.shortcuts.vectors && file.shortcuts.vectors.length > MAX_VECTORS) {
    throw new Error('Too many vectors in template')
  }
  return file
}

```

Now we need to start mapping the file response elements into a react-pdf document.

Continue to part 2