Skip to content
Soren-gitPublic

About

Personal resume built with React and TypeScript, featuring a clean, responsive and print-friendly design.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

CV — React & TypeScript

My résumé, built as a small React + TypeScript application. The same source renders the web version (responsive) and the one-page A4 PDF I send with my applications.

Public preview of the résumé

This repository contains the public, anonymised version: contact details are placeholders. My real details only exist on my machine and are never committed or bundled into the public build.

Highlights

  • Content separated from presentation — the résumé content lives in src/data/cv.ts, typed by src/types.ts. Components in src/components only render it.
  • One layout, three outputs — desktop, mobile and A4 print. SCSS partials with variables and print / mobile mixins keep the print rules next to the screen rules of each element.
  • Always up-to-date PDF — a custom Vite plugin (vite-plugins/cvPdf.ts) renders the page with headless Chromium (Playwright). In development the PDF is regenerated on every change; at build time it is generated from the production bundle, and the build fails if the résumé no longer fits on a single A4 page.
  • Public / private variants — see below.

Public and private versions

Public (default) Private
Contact details placeholders from src/data/identity.public.ts read from .env.local
Commands pnpm build, pnpm dev:public pnpm dev (when .env.local exists), pnpm build:private
Output dist/ (site + cv.pdf) private/ (site + named PDF)
Committed yes never (.env.local and private/ are git-ignored)

How the separation is enforced:

  • The app imports contact details from a virtual module, virtual:cv-identity, provided by vite-plugins/cvIdentity.ts. In public mode it re-exports the placeholders; only in --mode private does it read the real values.
  • pnpm build is always public. Only the local dev server switches to the private version automatically when .env.local is present.
  • Private variables use the CV_ prefix, not VITE_, so Vite never exposes them to client code. In public mode they are not even read, so they cannot end up in the public bundle.
  • scripts/check-privacy.mjs scans every committable file and the public build for the private values (taken from .env.local), generic e-mail and phone patterns, tracked PDFs, ignore rules and commit e-mail addresses. It runs before every git push through a versioned hook (.githooks/pre-push).

Getting started

Requirements: Node.js 20+, pnpm, and Chrome or Edge (or pnpm exec playwright install chromium) for PDF generation.

pnpm install          # also enables the pre-push privacy hook
pnpm dev              # http://localhost:5173 (public version until .env.local exists)

To work on the private version:

cp .env.example .env.local   # then fill in your real details
pnpm dev                     # live preview with your details, PDF kept up to date in private/
pnpm build:private           # final private PDF in private/

Scripts

Script Description
pnpm dev Dev server with live PDF regeneration — private version if .env.local exists, public otherwise
pnpm dev:public Dev server forced to the anonymised version
pnpm build Type-check, public build and PDF in dist/
pnpm build:private Type-check, private build and PDF in private/
pnpm preview Serve the public build
pnpm check:privacy Public build, then privacy audit of the repository and dist/

Project structure

src/
├── data/
│   ├── cv.ts                 # résumé content
│   └── identity.public.ts    # placeholder contact details
├── components/               # Sidebar, MainContent, Section, EntryItem…
├── styles/                   # SCSS partials: variables, mixins, layout…
└── types.ts
vite-plugins/
├── cvIdentity.ts             # public / private contact details
└── cvPdf.ts                  # PDF generation and one-page check
scripts/check-privacy.mjs     # pre-publication privacy audit

Tech stack

React 18 · TypeScript · Vite · SCSS · Playwright

About

Personal resume built with React and TypeScript, featuring a clean, responsive and print-friendly design.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages