Making a Resume in HTML or React

William Kwok
The Startup
Published in
5 min readMar 1, 2021

--

Three years ago, I made a guide on how to make a resume in React. Since then, I’ve been told the library I use no longer works. Along with that, I thought of just a better way in general to achieve the same outcome. First, I’m going to teach how to make the resume in HTML or React. Then, I’m going to explain why this is better than my previous version.

Be sure to check out my YouTube video on this if you want a more visual or auditory explanation: https://youtu.be/iNIiWAWrzxE

Check out my website where I still use the KendoUI version!

The idea

What we’re going to be doing is creating a component in HTML or React, using CSS to size it to a standard size paper so we can print it later if we want.

We’re going to then run the HTML app using live-server or the React Scripts that come with React.

Then, we’re going to use a feature within puppeteer that allows you to export PDFs to a file.

For those wanting to make the React version, read through the HTML version first because I essentially do the same thing there.

Why?

My previous explanation still holds true. I created my resume previously in Microsoft Word and PowerPoint, and I was getting frustrated with the difficulty of precision, control, modification, and expansion. As a programmer, I wanted to be able to change a single variable to instantly see my change, and not have to shift five different things up a single pixel, only to just undo my changes because I didn’t like them. I also wanted to put this resume live and inline on my personal website, which is also programmed using React.

Requirements

  • PDF must be highlightable and parseable using typical ATS software
  • Links must be clickable
  • Must be able to export things like icons or pictures
  • Must be able to use custom fonts

HTML Version

To start, we’re going to create an empty HTML document, and creating a div with the id “pdf”.

<body>
<div id="pdf">
</div>
</body>

Next, we want to style this with CSS to determine exactly what size the document should be. At this point, I also make the body background gray or some other color so that it’s clear where the pdf is.

Puppeteer will export PDFs at a default resolution of 96ppi, meaning to match a standard letter size, we will want to do 8.5x11 * 96, which turns to 816px wide and 1056px height.

We also want to make sure the body padding and margin are 0.

#pdf {
height: 1056px;
width: 816px;
background-color: white;
}
body {
background-color: gray;
padding: 0px;
margin: 0px;
}

Finally, I also include a few extra things in my header like fontawesome through a CDN and a custom font I like to use for my resume.

At this point, you can now fill in the entire div#pdf using regular HTML, or whatever Javascript you want to make it easier.

But what’s the point of just making it in HTML? We want to put it on our websites and have other content around the resume.

My solution for this was to have a query parameter that enables a “resume only mode” that is to be used during puppeteer’s export step. A basic version can be seen below, and expanded upon however you see fit.

<div id="other-body-stuff">
Hi stuff goes here
</div>
<div id="pdf">
</div>

<script>
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const resumeOnlyMode = params.get('resumeonly');
if (resumeOnlyMode) {
document.getElementById('other-body-stuff').remove();
}
</script>

This will search for the query parameter in your url (ie http://localhost:3000/?resumeonly=true ) and hide the other-body-stuff div if it is true, making the only thing on the page be the pdf element.

NOTE: URLSearchParams is not available in IE11. If you want to make your website compatible with IE11, then you need to manually write your own query parameter search method.

Next, let’s make the puppeteer script.

Puppeteer Script

Puppeteer has a variety of use cases for opening a browser page and doing stuff with it through code. In this case, we’re going to be opening the page you just made, and outputting a PDF.

First, you’ll want to run your HTML using live-server. Install nodejs, initialize a project, then npm install live-server puppeteer and create a basic javascript script to run.

Run the html with live-server using npx live-server --port=3000 index.html (or whatever you named the file). I chose port 3000 to match the React version, but it’s up to you.

The entire script is as follows, with comments:

const puppeteer = require('puppeteer');(async () => {
// launch and create a new page
const browser = await puppeteer.launch();
const page = await browser.newPage();
// go to page in resumeonly mode, wait for any network events to settle
await page.goto("http://localhost:3000?resumeonly=true", {
waitUntil: "networkidle2"
});
// output to a local file
await page.pdf({
path: "output/resume.pdf",
format: "Letter",
printBackground: true
});
// close
await browser.close();
})();

Yup, it’s that simple. Now, you have a PDF that can upload anywhere, and also have a download link on your website for.

React Version

The React Version is pretty much the exact same, just I reordered some stuff.

function App() {
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const resumeOnlyMode = params.get('resumeonly');
return (
<div className="App">
{!resumeOnlyMode && (
<div id="other-body-stuff">
Hi stuff goes here
</div>
)}
<div id="pdf">
</div>
</div>
);
}

And I also put my fonts and fontawesome within the public index.html file that create-react-app created for me, but you can just as easily import it within your React code in other ways that fit your use case.

Then, you just do the exact same with Puppeteer as the HTML app.

Why this over PDFExport with Kendo?

My previous version used Kendo UI’s PDFExport feature. This method of doing things is far superior for a few reasons:

You can run this on the server side to produce a PDF, instead of relying on client side calculations.

Kendo UI’s PDF Export ran completely client side. Usually you want to run things on your own server or in a controlled environment so there’s less rooms for bugs to pop up as a result of another company’s software.

The PDF produced is what will be given to users.

Similar to the last point, you know what the PDF the user will get looks like, because you will be sending a copy of what you produced to users if they want it.

It’s easier.

With Kendo, my methods were not very straightforward, and the code was super messy. With this, every step is very straightforward in comparison, and anyone with basic knowledge of nodejs can follow along. It is not limited to React.

Thanks for reading!

Hopefully this helped someone. I spent some time making the code for this, and producing an example to work off of. See that here: https://github.com/kwokwilliam/Web-Based-Resume

Thank you in advance for any claps, follows, subscriptions on YouTube, etc! I’ll be making more content like this in the future.

--

--