← Back to projects

ShortStayGuide

Project

Tri-locale curated travel guide platform (EN/FR/ES). 3,087 city guides (343 cities × 3 durations), 17,445 persona guides, 2,580 neighborhoods, 540 road trips, 333 worth-it verdicts, 46 country itineraries, 83 day-trip hubs, 48 food guides, 93 articles — 24,255 total content pieces, 3D globe, semantic search on the edge, trip planner with PDF export, currency switcher. 1,211 commits, ~61 K LOC, 69 components (48 Astro + 21 Preact islands).

FR EN
3,087 City guides (3 locales)
343 Unique cities
24,255 Total content pieces
~17,900 Geo stops
1,211 Commits
< 10 MiB Worker total

Why I built it

Low-cost flights turned the weekend into exploration territory. A backpack, two days, a city you don't know — it became a passion. But once on the ground, the real question is: what must I see to feel I genuinely made the most of my time? ShortStayGuide answers that: one curated guide per city, straight to the essentials, no drowning in 400 generic POIs. Built for fast travellers, by one of them.

Structural technical decisions

01
Astro 6.2 SSG + Preact islands on Cloudflare

Over 24,000 pages statically generated at build time (city guides × 3 languages, persona guides, neighborhoods, road trips, food, articles), spread across 94 page templates + 19 dynamic endpoints, with selective hydration only on the 21 Preact islands (globe, mega-menu, search, trip planner, currency switcher). Zero JS on the overwhelming majority of the site — SEO keeps its priority.

02
Content Collections + Zod as source of truth

Over 24,000 markdown files with strictly validated frontmatter (Zod 4) feed all routing (city / country / continent / duration / guide / persona / neighborhood / article / food / roadtrip) with no CMS. Reproducible builds; D1 only backs the trip planner's user data.

03
Cobe for the globe, Leaflet lazy-loaded

Cobe ships ~19 KB canvas-based instead of importing Three.js. And Leaflet (~150 KB) only loads on the guide routes that actually need it — never on the home, never on aggregation pages.

The non-trivial challenge

Industrializing content at SEO scale

Producing 3,087 coherent city guides (3 durations × 343 cities × 5 continents × 3 languages EN/FR/ES), each with geo-located stops (lat / lng), normalized tags, excerpts under 90 chars, UPPERCASE continent. Plus 17,445 persona guides, 2,580 neighborhoods, 540 road trips, 333 worth-it verdicts, 46 country itineraries, 83 day-trip hubs, 48 food guides, 93 articles — 24,255 total content pieces. Fitting all of it into 94 page templates + 19 dynamic endpoints + aggregation pages per city / country / continent / persona, without blowing up build time or schema consistency. The real boss isn't the globe or perf — it's schema discipline at volume × locales.

Lesson learned

The islands architecture lets you buy interactivity à la carte: Leaflet (150 KB) never touches the homepage, and the site stays essentially zero-JS where it matters for SEO.

Features

🌍
Interactive 3D Globe

WebGL navigation with per-city markers

🧠
Semantic search on the edge

Cloudflare Vectorize + Workers AI at the edge

🧳
Persistent trip planner

D1 storage, PDF export (Browser Rendering), shareable nanoid links

💱
Currency switcher

Live exchange rates per guide

🖼️
Dynamic OG images

Generated on the fly with Satori + resvg

🛡️
GDPR + hreflang + llms.txt

Cookie consent, EN/FR/ES hreflang, llms.txt for AI crawlers

Tech Stack

Framework
Astro 6.2Preact (21 islands)Zod 4TypeScript
UI
Tailwind 4Cobe (WebGL globe)LeafletFuse.js
Edge / AI
@astrojs/cloudflareWorkers AIVectorizeBrowser Rendering
Data
D1 (ssg-trips)KV (weather + profiles)Content Collections
Growth
PostHog@anthropic-ai/sdkJSON-LDSitemap