Als freelance software engineer is het van belang dat ik regelmatig mijn cv bijwerk. Er zijn verschillende soorten methoden om een prima cv te maken, zoals met Word of InDesign. Maar ja, als software engineer, wil ik dit met development-tools bouwen. Zo wordt jouw cv een showcase van jouw skills. In deze blogpost zet ik uiteen hoe ik mijn meest recente cv met front-end softwaretechnieken heb gebouwd.
Afgelopen jaren heb ik mijn curricula vitae met verschillende tools gecreëerd. Aan het begin van mijn carrière deed ik dit "gewoon" in Microsoft Word. Daarna gebruikte ik verschillende open-source tools, waaronder Scribus.
Stappen
Tijdens mijn werk als zzp softwareontwikkelaar, werk ik regelmatig met front-end technieken, zoals React met Typescript. Vandaar dat ik nu eens een cv wilde bouwen met deze technieken. Hier zie je een voorbeeld van het resultaat:

Technieken
Uiteindelijk heb een combinatie van de volgende technieken gebruikt:
- React, Typescript & create-react-app: Front-end Javascript library als basis voor het project.
- React-pdf: Node.js package voor het genereren van PDF-documenten in de browser ( kan tevens ook server-side).
- React-pdf-tailwind (& Tailwind CSS): Voor het stijlen van react-pdf elementen met Tailwind CSS.
- Google Fonts: Aangepaste lettertype. Let op, je kunt niet alle lettertypes gebruiken met react-pdf. Daarover later meer.
In de volgende stappen licht ik toe hoe ik het heb gebouwd.
1. Opzetten project
Als basis heb ik create-react-app gebruikt om het initiële project op te zetten met Typescript (via NPX). Vervolgens
heb ik Tailwind CSS toegevoegd.
Bash (/terminal)
1npx create-react-app demo-cv --template typescript
2cd demo-cv
3npm install -D tailwindcss
4npx tailwindcss initNa het toevoegen heb ik tailwind.config.js aangepast naar behoefte, zoals in de docs aangegeven. Daarnaast heb ik de
Tailwind elementen toegevoegd aan index.css:
CSS
1@tailwind base;
2@tailwind components;
3@tailwind utilities;Verder heb ik alle onnodige zaken verwijderd, zoals Jest, Web Vitals en assets uit de public-map, aangezien dat niet
van belang is voor dit project.
Het enige wat nog geïnstalleerd moet worden is react-pdf & react-pdf-tailwind:
Bash (/terminal)
1npm install @react-pdf/renderer react-pdf-tailwind --saveNu we klaar zijn met de basis, kunnen we beginnen met het vormgeven.
2. Vormgeven
2.1 HTML-template (index.html)
Om ervoor te zorgen dat ik de PDF-preview in de browser op full-screen kan bekijken, heb ik de html-template aangepast
zodat #root de volledige hoogte aanneemt (public/index.html):
HTML
1<!DOCTYPE html>
2<html lang="nl">
3<head>
4 <meta charset="utf-8"/>
5 <meta name="viewport" content="width=device-width, initial-scale=1"/>
6 <style>
7 #root {
8 height: 100vh;
9 }
10 </style>
11 <title>demo-cv</title>
12</head>
13<body>
14<div id="root"></div>
15</body>
16</html>Daarnaast kun je zien dat ik alle onnodige elementen eruit heb gehaald. Een favicon, meta description, etc. is niet nodig als ik alleen een PDF wil kunnen genereren.
2.2 Basisdocument & metadata
En het laatste wat we moeten aanpassen, voordat we echt kunnen beginnen met de inhoud, is index.tsx. Hier heb ik de
hele app gewrapt met PDFViewer en Document. PDFViewer zorgt ervoor dat we de resulterende PDF in de browser kunnen
bekijken. En Document is de absolute basis van het document. Hieraan kun je ook metadata toevoegen:
JSX
1root.render(
2 <PDFViewer width="100%" height="100%">
3 <Document
4 title={"Curriculum Vitae van Nyef - Software Engineer - 2024"}
5 author={"Nyef"}
6 subject={"Overzicht werkervaring, skills & opleidingen."}
7 language={"nl-NL"}
8 >
9 <Cv/>
10 </Document>
11 </PDFViewer>
12);Zie de documentatie van react-pdf voor alle opties. In het Cv
-component, vindt je
de inhoud en structuur (public/src/components/). Daarnaast heb ik in index.tsx het lettertype en react-pdf-tailwind
geconfigureerd.
2.3 Lettertype
Aangezien ik mijn cv qua stijl op mijn website wilde laten lijken, heb ik gekozen om hetzelfde lettertype te gebruiken: Fira Sans (Google Fonts).
Om een aangepast lettertype te kunnen gebruiken, moest ik die registreren in
de code
voor react-pdf (in index.tsx). Daarbij heb ik alleen de diktes (font-weight) toegevoegd die nodig waren:
JavaScript
1Font.register({
2 family: "Sans",
3 fonts: [
4 {
5 src: "/fonts/FiraSans-Regular.ttf",
6 fontWeight: 400,
7 },
8 {
9 src: "/fonts/FiraSans-Medium.ttf",
10 fontWeight: 500,
11 },
12 {
13 src: "/fonts/FiraSans-Bold.ttf",
14 fontWeight: 700,
15 },
16 ],
17});Let op: je kunt alleen TTF-lettertypes toevoegen.
2.4 Toepassen Tailwind CSS in pdf-document
Nu hoeft nog alleen Tailwind CSS te worden geconfigureerd met react-pdf-tailwind. Dat wordt gedaan als volgt (
in index.tsx):
Typescript
1import {Style} from "@react-pdf/types";
2
3export type TwToStyle = (input: string) => Style;
4
5export const tw: TwToStyle = createTw({
6 theme: {
7 fontFamily: {
8 sans: ["Sans"],
9 },
10 extend: {},
11 },
12});Het tw-object gebruik je om Tailwind CSS-classes toe te passen aan react-pdf componenten, bijvoorbeeld:
JSX
1<Text style={tw("text-[12px] font-bold text-slate-800")}>
2 {text}
3</Text>Nu alle configuratie klaar is, kan er eindelijk inhoudelijker gewerkt worden aan het cv.
2.5 Structuur & inhoud
In deze blogpost ga ik niet in op wat er allemaal in een cv hoort en de vormgeving ervan, daar zijn betere bronnen voor. Ik heb in mijn geval gekozen voor een combinatie tussen een functional & chronological cv.
Zoals eerder aangegeven, heb ik in het Cv-component de algemene structuur. Deze ziet er als volgt uit:
JSX
1const Cv = () => {
2 return (
3 <Page
4 size="A4"
5 style={tw("w-full h-screen bg-slate-100 flex flex-col justify-between font-sans text-[12px]")}
6 >
7 <View style={tw("flex flex-col items-start")}>
8 <Header/>
9
10 <View style={tw("w-full h-auto p-6 flex flex-row gap-6")}>
11 <PersonalDetails/>
12
13 <View style={tw("w-full flex flex-col gap-4")}>
14 <SkillsOverview/>
15 <ExperienceSection/>
16 </View>
17 </View>
18 </View>
19
20 <Footer/>
21 </Page>
22 );
23}Mijn doel was om de volgende structuur te bouwen:

