About this site
This post is a bit meta — I'm going to walk through how I built this site and the thinking behind it. The main thing I wanted to solve was keeping my web resume and a print-friendly PDF in sync without maintaining two separate versions of everything.
One source of truth
All my resume and site content lives in the _data directory. The main file is _data/author.json, where I keep my name, title, skills, work history, education, certifications, and so on. Both the site's Nunjucks templates and the generated resume markdown pull from this data, so when I update something, I only have to do it in one place. No copy-pasting, no wondering which version is current.
Web and print from the same content
Here's how the three outputs come together:
-
Website — The homepage and resume sections are built by 11ty straight from the
authordata. The layouts and partials in_layoutsand_includeshandle the rendering. -
Markdown resume — I have a file called
resume.txt.njk(withpermalink: /resume.md) that uses the sameauthordata to output a single markdown file at/resume.md. That's what you see linked as "Markdown resume" in the sidebar. -
PDF resume — After the site builds, a script called
generate-pdf.jskicks in. It reads the built_site/resume.md, converts it to HTML with markdown-it, and then uses Puppeteer to print that HTML to a PDF (with some print-specific CSS for page breaks and layout). The end result is a PDF that's always generated from the same markdown, which came from the sameauthor.json. On Netlify, the build command handles all of this — Puppeteer/Chrome runs as part of the deploy, so both the site and the PDF stay up to date automatically.
So the full flow looks like: author data → Nunjucks (site + resume.md) → markdown-it + Puppeteer → PDF. One source of truth, web and print always in sync.
Tech stack (brief overview)
Here's a quick rundown of what I'm using:
- 11ty (Eleventy) — My static site generator. It takes Nunjucks, Markdown, and JSON data as input and spits out HTML (plus that one markdown file used for the PDF).
- Nunjucks — Templating for all the layouts and partials.
- Tailwind CSS — Handles all the styling. I'm using a class-based approach for dark/light theme support via Tailwind's dark mode.
- markdown-it — Used inside
generate-pdf.jsto convert the resume markdown into HTML before Puppeteer gets involved. - Puppeteer — Headless Chrome that renders the HTML and generates the final PDF. Netlify installs Chrome at build time and runs the script as part of
npm run build. - Netlify — Hosting and CI. Every deploy runs the 11ty build followed by the PDF script, so everything stays current.
Scratch Pad
The Scratch Pad is a catch-all for things that don't belong on a resume. It's where I put hobby projects, experiments, and personal logs — anything I want a persistent home for but that isn't professional work. That includes things like interactive canvas demos, coffee roast logs from my Aillio Bullet, and whatever else I'm tinkering with at a given moment.