This Website
A data-driven website where photos, GPS tracks, and geographic data become web pages. A pnpm monorepo with Astro 5, React 19, Turso, and a content management dashboard on Netlify Functions.
Live
alessiogoria.com is not a template. It's a system where data from my experiences — photos, GPS tracks, coordinates, metadata — automatically become web pages. This is the story of how it was built.
The evolution
Version 1: static site with hand-written HTML. Version 2: React SPA with client-side routing. Version 3: Astro 4 SSG with a monolithic admin SPA. Version 5 (current, since 2026): pnpm 9 monorepo with Astro 5 + React 19, dashboard refactored into isolated modules, unified Turso database for site and mobile, and a full hardening pipeline (HSTS, CSP, rate limiting, Sentry). Result: Lighthouse 97/95/100/100, zero-downtime cutover, solid SEO.
Data-driven architecture
Content lives in Turso (cloud libsql): 39 trips, 152 geolocated waypoints, photos with EXIF coordinates, all with bilingual IT/EN metadata. A build script reads the database, generates optimized JSON in content-data/, and Astro produces static HTML for each page at build time. The production site remains purely static: the database serves the dashboard, not visitors.
Management dashboard
To manage content I refactored the dashboard into isolated modules (trips, waypoints, experiences, users, signups): React 19 with JWT + Argon2id authentication, schema-driven forms generated from shared Zod schemas, image uploads to Netlify Blobs, revision queue for editors, user management with roles and per-section permissions. Backend uses Netlify Functions v2 with Turso (serverless libsql) and rate limiting on login/contact/request-account.
Security and observability
HSTS + CSP + X-Frame-Options headers configured at the Netlify layer. Rate limiting on every sensitive endpoint (login, contact form, account requests). Runtime monitoring with Sentry free tier on both site and mobile app. Pre-commit hook with secretlint to block accidental keys. GitHub Actions CI pipeline with typecheck, lint, and schema drift checks on shared packages.
Native bilingual
Every page exists in Italian and English with dedicated URLs (/viaggi/giappone-2025 and /en/viaggi/giappone-2025). Interface translations are centralized in the site's i18n module. Content has _it and _en fields in every database record. The language toggle maintains page position. Hreflang tags ensure correct indexing.