Anvil Logo
Products
Industries
Resources
Developers
Engineering

Using React and styled-components to generate PDFs

Ben Ogle
By Ben Ogle
Updated August 12, 2021

Learn how to generate custom-styled PDFs using React + styled-components. Extend the approach here to use any technologies that generate vanilla HTML and CSS.

Back to all articles
Post hero image

Anvil's PDF generation API endpoint supports generating PDFs from HTML and CSS. For the sake of simplicity and interoperability, the endpoint only accepts vanilla HTML & CSS. Obviously writing vanilla HTML & CSS is painful and far out of fashion.

Modern technologies like React, Vue, LESS, SASS, styled-components, etc. allow you to write more modular, reusable code. Fortunately these technologies all compile down to vanilla HTML and CSS.

So, while the endpoint accepts only vanilla HTML and CSS, you can use any technologies you'd like to generate the HTML and CSS then send it to the API. For example, you can use the aforementioned libraries like React and Vue, or even your crazy homegrown template language. As long as a library can generate HTML and CSS strings, you can use it with the API!

In this post, I'll show you how to use React and styled-components in Node to create several PDFs, then ultimately an invoice PDF.

The gist of the post is: use the React and styled-components libraries to generate vanilla HTML + CSS strings, then send those strings to the API. Let's get started.

Set up the scaffolding

The first thing we'll do is set up a quick node script to generate a PDF from plain HTML and CSS. We'll use vanilla HTML and CSS strings at first, then we'll incrementally layer in React and styled-components.

First thing, make sure you have an API key, then install the Anvil Node API client:

Then this script will generate the PDF:

Run this script, and you'll see the following output. Great job!

Hello world HTML to PDF Hello world HTML to PDF

Add babel

Using React jsx syntax in node requires the use of babel. I assume most readers will have babel setup already. If you do, skip this section!

What follows is a super minimal install to get you up and running. Your production environment will likely be much more robust. The first step is installing two core packages, then a couple of presets—the most important being @babel/preset-react.

The last step is adding a .babelrc file to the root of your project that uses the installed presets:

Now you can run the script with yarn babel-node generate-pdf.js.

Add React

Time to generate some HTML with React. We'll be using server-side rendering via react-dom/server.

Install react and react-dom

Now we use ReactDOMServer.renderToStaticMarkup to generate the HTML. We're using renderToStaticMarkup instead of renderToString because renderToStaticMarkup omits some attributes React uses for dynamic updates. Since we're generating a PDF, there are no dynamic updates, so we have no use for the extra attributes.

Run the script and you're cooking with gas (React):

Hello react HTML to PDF Hello react HTML to PDF

Add styled-components

Next up is the CSS. We will generate the CSS string with styled-components. First install styled-components:

Like React, styled-components has server rendering abilities. Our path forward will be to create a new ServerStyleSheet, render sheet.collectStyles(<YourComponent />), then get all the styles as a string.

A quick snippet shows how it interacts with React.

Then, here's that snippet in context with some actual styling:

The result:

React HTML and styled components to PDF React & styled components to HTML & CSS to PDF

Insert global styles

You will likely need to inject a few global styles into the PDF. For example, you may want to set the font size, color, page details, etc. You can leverage styled-components’ createGlobalStyle() function. In the last example, we set the Container's font-size to 20px, but we could just as well do that styling in the body rule.

Here's a simplified snippet:

Using this in our script gives us the same result as the last example:

React HTML and styled components to PDF Same result with global styles

The whole script

Here we are with the whole enchilada: React, styled-components, and global styles. This script contains everything you need to render whatever you want to PDF by way of React and styled-components.

An invoice example

Hello-world examples are cute and all, but you may want to see a real-life example.

We've created React to PDF invoice example using the approach in this blog post. Along with the tech discussed in this post, the invoice example uses advanced HTML & CSS features like page numbering, header / footer rendering, special table features, etc.

React and styled-components invoice pdf example Invoice PDF generation example using React & styled-components

Summary

You should have all the tools necessary to create PDFs from your own React & styled-components code. You can use other technologies of your choice (e.g. Vue + SCSS) by extrapolating the approach in this post. That is, if it can output HTML and CSS strings, you can use it with the HTML to PDF endpoint.

If you have questions or you're developing something cool with PDFs, let us know at developers@useanvil.com. We’d love to hear from you.

Subscribe to the Anvil blog

Get new stories like this delivered directly to your inbox.

Loading...

Get a demo
(from a real person)

Schedule some time on our calendar to talk through your specific use case and see which Anvil products can help.
    Want to try Anvil first?
    Want to try Anvil first?