Skip to content
Currently booked
← All posts
· 5 min read

How this site is built: static, fast and made to be found

Why this portfolio runs as a static site on Astro and Cloudflare, and how it handles performance, SEO, GEO for AI answers, and security with current best practices.

Request an AI summary

A portfolio has two jobs: make a good first impression and be found by the right people. Both depend on decisions made long before the first pixel is designed: how the site is built, where it runs and what it leaves out.

Here’s how this site is put together, and why.

1. Why static: nothing to break into

Every page of this site is plain HTML, built once and then served as a file. There is no database, no admin login, no plugins and no server code running on each request.

That matters more every year. Automated scanners probe websites around the clock for known holes in outdated CMS installs, plugins and login forms, and AI makes finding and exploiting those holes faster and cheaper. A static site takes most of that off the table: there’s no login to guess, no plugin to patch and no database to leak. What’s left is the hosting, the domain and the mail, and those are locked down separately (more in the post on securing this site).

Static doesn’t mean simple. The site has animations, a little game, two languages and a blog. All of it is built into the HTML at build time, so visitors get the finished result.

2. The stack: Astro, Tailwind, Motion

  • Astro builds the pages. It renders everything to HTML and only ships JavaScript where a component really needs it. Content collections keep the blog posts typed and checked, and its i18n routing handles German and English.
  • Tailwind CSS holds the design system: colours, type roles, spacing and radii live as tokens in one place, so every component speaks the same visual language.
  • Motion and Lenis handle the animations and smooth scrolling. There’s no frontend framework running in the browser, just small scripts per component.
  • Cloudflare serves the files from its network close to each visitor, with security headers and caching rules set in one file.

Every push to the main branch runs type checks, the build and the tests, and Cloudflare deploys the site from that branch. A build that fails, for example on the security check, never goes live.

3. Performance: fast by leaving things out

Speed mostly comes from what a page doesn’t load:

  • CSS is inlined. The whole stylesheet is small enough to ship inside the HTML, which saves a render-blocking request.
  • Fonts are self-hosted as compact WOFF2 files, with no requests to third-party font services.
  • Images come in several sizes in modern formats, and the browser picks the one that fits the screen. Images below the fold load lazily.
  • Heavy parts load only when needed. The 3D logo, the game and the noise background are separate bundles that load on demand.
  • Animations run in CSS where possible. Scroll-driven animations follow the scroll without blocking the main thread.
  • Pixel art is drawn, not downloaded. The process scenes and these blog covers are a few kilobytes of code instead of heavy images or videos.
  • Hashed files are cached for a year. A changed file gets a new name, so visitors never get a stale version.

And for people who prefer less motion, every animation respects the reduced-motion setting.

4. SEO: clear signals for search engines

  • Every page has its own title, description and canonical URL.
  • German and English pages point to each other with hreflang, and the sitemap lists both languages.
  • Structured data describes the site in a form search engines read directly: the person, the services on offer, the FAQ and every blog post.
  • Open Graph tags give shared links a proper preview.
  • The HTML is semantic: real headings, lists and landmarks, which helps search engines and screen readers alike.

5. GEO: being found in AI answers

More and more people ask an AI assistant instead of a search engine. Generative Engine Optimization (GEO) makes sure the answer can include you:

  • AI crawlers are explicitly allowed in robots.txt, so a later blanket rule can’t shut them out by accident.
  • An llms.txt file summarises the site in plain text: who I am, what I offer, the FAQ and the blog posts.
  • Structured data and a clear FAQ give assistants facts they can quote instead of guess.
  • “Request an AI summary” links let visitors open ChatGPT, Claude, Gemini or Perplexity with a prompt about the page they’re reading.

6. Security: strict by default

  • A Content Security Policy with hashes for every inline script and style. The build fails if a page contains inline styles or event handlers, so the policy can’t be weakened by accident.
  • HSTS, HTTPS only and TLS 1.2 or newer.
  • No cookies, so no cookie banner either.
  • DNSSEC, CAA records and certificate alerts for the domain, plus SPF, DKIM and DMARC for mail.

7. Best practices: staying current

A site is only as current as its last update. So before every release, all dependencies are updated, and the changelog of every major version is read for breaking changes. Dependabot proposes updates every week, and the CI actions are pinned to exact versions.

The code itself follows the platform: native browser features like scroll-driven CSS and the inert attribute come first, libraries only where they add something the platform can’t. Accessibility is part of the build: visible focus styles, text contrast that passes WCAG AA, and menus that can’t be tabbed into while they’re closed.

The short version

  • Static: plain HTML, no database, no login, almost nothing to attack.
  • Stack: Astro, Tailwind CSS, Motion, Cloudflare.
  • Performance: inlined CSS, self-hosted fonts, responsive images, lazy bundles, CSS animations.
  • SEO: titles, canonicals, hreflang, sitemap, structured data.
  • GEO: AI crawlers allowed, llms.txt, quotable FAQ, AI summary links.
  • Security: strict CSP, HTTPS only, no cookies, hardened domain and mail.

If you’d like a website built on the same foundation, get in touch.