Skip to content

Latest commit

 

History

History
176 lines (116 loc) · 4.23 KB

File metadata and controls

176 lines (116 loc) · 4.23 KB

Netlify Status

Robert Schäfer Portfolio

Personal portfolio and printable CV built with SvelteKit, Tailwind CSS, Paraglide, Typst, and prerendering.

The site is bilingual (de, en), privacy-conscious, screen-reader friendly, and designed to print cleanly as a CV.

Stack

  • SvelteKit with @sveltejs/adapter-static
  • Tailwind CSS
  • Paraglide for UI i18n
  • Typst for PDF generation
  • Biome for linting and formatting
  • Vitest for unit tests
  • Netlify for hosting, edge locale redirects, and short-link redirects

Content Model

  • resume.i18n.json

The downloadable PDFs are generated from the same localized JSON sources through a dedicated Typst pipeline.

UI translations live in:

  • messages/de.json
  • messages/en.json

Local Development

Use the tool versions declared in mise.toml. It installs:

  • node
  • pnpm
  • typst

Install dependencies:

pnpm install

Start the dev server:

pnpm dev

The app runs with Paraglide compilation as part of the dev workflow.

With mise

If you use mise, install the local tools before running project commands:

mise install
mise exec -- pnpm install
mise exec -- pnpm dev

Useful Commands

Compile Paraglide messages:

pnpm build:paraglide

Lint:

pnpm lint

Typecheck:

pnpm check:types

Quick pre-push check (paraglide + resume source + lint + typecheck + unit tests):

pnpm check:quick

Full check, mirroring everything CI runs (slow - includes Playwright, PDFs, and a full build):

pnpm check

Test:

pnpm test

Build everything, including PDFs:

pnpm build

Build PDFs only:

pnpm build:pdf

Format:

pnpm format

Tests

The repo currently checks:

  • tech-experience derivation
  • locale preference parsing
  • localized resume parity
  • short-link parity between src/lib/data/short-links.ts and netlify.toml

Deployment

Target hosting is Netlify.

The deployed PDFs are published as:

  • /de/robert-schaefer-resume.de.pdf
  • /en/robert-schaefer-resume.en.pdf

Important deployment behavior:

  • / redirects to /de or /en via a Netlify edge function based on Accept-Language
  • /resume.json redirects to /de/resume.json or /en/resume.json
  • human-readable short links like /linkedin or /oss-contributors-35c3 are defined in netlify.toml

PDF Build And Deploy

  • Typst is not assumed to be available in Netlify builds.
  • GitHub Actions builds the PDFs and the final static site.
  • GitHub Actions deploys the finished build/ directory to Netlify.
  • Netlify should be configured to use the GitHub Actions deployment path rather than relying on its own repository build if you want the PDFs to stay part of every deploy.
  • Vendored ttf or otf fonts under typst/fonts/ are required for the PDF build. See typst/README.md.

Required GitHub repository secrets for deployment:

  • NETLIFY_AUTH_TOKEN
  • NETLIFY_SITE_ID
  • SOPS_AGE_KEY (a dedicated age private key for CI decryption of resume.i18n.json - see "Redacted Clients" in AGENTS.md)

SEO / Social Metadata

The site includes:

  • localized <title> and meta description tags
  • canonical URLs
  • hreflang tags for the localized portfolio pages
  • Open Graph tags
  • Twitter card tags

The current social preview image is:

  • static/roschaefer.jpg

Project Notes

  • Print output is optimized primarily for Firefox.
  • The web version and print version share the same content source.
  • Generated Paraglide files in src/lib/paraglide are never committed (the directory has its own nested .gitignore) and are recompiled on every dev/build/check/test run.
  • The decrypted, masked resume source (.generated/resume-source.json, .generated/resume.de.json, .generated/resume.en.json) is likewise gitignored and always regenerated fresh - see AGENTS.md for why.
  • CI needs a SOPS_AGE_KEY repository secret (a dedicated age private key, separate from any personal key) to decrypt resume.i18n.json during pnpm build/pnpm check:quick.