Notes · · 2 min read

How this site is built: zero JavaScript, strict headers

A personal site doesn't need trackers or a framework. Here is how I kept this one small, private, and locked down.

I work in security and privacy, so my own website should practise what I preach. The goal: a site that loads fast, collects nothing about its visitors, and would hold up if someone poked at it.

No JavaScript at all

The page is plain HTML and CSS, generated by Hugo from a single data file. There is no framework, no analytics snippet, and no cookie banner, because there are no cookies.

Everything that moves on the page is CSS: the network graph at the top draws itself with SVG stroke animations, and sections fade in using scroll-driven animations. All of it sits behind prefers-reduced-motion, so it stays still for people who ask their system for less motion.

A content security policy that says “no” by default

Every response carries a strict Content-Security-Policy:

default-src 'none'; style-src 'self'; img-src 'self'; font-src 'self';
base-uri 'none'; form-action 'none'; frame-ancestors 'none'

Nothing is allowed unless it is explicitly listed, and scripts are not listed at all. Even if someone managed to inject markup, the browser would refuse to run it. The stylesheet is fingerprinted with a Subresource Integrity hash, and the page also sends HSTS, nosniff, a strict referrer policy, and a permissions policy that turns off camera, microphone, and location.

Here are the headers the site actually sends. This card is generated from the same file Cloudflare uses, so it can’t drift out of date:

curl -I elmartromp.dev
HTTP/2 200
content-security-policy: default-src 'none'; style-src 'self'; img-src 'self'; font-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
permissions-policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
cross-origin-opener-policy: same-origin
strict-transport-security: max-age=31536000
  • 0 JavaScript
  • 0 cookies
  • 0 trackers
  • 0 third-party requests

Static HTML from Hugo, served by Cloudflare. Found a security issue? See security.txt.

No third parties

The display font is self-hosted, and so are the images. Visiting this site sends requests to this site and nowhere else: no CDN fonts, no embeds, no tracking pixels.

Guard rails in the build

A small check script runs on every change, both on my machine and in GitHub Actions. It builds the site and fails if it finds inline scripts, inline styles, or event handlers that the CSP would block. The one exception is a block of structured data for search engines, which browsers never execute.

Security contact

Like any service that takes security seriously, the site publishes a security.txt with an address for reporting issues. If you find something, I’d genuinely like to hear about it.