Hieruit kun je over het algemeen opmaken uit welke secties mijn cv bestaat.
Ik heb alles in zo logisch en klein mogelijke componenten verdeeld voor betere code-kwaliteit en herbruikbare code. Bijvoorbeeld, in skills heb ik een overzicht van badges met daarin een skill, verdeeld over een aantal categorieën:
JSX
1const SkillsOverview = () => {
2 return (
3 <>
4 <ProgrammingLangSkills/>
5 <FrameworksLibsSkills/>
6 <WebServerSkills/>
7 <ModelingPrinciplesSkills/>
8 <ProjectManagementSkills/>
9 </>
10 );
11};En iedere skill-sectie, kan ik simpelweg aanmaken met consistente stijl, bijvoorbeeld:
JSX
1const ProgrammingLangSkills = () => {
2 return (
3 <BadgeSection
4 title={"Programmeer-, stijl- & markup-talen"}
5 items={[
6 "Java",
7 "Javascript (ES6)",
8 "SQL (PostgreSQL, MySQL, MS SQL)",
9 "HTML",
10 "CSS",
11 "Less",
12 "Markdown",
13 "PHP",
14 ]}
15 />
16 );
17};Let wel op, je kunt niet alle CSS-stijlen gebruiken met react-pdf. Dus controleer de documentatie om te zien wat mogelijk is.
Na het implementeren van alle componenten, kwam ik op het volgende uit:

3. Exporteren & delen
Nu rest alleen het downloaden van een export, zodat ik mijn software-engineering cv in PDF-formaat kan delen met anderen.
Dit kan simpelweg via de browseropties van de PDF-viewer.

React-pdf biedt tevens ook een aantal opties om je document op te slaan. In mijn geval wilde ik het zo simpel mogelijk houden.
Voordelen cv bouwen als softwareontwikkelaar
That's it! Over het algemeen is het vrij simpel om een cv te bouwen met behulp van o.a. React, Typescript en Tailwind CSS.
Het zelf bouwen van een cv met softwareontwikkel-technieken, levert de volgende voordelen op:
-
Je kunt relatief simpel meertalige cv's maken, bijvoorbeeld als je react-intl toevoegt (i18n).
-
Je kunt het project verder uitbouwen zodat je o.b.v. een configuratie je cv dynamisch laat genereren. Handig voor als je je cv wilt aanpassen voor verschillende sollicitaties.
-
Als je meer ervaren bent met CSS, zul je je meer vertrouwd voelen hiermee.
-
Je cv zelf is een showcase van je front-end skills! Het helpt om je vaardigheden aan potentiële werkgevers te tonen.
