All work

jacob-j.com

Built to ship almost no JavaScript

SvelteKit - TypeScript - Tailwind CSS GitHub

Setup

This site is built with SvelteKit and prerendered to static files. There is no server, no database and no UI component library.

Framework
SvelteKit 3, Svelte 5, adapter-static
Styling
Tailwind CSS 4, JetBrains Mono (self-hosted), Vesper palette
Languages
English and Danish with Paraglide
Hosting
Cloudflare Pages

No client-side framework

All routes are rendered to HTML at build time and client-side rendering is turned off. The browser receives HTML and CSS, not the Svelte runtime.

// src/routes/+layout.ts
export const prerender = true;
export const csr = false;

The theme switch, the sticky header, the scroll effects and the image lightbox are handled by one inline script in app.html. The script only changes attributes and CSS variables on the page. The visuals and animations themselves are done in CSS.

Scroll-driven text

On the front page, the highlight text lights up word by word while scrolling. The script writes the scroll progress to --p, and each word has its own position in --w.

.word {
    opacity: clamp(0.25, calc((var(--p) - var(--w)) * 6 + 1), 1);
}

Fonts and images

  • The font files contain only Latin and Danish characters, which cuts each one from 93 KB to 40 KB.
  • Screenshots are generated as AVIF and WebP in three widths, so a phone downloads a smaller file than a desktop. They are below the first screen, so they load lazily: the browser fetches them when the visitor scrolls near them, not on page load.
  • The mobile menu and the lightbox use the HTML Popover API instead of a script.

Search and sharing

Each page sets its own title, description and Open Graph tags through one component. The layout adds the canonical URL and hreflang links, so search engines treat the English and Danish versions as the same page in two languages.

  • sitemap.xml is a prerendered route that lists every page in both languages. New entries under /work are added automatically.
  • The front page includes JSON-LD describing a Person and a WebSite.
  • A 1200 x 630 image is used as the preview when a link is shared.

Workflow

Conventional Commits, one branch per change, pull requests into main. pnpm verify runs formatting, linting, the build and type checking.

Note

The prerenderer follows every internal link. A link to a missing page fails the build.