Hybrid WordPress Content Delivery Platform
WORDPRESS · NEXT.JS · API CONTRACT
Teams go headless for frontend freedom and quietly lose preview, redirects, search, plugin behaviour and cache clarity. This platform keeps WordPress authoritative and layers a typed, versioned contract underneath a React consumer — with the tradeoff written down rather than discovered later.
- Maintainer
- Pixy Puala
- Vertical
- Headless · Content APIs
- Year
- 2026
- Role
- Open source
- Stack
- WordPress REST API
- Status
- ● Public repo
- Verified
- Source on GitHub
Problem
Headless WordPress usually duplicates business rules: redirects get reimplemented in the frontend, preview breaks, and nobody can say which cache holds the stale page. The failure is not technical capability — it is an unowned contract between producer and consumer, so shapes drift and integrations break silently.
Constraints
Decisions
The contract is a published artefact
The content shape ships as a JSON Schema file, not as tribal knowledge. Producer and consumer both validate against it, so drift fails a test instead of a page.
Cache invalidation is deterministic surrogate keys
Every response carries surrogate keys; a content change resolves to an exact key set. Purging is a computed, testable function rather than a "clear everything and hope" button.
The ADR argues both ways
A decision record weighs when headless is justified and when it is not. A portfolio that only shows the yes case has not shown judgement.
Build
Stack
- ▸ WordPress REST API · PHP 8.1+ · Composer
- ▸ Next.js App Router · TypeScript
- ▸ JSON Schema (draft) content contract
- ▸ Surrogate-key cache invalidation resolver
- ▸ Vitest · offline fixture consumer build
- ▸ GitHub Actions CI
Tooling
- ✓ kept Composer · pnpm · Vitest · GitHub Actions
Results · Measured
Adapters were exercised against a live WordPress 7.0.2 install with route, status and contract conformance independently checked; all four invalidation paths are recorded in docs/RUNTIME-VERIFICATION.md.
Tradeoffs
Two things are deliberately out of scope, not unfinished: a live GraphQL server runtime, and a concrete CDN CachePurger implementation. The purger is deployment-specific and no CDN account was used during verification — shipping an untested one would be a claim, not a feature.