Energie Schweiz - Gatsby to Astro Migration
★ FeaturedMigration of the public, three-language (DE/FR/IT) EnergieSchweiz platform (Swiss Federal Office of Energy) from Gatsby to Astro - evolutionary, not a rewrite. URLs, SEO and search stay intact; the go-live is zero-downtime and reversible.
Technical Challenges
- Rebuilding a live, three-language federal platform - no downtime, no visible change
- Carrying over every URL and protecting SEO (~500 redirects per language)
- Keeping cross-references intact across two separate content systems - including circular links
- Rebuilding search: always-current results, no stale entries
- Matching or beating the old site on performance and accessibility
Solutions
I reviewed the existing architecture, kept what worked, and replaced only what the framework change required. At the core: a fast static site with an editorial preview, plus a routing layer that guarantees identical URLs across all three languages. I sized the verification to the risk - a proof-of-concept, production-identical staging, and a reversible switch with the old system as fallback.
Outcomes
- Successful, zero-downtime and reversible go-live on 27 July 2026
- Every URL carried over one-to-one (~500 per language, DE/FR/IT); rankings protected
- Fast static site with live editorial preview
- Search always current and provably correct
- Performance and accessibility verified against the old site
- A leaner, clearly organized codebase
Project Context & Goals
EnergieSchweiz is the Swiss Federal Office of Energy’s (SFOE) public information hub, serving citizens and businesses across three languages (German, French, and Italian). The migration from Gatsby to Astro was designed as an evolutionary technological replacement. The goals were clear: maintain identical URL structures, preserve SEO rankings, improve search accuracy, and boost page performance, all without causing downtime or visible changes for the end-user.
Architecture Decisions & Monorepo Structure
To ensure codebase cleanliness and modularity, the project was designed as a modern monorepo with distinct packages:
- Static Website Frontend (Astro/React): The presentation layer integrating React components as interactive, hydrated islands.
- Contentful Data Layer (LevelDB): A library that syncs Contentful space contents locally during builds, providing a typed repository API to prevent API rate-limiting issues.
- Custom Content Routing: A decoupled package responsible for building locale-aware tree paths, handling circular references, and resolving page breadcrumbs.
Key Architectural Decisions (ADRs)
- ADR-001 (LevelDB Caching): Instead of querying the Contentful Delivery API directly during build time (which would trigger rate limits), a local LevelDB database is synced with Contentful before builds. This reduced build times and stabilized the pipeline.
- ADR-003 (Data Access Boundary): Data fetching is strictly isolated inside Astro page frontmatters. React components are pure and receive all data as props. This pattern ensures clean SSR/SSG compilation and avoids client-side data fetching overhead.
- ADR-005 (Localization): React components leverage
react-intlon dynamic islands for local translation handling. - ADR-006 (Styles Cache): Emotion styling is integrated via Babel. Hydrated React islands are wrapped in a
<CacheProvider>to eliminate SSR/CSR style hash mismatches and layout flashes.
URL Routing & Search Integration
Porting the routing layer from Gatsby’s tree traversal required precise recreation. Pages under the main brand/portal
are served at the root /, whereas campaign-specific pages are structured under dynamic paths like /{programme|programmes|programmi}/{campaignSlug}/....
Search was rebuilt using Algolia indexers integrated directly into the CI/CD pipeline, guaranteeing that only validated, live content is searchable without delay.