Space / satellite servicing & debris removal
Satellite company
Built the frontend for a large, CMS-driven corporate and investor-relations platform — editor-composable pages, up to 10 locales, and interactive 3D/WebGL brand experiences.
- Role
- Software development partner
- Stage
- Public company
- Sector
- Space / satellite servicing & debris removal

Outcomes
- Page routes + 8 API routes
- ~30Page routes + 8 API routes
- Composable CMS section types
- 47Composable CMS section types
- Locales (3 core + 7 news MT)
- 10Locales (3 core + 7 news MT)
- Three.js models + Unity/HTML5 games
- 3D + WebGLThree.js models + Unity/HTML5 games
Context
Not a landing page — a full multi-section corporate site (Solutions, Missions, Sectors, Resources, News, a dedicated Investor-Relations sub-site, Contact, Legal) plus interactive brand games. Content had to be fully editor-driven, and had to work across markets and languages.
The problem
Let a content team assemble arbitrary pages with no engineering involvement, serve investor content and news across many languages, and embed heavy 3D and game media — all while staying inside a headless CMS’s real platform limits and under a strict security posture.
- 01
Server-first Next.js 15 / React 19 frontend
App Router with React Server Components by default and client boundaries pushed down, strict TypeScript throughout.
- 02
Editor-composable page system on Contentful
A 47-type section library consumed over typed GraphQL (GraphQL Code Generator) and rendered by a __typename switch — editors drop any section onto any page with zero per-page code changes.
- 03
A fan-out GraphQL loader that beats the CMS’s own limits
Split one giant page query into a page-shell query plus parallel per-section-type batches — engineered specifically to stay under Contentful’s 8192-byte query-text and 11,000 cost-unit ceilings, which a single query blows past at ~15+ section types.
- 04
Internationalization across 10 locales
next-intl with three hand-authored core locales (en/fr/ja) plus a hashed, incremental, rich-text-aware machine-translation pipeline that adds seven more languages for news, so unchanged content is never re-translated.
- 05
Middleware for routing, locale scoping, and security
Locale routing, scoping machine-translation locales to news paths only, special-casing a Japanese IR vendor iframe, and a site-wide Content-Security-Policy moved out of next.config so it also covers static assets.
- 06
3D/WebGL brand experiences and B2B integrations
Three.js satellite models with Draco + KTX2 decoders and embedded Unity/HTML5 games, plus Salesforce, Mailgun, Mailchimp and Google Maps integrations and dynamic Zod form schemas built from CMS field definitions.
The Maverick moment: beating the CMS’s own query limits
A single query fetching 15+ section types blows straight past Contentful’s 8192-byte query-text and 11,000 cost-unit ceilings — the platform simply refuses it. Rather than cap what editors could compose on a page, we changed the data-access shape: split the fetch into a lightweight page-shell query plus parallel per-section-type batches. Pages could then grow to any number of section types while staying under the platform limits, and every section type became independently cacheable as a bonus.
Takeaway
When the platform’s limits fight the product’s flexibility, change the data-access shape, not the product.
Trade-offs
Every architecture is a set of things you chose not to have. These are the ones that mattered here.
Fan-out queries over one big query
Deliberately traded a couple of cold-request round-trips for staying under the CMS’s query limits — and for keeping each section type independently cacheable.
CSP in middleware, not next.config
Moved the Content-Security-Policy into middleware so the policy also covers /public static files, with the rationale documented for the team.
Stack
- Next.js 15
- React 19
- TypeScript
- Contentful
- GraphQL
- next-intl
- Tailwind CSS
- Three.js
- Storybook
- Salesforce
- Vercel