This very website is built from modules. The blog you are reading, the LiDAR lab, the careers section, even the contact form — each is a self-contained unit that can be switched on or off while the site is running, without a rebuild or redeploy.
Why bother?
Because websites are never finished. Sections launch half-ready, campaigns end, experiments fail. The usual answer is a feature branch and a deployment; ours is a toggle. When we reuse this codebase for another site, we start from the same catalogue and simply enable a different subset.
The anatomy of a module
Each module is described by a small manifest: an id, the routes it owns, and its navigation entry. From that single source of truth we derive everything else:
- The proxy (Next.js middleware) checks each request against disabled modules' route claims and answers with a 404 — this is what makes toggles apply live, even for statically prerendered pages.
- A route guard in the module's layout provides a second line of defence inside the app.
- The header, footer, and command palette filter their links through the same enabled-set, refreshed client-side.
Three layers of configuration
The enabled set is resolved from three levels, later ones winning: checked-in defaults, per-deployment environment variables, and a runtime overrides file written by a token-protected admin panel. Core modules — home page, legal pages — refuse to be disabled at any level.
The honest trade-off
The plumbing costs you indirection: a new section must register a manifest instead of just adding a page. In exchange, "can we hide that section for now?" becomes a ten-second answer instead of a deployment. For a studio that runs many small sites, that trade pays for itself quickly.
More posts
Devlog: rebuilding preunec.de
We rebuilt preunec.de from the ground up. Here's what changed for you as a visitor — and a friendly peek under the hood at how it works.
ReadHow we build mobile apps: a Clean Architecture playbook for Expo
The architecture we use for every Expo app — layers with a strict dependency rule, manual DI, feature modules, and a workflow that lets two developers move fast without stepping on each other.
ReadWhat Makes a Good EU Project Dissemination Site
Lessons from building multilingual dissemination platforms for Erasmus+ consortia.
Read