Personal website of Danny Koppenhagen — built with Angular v22, server-side rendering, static site generation, and build-time internationalization.
🌐 k9n.dev
The application is an Angular v22 standalone-component app using signals, SSR/SSG prerendering, and @angular/localize for build-time i18n. Content is authored in Markdown and compiled into TypeScript manifests at build time.
- Angular v22 — Standalone components, signals,
OnPushchange detection - SSR / SSG —
@angular/ssrwithoutputMode: "static"for full prerendering - i18n —
@angular/localizewith build-time locale bundles (/de/,/en/) - Content — Markdown with frontmatter, parsed via custom build scripts
- Testing — Vitest for unit tests, AXE for accessibility auditing
- Styling — CSS design tokens, mobile-first, dark/light mode
┌─────────────────────────────────────────────────────────┐
│ Build Pipeline │
├─────────────────────────────────────────────────────────┤
│ Markdown Content → build-content.ts → TS Manifests │
│ Angular Source → ng build (i18n) → /de/ + /en/ │
│ Post-Build → post-build.ts → SEO + 404 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Runtime (per locale) │
├─────────────────────────────────────────────────────────┤
│ Prerendered HTML ← Angular SSG │
│ Locale Detection → Redirect to /de/ or /en/ │
│ Language Switcher → Full page navigation between builds│
│ Content Filter → Search + Tags + Language │
│ MetaManager → SEO, hreflang, og:locale, JSON-LD │
└─────────────────────────────────────────────────────────┘
All routes are locale-prefixed:
| Locale | Base URL | Example |
|---|---|---|
| German (default) | /de/ |
/de/blog/my-post |
| English | /en/ |
/en/blog/my-post |
Requests without a locale prefix are permanently redirected (HTTP 301) to the default locale. This ensures backward compatibility with previously indexed URLs (e.g., /blog/my-post → /de/blog/my-post).
Blog posts, talks, and projects are written in Markdown with YAML frontmatter. They are not translated — each item has a language field indicating its authored language (de or en). The UI adapts by setting appropriate lang attributes on content blocks.
This project uses pnpm as its package manager (pinned via Corepack). Enable it once with corepack enable pnpm.
pnpm install
pnpm run build:content
pnpm startpnpm run previewBaut die komplette Produktionsversion (beide Locales, SEO-Dateien, Legacy-Redirects) und startet einen lokalen Server auf http://localhost:4200 — identisch zum Deployment-Verhalten inkl. 301-Redirects für alte URLs ohne Locale-Prefix.
See CONTRIBUTING.md for detailed development setup, the i18n workflow (mark → extract → translate → serve), testing, and build instructions.
See AGENTS.md for comprehensive coding standards, Angular patterns, naming conventions, accessibility requirements, and i18n rules.
Private project — all rights reserved.