Boilerplate Next.js site for the gatewaze sites module. When an operator creates a new site in the gatewaze admin, the platform clones this repo as the initial commit of the site's internal git repo (per spec-content-modules-git-architecture §6.3).
app/
layout.tsx # Root layout with <GatewazeHead /> for analytics + A/B
page.tsx # Homepage — reads content/pages/index.json
[slug]/page.tsx # Dynamic route — reads content/pages/<slug>.json
globals.css # Bare-minimum styles; replace with your design system
components/
PageContent.tsx # Schema-driven renderer; subscribes to gatewaze:ab-ready
wrappers/SiteWrapper.tsx # Optional site-level wrapper (referenced by theme.json)
content/
schema.json # JSON Schema for page.content; ingested by gatewaze
pages/index.json # Sample homepage content
theme.json # Theme metadata read by the publish-worker
- Operator creates a site in gatewaze admin → gatewaze clones this repo into the site's internal bare git repo.
- Connect the same repo via the Source tab → Connect external repo (HTTPS URL + PAT) → gatewaze ingests
content/schema.jsonand stores it as the site'stemplates_content_schemasrow. - Operator creates a page in the Pages tab →
pages.contentJSONB conforms tocontent/schema.json. - Operator publishes → publish-worker writes
content/pages/<slug>.jsonfiles into the publish branch → operator's CI (Vercel / Cloudflare Pages / Netlify) builds + deploys.
- Layout —
app/layout.tsxkeeps<GatewazeHead />; otherwise replace with your design. - Schema — edit
content/schema.json. Push to your repo'smain. Run Refresh in the Source tab to re-ingest. Past versions are retained intemplates_content_schemas. - Render — edit
components/PageContent.tsx. Add fields, components, animations. Keep thegatewaze:ab-readysubscription so A/B variant content overlays correctly. - Wrapper —
components/wrappers/SiteWrapper.tsxis optional; only used when the gatewaze admin assigns a site-level wrapper to the site.
When an operator runs an A/B test:
- Default content is in
content/pages/<slug>.json. - Per-variant content lands at
content/pages/<slug>.<variant>.json. - The
<GatewazeHead />bootstrap fetches the matching variant file after assignment, exposes content atwindow.gatewazeAB.variantContent, and firesgatewaze:ab-ready. <PageContent>listens for the event and re-renders with the merged variant content.- CTA
onClick→window.gatewazeAB.recordConversion(goalEvent).
<GatewazeHead /> reads public/_gatewaze/site-config.json (emitted by the gatewaze publish-worker) and injects the configured analytics provider's <script> automatically — no per-theme wiring required.
source.html is the canonical block catalogue for the visual canvas. In addition to the boilerplate blocks (hero, heading, paragraph, two_columns, …), other modules can contribute blocks here so they show up alongside the core set in the canvas picker.
For now, contributions are hand-merged into source.html from each module's blocks/<key>/source.html file under lf-gatewaze-modules/modules/<module>/ (or premium-gatewaze-modules/modules/<module>/). Each contributed block is wrapped in a comment marker noting its origin, e.g.
<!-- BLOCK:ambassador_apply_form | name=… | contributed_by=ambassadors -->A build-time merger that walks every module's blocks/*/source.html and auto-appends the catalogue is tracked as OQ-14 in spec-ambassadors-module.md §9.1. Until that lands, when a module ships a new block, the operator (or a coordinated PR) merges the block markup into this file and the corresponding Next.js renderer into components/blocks/.
| Block key | Contributed by | Notes |
|---|---|---|
ambassador_apply_form |
ambassadors |
Embeds a forms-module application form inline and POSTs anonymously to /api/modules/forms/:slug/submit. No server-side data needed — the form fields are baked at publish time from the forms.fields row keyed by application_form_slug. |
ambassador_grid |
ambassadors |
Public roster grid. Rendered server-side at publish/revalidate time by components/blocks/ambassador-grid.tsx, which calls ${apiBase}/api/modules/ambassadors-public-api/programs/:slug/roster. Falls back to an empty preview if the API is unreachable. Gated by the ambassadors module's publicGridEnabled config flag. |
pnpm install
pnpm devYou'll need to either pre-populate content/pages/*.json manually OR point Next at a clone of the gatewaze publish branch (which contains the published content).
Apache-2.0.