riverbankcms 0.1.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acceptance/matrix.mjs +86 -22
- package/dist/cli/index.mjs +18913 -14808
- package/dist/cli/init-docs/content/agents-section.md +9 -2
- package/dist/cli/init-docs/content/cli-reference.md +77 -11
- package/dist/cli/init-docs/content/content-management.md +12 -3
- package/dist/cli/init-docs/content/getting-started.md +8 -10
- package/dist/cli/init-docs/content/workflow-add-block.md +8 -1
- package/dist/cli/init-docs/content/workflow-block-extensions.md +25 -9
- package/dist/cli/init-docs/content/workflow-custom-block.md +35 -8
- package/dist/cli/init-docs/content/workflow-isr-revalidation.md +26 -24
- package/dist/cli/init-docs/content/workflow-preview-mode.md +30 -6
- package/dist/cli/init-docs/content/workflow-remote-setup.md +66 -10
- package/dist/eventUpsertInputSchema-CzMX5BZI.mjs +4941 -0
- package/dist/load-config-226EuL6w.mjs +5 -0
- package/dist/{load-config-r1s4htWu.mjs → load-config-Boa0tkmk.mjs} +1 -1
- package/dist/plan-2c4zVtlW.mjs +2213 -0
- package/dist/scaffold/index.mjs +5 -0
- package/dist/sdk-event-upsert-BCZUdIrL.mjs +887 -0
- package/dist/{sdk-peer-DrblJmno.mjs → sdk-peer-DiZYsNXj.mjs} +6 -3
- package/dist/src-XEJYAKbQ.mjs +4697 -0
- package/dist/{style-Chv9Gcwq.mjs → style-3BjmymXd.mjs} +30532 -35235
- package/dist/testing.mjs +4 -2
- package/package.json +7 -2
- package/dist/load-config-CRB4AHKq.mjs +0 -5
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
## RiverbankCMS SDK Context
|
|
2
2
|
|
|
3
|
-
This repository is a site using **RiverbankCMS** as a
|
|
3
|
+
This repository is a fully headless site using **RiverbankCMS** as a CMS via
|
|
4
|
+
the `@riverbankcms/sdk` package. The host owns markup, styles, and block
|
|
5
|
+
rendering through the override registry.
|
|
4
6
|
|
|
5
7
|
### What This Means
|
|
6
8
|
|
|
@@ -23,7 +25,7 @@ Detailed documentation is available in `.riverbank/docs/`:
|
|
|
23
25
|
- `content-management.md` - Content model and sync workflows
|
|
24
26
|
- `schema.md` - Site-specific schema (auto-generated from config)
|
|
25
27
|
- `block-types.md` - Available block types (auto-generated)
|
|
26
|
-
- `theme-schema.md` -
|
|
28
|
+
- `theme-schema.md` - Optional theme schema reference (auto-generated from Zod)
|
|
27
29
|
- `workflows/` - Step-by-step guides for common tasks, including editor workflows
|
|
28
30
|
- `workflows/agent-safe-sync.md` - Agent-safe dry-run, scoped push, and `--env` guidance
|
|
29
31
|
- `site-workflows/` - Site-specific workflows and customizations
|
|
@@ -46,6 +48,11 @@ Use CLI `--env=remote` / `--env=local` for CMS commands rather than relying on `
|
|
|
46
48
|
3. **Preview**: `riverbankcms push --dry-run` shows what would change
|
|
47
49
|
4. **Push**: `riverbankcms push` applies changes to CMS
|
|
48
50
|
|
|
51
|
+
Built-in semantic kinds such as `block.hero` remain in content JSON. Register
|
|
52
|
+
the host-owned override for every kind the site uses in `src/lib/block-overrides.tsx`.
|
|
53
|
+
The generated default uses `SITE_RENDERING` with override-only rendering and no
|
|
54
|
+
CMS theme runtime.
|
|
55
|
+
|
|
49
56
|
For narrow edits, push the narrowest scope possible, for example `riverbankcms push pages privacy-policy --env=remote --dry-run`. If broad local content is stale or contains unrelated differences, see `.riverbank/docs/workflows/agent-safe-sync.md`.
|
|
50
57
|
|
|
51
58
|
### Editing Page Content Directly
|
|
@@ -10,7 +10,7 @@ All commands support these options:
|
|
|
10
10
|
| ---------------- | ---------------------------------------------------------- |
|
|
11
11
|
| `--json` | Output a single JSON envelope for machine parsing |
|
|
12
12
|
| `--quiet` | Minimal output (suppress non-essential messages) |
|
|
13
|
-
| `--env <target>` | Target environment: `local` (default), `remote`, or `both` |
|
|
13
|
+
| `--env <target>` | Target project environment: `local` (default), `remote`, or `both` |
|
|
14
14
|
| `--remote` | **[Deprecated]** Use `--env=remote` instead |
|
|
15
15
|
|
|
16
16
|
**The `--json` envelope (single-document contract):** under `--json`, *every* invocation emits **exactly one** JSON document on stdout:
|
|
@@ -25,8 +25,8 @@ All commands support these options:
|
|
|
25
25
|
|
|
26
26
|
**Environment targeting:**
|
|
27
27
|
|
|
28
|
-
- `--env=local` (default): Target local
|
|
29
|
-
- `--env=remote`: Target production CMS
|
|
28
|
+
- `--env=local` (default): Target the local development CMS
|
|
29
|
+
- `--env=remote`: Target the production CMS
|
|
30
30
|
- `--env=both`: Run against both environments sequentially
|
|
31
31
|
|
|
32
32
|
**Safety behavior:**
|
|
@@ -67,12 +67,55 @@ RIVERBANK_REMOTE_API_KEY=bld_live_sk_... # Required for deploy command
|
|
|
67
67
|
|
|
68
68
|
- Management API keys start with `bld_mgmt_sk_` (for write operations)
|
|
69
69
|
- Content API keys start with `bld_live_sk_` (for read-only operations)
|
|
70
|
-
- `RIVERBANK_*_SUPABASE_URL` is deprecated and ignored by media sync
|
|
71
70
|
|
|
72
71
|
---
|
|
73
72
|
|
|
74
73
|
## Setup Commands
|
|
75
74
|
|
|
75
|
+
### Account authentication and site setup
|
|
76
|
+
|
|
77
|
+
Account commands use a provider-neutral Riverbank account session. Select the
|
|
78
|
+
account environment independently from the project `--env` target:
|
|
79
|
+
|
|
80
|
+
Production account OAuth is deliberately rollout-disabled. The examples below
|
|
81
|
+
use staging; use local for development. Do not use
|
|
82
|
+
`--account-env=production` until the production account rollout is explicitly
|
|
83
|
+
enabled.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
riverbankcms login --account-env=staging
|
|
87
|
+
riverbankcms whoami --account-env=staging
|
|
88
|
+
riverbankcms sites list --account-env=staging
|
|
89
|
+
riverbankcms sites create --account-env=staging --name "Dovetail" --yes
|
|
90
|
+
riverbankcms logout --account-env=staging
|
|
91
|
+
riverbankcms auth revoke --account-env=staging --yes
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The CLI stores the refresh session in the OS credential store when available.
|
|
95
|
+
If a locked-file fallback is required, the CLI explains the risk and requires
|
|
96
|
+
`--allow-locked-file`. `logout` removes this machine’s stored session;
|
|
97
|
+
`auth revoke` revokes the account grant so access tokens on other machines can
|
|
98
|
+
no longer refresh. Neither operation removes sites, project credentials, or
|
|
99
|
+
content.
|
|
100
|
+
|
|
101
|
+
Use `link` for an existing project and `init` for a complete new project:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
riverbankcms link --project ./my-site --account-env=staging --site <site-id> --preview
|
|
105
|
+
riverbankcms init ./my-site --account-env=staging --name "Dovetail" --preview
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Preview is explicit state. `--preview` includes preview routes and a preview
|
|
109
|
+
credential; `--no-preview` omits both. Interactive `init` asks for the choice;
|
|
110
|
+
JSON and other non-interactive mutations require an explicit choice and
|
|
111
|
+
`--yes`. Published CLI projects install packages from npm. Local/tarball
|
|
112
|
+
sources are test-fixture seams and are not public flags.
|
|
113
|
+
|
|
114
|
+
Generated projects are provider-neutral and contain only Riverbank project
|
|
115
|
+
configuration. The account refresh session is never written to the project
|
|
116
|
+
env file, and no database-provider URL, provider auth token, or service-role
|
|
117
|
+
credential is scaffolded.
|
|
118
|
+
|
|
76
119
|
### setup plan
|
|
77
120
|
|
|
78
121
|
Show the safe site, key, user access, and env setup lifecycle for the selected environment.
|
|
@@ -88,10 +131,31 @@ riverbankcms setup plan --env=remote
|
|
|
88
131
|
riverbankcms setup plan --env=both --json
|
|
89
132
|
```
|
|
90
133
|
|
|
91
|
-
The setup planner is read-only. It
|
|
134
|
+
The setup planner is read-only. It reports which values are missing and shows
|
|
135
|
+
the supported lifecycle. Use `riverbankcms sites create`, `riverbankcms link`,
|
|
136
|
+
or `riverbankcms init` with an authenticated account session to create sites
|
|
137
|
+
and issue project credentials for the signed-in account. Use the dashboard to
|
|
138
|
+
grant access to additional users. SDK management keys are site-scoped and are
|
|
139
|
+
used for project sync; they cannot create sites or grant other users access.
|
|
92
140
|
|
|
93
141
|
Use this command when a project has missing `RIVERBANK_*_SITE_ID`, `RIVERBANK_*_DASHBOARD_URL`, or `RIVERBANK_*_MGMT_API_KEY` values, or when onboarding an existing remote site into an SDK repo.
|
|
94
142
|
|
|
143
|
+
### Post-deployment revalidation
|
|
144
|
+
|
|
145
|
+
`init` scaffolds `/api/revalidate` but does not register a webhook or write a
|
|
146
|
+
webhook secret. After the project has a public HTTPS origin, activate it
|
|
147
|
+
explicitly:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
riverbankcms webhooks setup \
|
|
151
|
+
--env=remote \
|
|
152
|
+
--url=https://www.example.com/api/revalidate \
|
|
153
|
+
--yes
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Until setup is complete, the generated site’s ISR interval is the freshness
|
|
157
|
+
fallback. Keep the one-time webhook secret in the deployment environment.
|
|
158
|
+
|
|
95
159
|
---
|
|
96
160
|
|
|
97
161
|
## Content Sync Commands
|
|
@@ -914,14 +978,14 @@ riverbankcms event get summer-fest
|
|
|
914
978
|
riverbankcms event upsert summer-fest --file ./content/events/summer-fest.json
|
|
915
979
|
riverbankcms event cancel summer-fest
|
|
916
980
|
riverbankcms event delete summer-fest --yes
|
|
917
|
-
riverbankcms event occurrence list summer-fest
|
|
918
|
-
riverbankcms event occurrence add summer-fest \
|
|
981
|
+
riverbankcms event occurrence list summer-fest summer-run
|
|
982
|
+
riverbankcms event occurrence add summer-fest summer-run \
|
|
919
983
|
--starts-at 2026-08-01T10:00 \
|
|
920
984
|
--duration-minutes 60
|
|
921
|
-
riverbankcms event occurrence update summer-fest <occurrence-uuid> \
|
|
985
|
+
riverbankcms event occurrence update summer-fest summer-run <occurrence-uuid> \
|
|
922
986
|
--capacity 20
|
|
923
|
-
riverbankcms event occurrence cancel summer-fest <occurrence-uuid>
|
|
924
|
-
riverbankcms event occurrence delete summer-fest <occurrence-uuid> --yes
|
|
987
|
+
riverbankcms event occurrence cancel summer-fest summer-run <occurrence-uuid>
|
|
988
|
+
riverbankcms event occurrence delete summer-fest summer-run <occurrence-uuid> --yes
|
|
925
989
|
```
|
|
926
990
|
|
|
927
991
|
`event upsert` and `push events` accept canonical event files with `path` and `blocks`. Events use native page authority: an `eventOffering` or `eventSeries` subject owns a page surface, and that surface owns its route, field content, publication state, and slots. `path` updates the page-surface route. `blocks` maps slot keys to surface-slot blocks, for example `blocks.main` for the built-in event template. Use stable block identifiers so repeat pushes update existing slot blocks safely. Unknown slot keys or block kinds fail validation; default slots accept enabled SDK `custom.*` blocks, while explicit template `allowedBlocks` lists remain authoritative. Ordinary editorial entries continue to use the separate `entry` commands and content-entry model described above.
|
|
@@ -932,7 +996,9 @@ riverbankcms event occurrence delete summer-fest <occurrence-uuid> --yes
|
|
|
932
996
|
series. Mutation commands always use the occurrence UUID shown by `list`; a
|
|
933
997
|
calendar date is never accepted as an identity.
|
|
934
998
|
|
|
935
|
-
- `list <event-identifier>` shows all future dates, including
|
|
999
|
+
- `list <event-identifier> <run-identifier>` shows all future dates, including
|
|
1000
|
+
cancelled dates. The parent Event and run are both explicit, so multi-run
|
|
1001
|
+
Events never rely on an ambiguous identifier.
|
|
936
1002
|
Add `--all` to include history or `--status scheduled|cancelled|completed` to
|
|
937
1003
|
filter. The CLI follows the API's bounded pages, while `--json` keeps the
|
|
938
1004
|
canonical UTC instants in its single result envelope.
|
|
@@ -75,16 +75,19 @@ content/
|
|
|
75
75
|
navigation.json # All navigation menus
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
### 5. Themes
|
|
78
|
+
### 5. Themes (Optional Opt-in)
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
CMS theme objects are optional. Fully headless sites use host-owned markup,
|
|
81
|
+
styles, and block overrides instead of loading a CMS theme or SDK runtime
|
|
82
|
+
styles. Use a theme only when the site intentionally opts into themed built-in
|
|
83
|
+
rendering or local theme iteration.
|
|
81
84
|
|
|
82
85
|
**Local file structure:**
|
|
83
86
|
|
|
84
87
|
```
|
|
85
88
|
content/
|
|
86
89
|
themes/
|
|
87
|
-
current.json #
|
|
90
|
+
current.json # Optional theme (pulled from CMS or edited locally)
|
|
88
91
|
```
|
|
89
92
|
|
|
90
93
|
### 6. Footer Content
|
|
@@ -130,6 +133,12 @@ content/
|
|
|
130
133
|
yoga-class.json # Event with schedule, pricing, venue/category refs
|
|
131
134
|
```
|
|
132
135
|
|
|
136
|
+
Event registration keeps the semantic `block.event-registration` kind. In the
|
|
137
|
+
fully headless default, register a host-owned `event-registration` override and
|
|
138
|
+
own its markup, accessibility, and styles. Use the public
|
|
139
|
+
`useHeadlessEventRegistrationFlow` controller from `@riverbankcms/sdk/bookings`
|
|
140
|
+
where it fits; controller support varies by functional block.
|
|
141
|
+
|
|
133
142
|
---
|
|
134
143
|
|
|
135
144
|
## Working with Identifiers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Getting Started with RiverbankCMS SDK
|
|
2
2
|
|
|
3
|
-
This site uses RiverbankCMS as a headless CMS. Content is managed through the Riverbank CLI.
|
|
3
|
+
This site uses RiverbankCMS as a fully headless CMS. Content is managed through the Riverbank CLI, while the host owns markup, styles, and block rendering.
|
|
4
4
|
|
|
5
5
|
## Quick Setup
|
|
6
6
|
|
|
@@ -36,12 +36,10 @@ content/
|
|
|
36
36
|
│ └── [content-type].json
|
|
37
37
|
├── pages/
|
|
38
38
|
│ └── [page-identifier].json
|
|
39
|
-
├── themes/
|
|
40
|
-
│ └── current.json
|
|
41
39
|
└── navigation.json
|
|
42
40
|
```
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
Themes are optional. Only add `content/themes/` when this site explicitly opts into CMS/local theme rendering; fully headless sites use the host-owned `SITE_RENDERING` override-only configuration and do not need a theme file. The CLI still supports pulling a theme when you choose that opt-in:
|
|
45
43
|
|
|
46
44
|
```bash
|
|
47
45
|
riverbankcms pull theme
|
|
@@ -76,11 +74,11 @@ Apply changes to the CMS:
|
|
|
76
74
|
riverbankcms push
|
|
77
75
|
```
|
|
78
76
|
|
|
79
|
-
## Local Theme Iteration (Edge-safe)
|
|
77
|
+
## Optional Local Theme Iteration (Edge-safe)
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
Fully headless sites do not load CMS themes or SDK runtime styles by default. If a site intentionally opts into themed built-in rendering, `createCatchAllPage()` can render local theme objects (and switch themes at runtime) without pushing theme changes to the CMS. See `cli-reference.md` for the legitimate theme pull/push commands and the SDK README for the `createCatchAllPage({ themes, themeSwitch })` API.
|
|
82
80
|
|
|
83
|
-
Event registration
|
|
81
|
+
Event registration keeps the semantic `block.event-registration` kind, but its UI is host-owned in the fully headless default. Register an `event-registration` override in `src/lib/block-overrides.tsx` and use the public `useHeadlessEventRegistrationFlow` controller from `@riverbankcms/sdk/bookings` where it fits; own the markup, accessibility, and styles in the host. Other functional blocks may have different public controller support, so check their SDK surface rather than assuming a controller exists for every kind.
|
|
84
82
|
|
|
85
83
|
## Key Documentation
|
|
86
84
|
|
|
@@ -90,7 +88,7 @@ Event registration blocks need both the SDK base stylesheet and a runtime theme
|
|
|
90
88
|
| `content-management.md` | How content is structured |
|
|
91
89
|
| `schema.md` | This site's content types and blocks (auto-generated) |
|
|
92
90
|
| `block-types.md` | Available block types (auto-generated) |
|
|
93
|
-
| `theme-schema.md` |
|
|
91
|
+
| `theme-schema.md` | Optional theme schema reference (auto-generated from Zod) |
|
|
94
92
|
| `workflows/` | Step-by-step guides for common tasks, including editor workflows |
|
|
95
93
|
| `workflows/agent-safe-sync.md` | Agent-safe dry-run, scoped push, and stale-content handling |
|
|
96
94
|
|
|
@@ -127,13 +125,13 @@ Additional content configuration for scaffolding.
|
|
|
127
125
|
|
|
128
126
|
## Working with Remote/Production
|
|
129
127
|
|
|
130
|
-
If the remote site
|
|
128
|
+
If the remote site or project management key is not set up yet, start with the safe setup planner:
|
|
131
129
|
|
|
132
130
|
```bash
|
|
133
131
|
riverbankcms setup plan --env=remote
|
|
134
132
|
```
|
|
135
133
|
|
|
136
|
-
See `workflows/remote-setup.md` for the full site/key/user lifecycle. The Riverbank CLI
|
|
134
|
+
See `workflows/remote-setup.md` for the full site/key/user lifecycle. The authenticated Riverbank CLI can create a site and link project credentials for the signed-in account. Use the dashboard to grant access to additional users.
|
|
137
135
|
|
|
138
136
|
Use `--env=remote` to target production instead of local:
|
|
139
137
|
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This workflow guides you through adding a block to an existing page.
|
|
4
4
|
|
|
5
|
+
Generated sites use fully headless, override-only rendering by default. Keep
|
|
6
|
+
the built-in semantic kind in CMS content (for example, `block.hero` or
|
|
7
|
+
`block.body-text`), then register the host-owned renderer for every kind the
|
|
8
|
+
site uses in `src/lib/block-overrides.tsx`. The registry uses short semantic
|
|
9
|
+
keys such as `hero`; an unregistered kind raises `MissingBlockOverrideError`
|
|
10
|
+
instead of falling back to a built-in renderer.
|
|
11
|
+
|
|
5
12
|
## Prerequisites
|
|
6
13
|
|
|
7
14
|
- Page already exists in the CMS
|
|
@@ -25,7 +32,7 @@ View built-in blocks in `block-types.md`. Common block kinds:
|
|
|
25
32
|
|
|
26
33
|
Check `schema.md` for custom blocks specific to this site.
|
|
27
34
|
|
|
28
|
-
Prefer built-in blocks before creating a custom block. For a simple policy/terms/about page, use `block.body-text` and put the page title, intro, and section headings in the rich text body. Only create a custom block when the needed structure or behavior cannot be represented by built-in blocks plus styling.
|
|
35
|
+
Prefer built-in blocks before creating a custom block. For a simple policy/terms/about page, use `block.body-text` and put the page title, intro, and section headings in the rich text body. Only create a custom block when the needed structure or behavior cannot be represented by built-in blocks plus a host-owned override or styling.
|
|
29
36
|
|
|
30
37
|
### 2. List Existing Blocks
|
|
31
38
|
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Add layout variants and custom fields to built-in system blocks without creating entirely new custom blocks.
|
|
4
4
|
|
|
5
|
+
In a fully headless generated site, the CMS kind remains a built-in semantic
|
|
6
|
+
kind such as `block.hero`; the host owns how that kind is rendered. Register
|
|
7
|
+
the host component for the kind in `src/lib/block-overrides.tsx` after adding
|
|
8
|
+
the extension. An extension changes the content contract, not the rendering
|
|
9
|
+
authority.
|
|
10
|
+
|
|
5
11
|
## When to Use Block Extensions
|
|
6
12
|
|
|
7
13
|
**Use block extensions when:**
|
|
@@ -24,7 +30,7 @@ See `.riverbank/docs/block-types.md` for which system blocks support variants an
|
|
|
24
30
|
## Prerequisites
|
|
25
31
|
|
|
26
32
|
- `riverbank.config.ts` exists
|
|
27
|
-
-
|
|
33
|
+
- Host override registry set up (e.g., `src/lib/block-overrides.tsx`)
|
|
28
34
|
- Understanding of the system block you're extending
|
|
29
35
|
|
|
30
36
|
## Steps
|
|
@@ -103,18 +109,23 @@ export function CustomHero({ content, ...props }: BlockOverrideProps<ExtendedHer
|
|
|
103
109
|
}
|
|
104
110
|
```
|
|
105
111
|
|
|
106
|
-
### Step 3: Register in blockOverrides
|
|
112
|
+
### Step 3: Register in `blockOverrides`
|
|
107
113
|
|
|
108
|
-
Add your override component to the
|
|
114
|
+
Add your host-owned override component to the typed registration map. The CMS
|
|
115
|
+
content continues to use `block.hero`; `hero` is the corresponding short
|
|
116
|
+
registry key.
|
|
109
117
|
|
|
110
118
|
```typescript
|
|
111
119
|
// src/lib/block-overrides.tsx
|
|
112
|
-
import
|
|
120
|
+
import {
|
|
121
|
+
defineBlockOverrideRegistrations,
|
|
122
|
+
type BlockOverrideRegistrations,
|
|
123
|
+
} from '@riverbankcms/sdk/rendering';
|
|
113
124
|
import { CustomHero } from '@/components/CustomHero';
|
|
114
125
|
|
|
115
|
-
export const blockOverrides
|
|
126
|
+
export const blockOverrides = defineBlockOverrideRegistrations({
|
|
116
127
|
hero: CustomHero,
|
|
117
|
-
};
|
|
128
|
+
}) satisfies BlockOverrideRegistrations;
|
|
118
129
|
```
|
|
119
130
|
|
|
120
131
|
### Step 4: Push Config
|
|
@@ -323,6 +334,11 @@ blockFieldExtensions: {
|
|
|
323
334
|
**Override component:**
|
|
324
335
|
|
|
325
336
|
```typescript
|
|
337
|
+
import {
|
|
338
|
+
defineBlockOverrideRegistrations,
|
|
339
|
+
type BlockOverrideRegistrations,
|
|
340
|
+
} from '@riverbankcms/sdk/rendering';
|
|
341
|
+
|
|
326
342
|
type ExtendedHeroContent = HeroContent & {
|
|
327
343
|
layout?: 'default' | 'topography';
|
|
328
344
|
topographyColor?: 'teal' | 'green' | 'tan' | 'brown';
|
|
@@ -338,9 +354,9 @@ const HeroOverride = (props: BlockOverrideProps<ExtendedHeroContent>) => {
|
|
|
338
354
|
return <CustomHeroWithCanvas {...props} />;
|
|
339
355
|
};
|
|
340
356
|
|
|
341
|
-
export const blockOverrides
|
|
357
|
+
export const blockOverrides = defineBlockOverrideRegistrations({
|
|
342
358
|
hero: HeroOverride,
|
|
343
|
-
};
|
|
359
|
+
}) satisfies BlockOverrideRegistrations;
|
|
344
360
|
```
|
|
345
361
|
|
|
346
362
|
## Troubleshooting
|
|
@@ -359,7 +375,7 @@ export const blockOverrides: BlockOverrides = {
|
|
|
359
375
|
|
|
360
376
|
### Override component not rendering
|
|
361
377
|
|
|
362
|
-
- Verify the override is registered in `blockOverrides`
|
|
378
|
+
- Verify the host override is registered in `blockOverrides`
|
|
363
379
|
- Check the key matches the block name (e.g., `hero` for `block.hero`)
|
|
364
380
|
- Ensure the component is exported correctly
|
|
365
381
|
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Create a site-specific block with custom fields and rendering when system blocks don't meet your needs.
|
|
4
4
|
|
|
5
|
+
Generated sites are fully headless by default: custom block kinds are content
|
|
6
|
+
semantics, while the host owns their markup and styles. Register each custom
|
|
7
|
+
kind in the host override registry; missing registrations fail visibly instead
|
|
8
|
+
of falling back to a CMS renderer.
|
|
9
|
+
|
|
5
10
|
## When to Use Custom Blocks
|
|
6
11
|
|
|
7
12
|
Before creating a custom block, check `block-types.md` and the site `schema.md`. Many content needs are already covered by system blocks:
|
|
@@ -26,7 +31,7 @@ Do not create a custom block just to get “a rich text area with different spac
|
|
|
26
31
|
## Prerequisites
|
|
27
32
|
|
|
28
33
|
- `riverbank.config.ts` exists
|
|
29
|
-
-
|
|
34
|
+
- Host override registry set up (e.g., `src/lib/block-overrides.tsx`)
|
|
30
35
|
- Understanding of the content structure you need
|
|
31
36
|
|
|
32
37
|
## Steps
|
|
@@ -163,18 +168,40 @@ export function OurFlowBlock({ content }: BlockOverrideProps<OurFlowContent>) {
|
|
|
163
168
|
}
|
|
164
169
|
```
|
|
165
170
|
|
|
166
|
-
### Step 4: Register in blockOverrides
|
|
171
|
+
### Step 4: Register in `blockOverrides`
|
|
167
172
|
|
|
168
|
-
|
|
173
|
+
Register the host component with the typed registrations helper. The CMS
|
|
174
|
+
content keeps the semantic `custom.our-flow` kind.
|
|
169
175
|
|
|
170
176
|
```typescript
|
|
171
177
|
// src/lib/block-overrides.tsx
|
|
172
|
-
import
|
|
178
|
+
import {
|
|
179
|
+
defineBlockOverrideRegistrations,
|
|
180
|
+
type BlockOverrideRegistrations,
|
|
181
|
+
} from '@riverbankcms/sdk/rendering';
|
|
173
182
|
import { OurFlowBlock } from '@/components/OurFlowBlock';
|
|
174
183
|
|
|
175
|
-
export const blockOverrides
|
|
184
|
+
export const blockOverrides = defineBlockOverrideRegistrations({
|
|
176
185
|
'custom.our-flow': OurFlowBlock,
|
|
177
|
-
};
|
|
186
|
+
}) satisfies BlockOverrideRegistrations;
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
For client-heavy or rarely used blocks, wrap the dynamic import with
|
|
190
|
+
`defineLazyBlockOverride` so the component is loaded only when its kind is
|
|
191
|
+
rendered:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import {
|
|
195
|
+
defineBlockOverrideRegistrations,
|
|
196
|
+
defineLazyBlockOverride,
|
|
197
|
+
type BlockOverrideRegistrations,
|
|
198
|
+
} from '@riverbankcms/sdk/rendering';
|
|
199
|
+
|
|
200
|
+
export const blockOverrides = defineBlockOverrideRegistrations({
|
|
201
|
+
'custom.our-flow': defineLazyBlockOverride(async () =>
|
|
202
|
+
import('@/components/OurFlowBlock').then((module) => module.OurFlowBlock),
|
|
203
|
+
),
|
|
204
|
+
}) satisfies BlockOverrideRegistrations;
|
|
178
205
|
```
|
|
179
206
|
|
|
180
207
|
### Step 5: Push Config
|
|
@@ -453,8 +480,8 @@ Pricing cards with nested features and conditional button actions:
|
|
|
453
480
|
|
|
454
481
|
### Component not rendering
|
|
455
482
|
|
|
456
|
-
- Verify override is registered with exact block ID
|
|
457
|
-
- Check the key in `blockOverrides` matches (e.g., `'custom.our-flow'`)
|
|
483
|
+
- Verify the host override is registered with the exact block ID
|
|
484
|
+
- Check the key in `blockOverrides` matches the semantic kind (e.g., `'custom.our-flow'`)
|
|
458
485
|
- Ensure component is exported correctly
|
|
459
486
|
|
|
460
487
|
### Repeater items not working
|
|
@@ -7,12 +7,13 @@ Configure a Riverbank SDK Next.js App Router site to prerender published routes,
|
|
|
7
7
|
## Prerequisites
|
|
8
8
|
|
|
9
9
|
- A Riverbank SDK site using `createCatchAllPage()` in `src/app/[[...slug]]/page.tsx`.
|
|
10
|
-
- A
|
|
11
|
-
- `RIVERBANK_SITE_ID` set to this site's Riverbank site ID.
|
|
12
|
-
- `NEXT_PUBLIC_DASHBOARD_URL` set to the dashboard origin, for example `https://cms.example.com`.
|
|
10
|
+
- A configured `getRiverbankClient()` helper and `siteId` in `riverbank.config.ts`.
|
|
13
11
|
- `RIVERBANK_WEBHOOK_SECRET` set from the CMS-generated Riverbank webhook secret.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
Sites scaffolded with preview support should set `RIVERBANK_PREVIEW_MODE=true` in
|
|
14
|
+
preview deployments. The SDK preview integration reads the request-bound preview
|
|
15
|
+
session and opts those requests into dynamic rendering; the literal ISR interval
|
|
16
|
+
remains unchanged.
|
|
16
17
|
|
|
17
18
|
## Configure the Catch-All Route
|
|
18
19
|
|
|
@@ -21,21 +22,26 @@ In `src/app/[[...slug]]/page.tsx`:
|
|
|
21
22
|
```tsx
|
|
22
23
|
import {
|
|
23
24
|
createCatchAllPage,
|
|
24
|
-
|
|
25
|
-
getISRConfig,
|
|
25
|
+
createGenerateStaticParams,
|
|
26
26
|
} from '@riverbankcms/sdk/next'
|
|
27
27
|
|
|
28
28
|
import config from '@/riverbank.config'
|
|
29
29
|
import { blockOverrides } from '@/lib/block-overrides'
|
|
30
30
|
import { getRiverbankClient } from '@/lib/riverbank-client'
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
// Next.js route config values must remain statically analyzable literals.
|
|
33
|
+
export const revalidate = 300
|
|
33
34
|
export const dynamicParams = true
|
|
34
|
-
export
|
|
35
|
+
export const generateStaticParams = createGenerateStaticParams({
|
|
36
|
+
getClient: getRiverbankClient,
|
|
37
|
+
siteId: config.siteId,
|
|
38
|
+
failureMode: 'throw',
|
|
39
|
+
})
|
|
35
40
|
|
|
36
41
|
const { Page, generateMetadata } = createCatchAllPage({
|
|
37
42
|
getClient: getRiverbankClient,
|
|
38
43
|
config,
|
|
44
|
+
searchParamsMode: 'ignore',
|
|
39
45
|
blockOverrides,
|
|
40
46
|
})
|
|
41
47
|
|
|
@@ -43,7 +49,18 @@ export default Page
|
|
|
43
49
|
export { generateMetadata }
|
|
44
50
|
```
|
|
45
51
|
|
|
46
|
-
`
|
|
52
|
+
`searchParamsMode: 'ignore'` is required for this ISR shape because reading the
|
|
53
|
+
Next.js page `searchParams` prop opts the route into dynamic rendering. Use the
|
|
54
|
+
default `dynamic` mode only when server-rendered themes, data loaders, redirects,
|
|
55
|
+
or metadata genuinely depend on URL query parameters.
|
|
56
|
+
|
|
57
|
+
`createGenerateStaticParams()` uses the site's configured client to discover
|
|
58
|
+
published pages and routable entries at build time. The example uses strict
|
|
59
|
+
failure handling so production CI cannot silently publish an incomplete route
|
|
60
|
+
set.
|
|
61
|
+
|
|
62
|
+
If a site instead uses the SDK's generic environment variable names,
|
|
63
|
+
`generateAllStaticParams()` is available. It reads:
|
|
47
64
|
|
|
48
65
|
- `RIVERBANK_API_KEY`
|
|
49
66
|
- `RIVERBANK_SITE_ID`
|
|
@@ -59,21 +76,6 @@ export function generateStaticParams() {
|
|
|
59
76
|
}
|
|
60
77
|
```
|
|
61
78
|
|
|
62
|
-
If your site already centralizes the SDK client, use the explicit factory:
|
|
63
|
-
|
|
64
|
-
```tsx
|
|
65
|
-
import { createGenerateStaticParams } from '@riverbankcms/sdk/next'
|
|
66
|
-
|
|
67
|
-
import config from '@/riverbank.config'
|
|
68
|
-
import { getRiverbankClient } from '@/lib/riverbank-client'
|
|
69
|
-
|
|
70
|
-
export const generateStaticParams = createGenerateStaticParams({
|
|
71
|
-
getClient: getRiverbankClient,
|
|
72
|
-
siteId: config.siteId,
|
|
73
|
-
failureMode: 'throw',
|
|
74
|
-
})
|
|
75
|
-
```
|
|
76
|
-
|
|
77
79
|
## Add the Revalidation Route
|
|
78
80
|
|
|
79
81
|
Create `src/app/api/revalidate/route.ts`:
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
Enable dashboard preview editing for an SDK-hosted Next.js site. Preview mode lets the dashboard open the external site with a short-lived editor session, render draft content, and show the Riverbank preview shell.
|
|
6
6
|
|
|
7
|
+
The generated fully headless site keeps `SITE_RENDERING` as the rendering
|
|
8
|
+
authority in both the live catch-all route and this preview path. Preserve its
|
|
9
|
+
`overrides-only`/`runtime: none` contract when adding preview behavior: preview
|
|
10
|
+
changes the content/session source, not who owns block markup and styles.
|
|
11
|
+
|
|
7
12
|
## Prerequisites
|
|
8
13
|
|
|
9
14
|
- A Riverbank SDK site using the Next.js App Router.
|
|
@@ -111,13 +116,20 @@ import {
|
|
|
111
116
|
} from '@riverbankcms/sdk/preview-next/client'
|
|
112
117
|
|
|
113
118
|
import { blockOverrides } from '@/lib/block-overrides'
|
|
119
|
+
import { SITE_RENDERING } from '@/lib/rendering'
|
|
114
120
|
|
|
115
121
|
export function SdkPreviewModeClient(
|
|
116
122
|
props: SdkPreviewModePropsWithoutBlockOverrides
|
|
117
123
|
) {
|
|
124
|
+
const { themeRuntime: _themeRuntime, ...previewProps } = props
|
|
125
|
+
|
|
118
126
|
return (
|
|
119
127
|
<PreviewQueryProvider>
|
|
120
|
-
<SdkPreviewMode
|
|
128
|
+
<SdkPreviewMode
|
|
129
|
+
{...previewProps}
|
|
130
|
+
rendering={SITE_RENDERING}
|
|
131
|
+
blockOverrides={blockOverrides}
|
|
132
|
+
/>
|
|
121
133
|
</PreviewQueryProvider>
|
|
122
134
|
)
|
|
123
135
|
}
|
|
@@ -134,11 +146,13 @@ import { createPreviewModeBeforeRender } from '@riverbankcms/sdk/preview-next/be
|
|
|
134
146
|
import config from '../../../riverbank.config'
|
|
135
147
|
import { blockOverrides } from '@/lib/block-overrides'
|
|
136
148
|
import { getRiverbankClient } from '@/lib/riverbank-client'
|
|
149
|
+
import { SITE_RENDERING } from '@/lib/rendering'
|
|
137
150
|
import { SdkPreviewModeClient } from '@/components/preview/SdkPreviewModeClient'
|
|
138
151
|
|
|
139
152
|
const { Page, generateMetadata } = createCatchAllPage({
|
|
140
153
|
getClient: getRiverbankClient,
|
|
141
154
|
config,
|
|
155
|
+
rendering: SITE_RENDERING,
|
|
142
156
|
blockOverrides,
|
|
143
157
|
beforeRender: createPreviewModeBeforeRender({
|
|
144
158
|
getClient: getRiverbankClient,
|
|
@@ -151,9 +165,16 @@ export default Page
|
|
|
151
165
|
export { generateMetadata }
|
|
152
166
|
```
|
|
153
167
|
|
|
154
|
-
## Custom
|
|
168
|
+
## Optional Custom Preview Chrome
|
|
155
169
|
|
|
156
|
-
|
|
170
|
+
Fully headless generated sites keep a plain host-owned root layout. If the host
|
|
171
|
+
replaces the preview header or footer, pass that chrome into
|
|
172
|
+
`PreviewLayoutProvider` only when there is an editable preview session.
|
|
173
|
+
`RIVERBANK_PREVIEW_MODE=true` makes the route preview-capable, but
|
|
174
|
+
`getPreviewSession()` tells you whether the current request actually has
|
|
175
|
+
preview cookies. Regular visitors without preview cookies should keep the
|
|
176
|
+
site's normal layout. The `Layout` example below is only for a site that
|
|
177
|
+
intentionally opts into themed SDK rendering.
|
|
157
178
|
|
|
158
179
|
In `src/app/layout.tsx`:
|
|
159
180
|
|
|
@@ -212,9 +233,12 @@ export default async function RootLayout({
|
|
|
212
233
|
|
|
213
234
|
If your custom chrome needs CMS navigation data, build the `headerNode` and `footerNode` from the same data used by your normal layout before branching. Calling `getPreviewSession()` in the root layout reads cookies, so the layout becomes dynamic.
|
|
214
235
|
|
|
215
|
-
## Import Preview CSS
|
|
236
|
+
## Import Preview Editor Chrome CSS
|
|
216
237
|
|
|
217
|
-
|
|
238
|
+
Preview-enabled sites need the SDK preview editor chrome styles even when they
|
|
239
|
+
are fully headless. These imports provide the preview shell and editor chrome;
|
|
240
|
+
they are not the CMS theme or built-in block styles. A Tailwind site can add
|
|
241
|
+
this to `src/app/globals.css`:
|
|
218
242
|
|
|
219
243
|
```css
|
|
220
244
|
@import 'tailwindcss';
|
|
@@ -222,7 +246,7 @@ For Tailwind sites, add this to `src/app/globals.css`:
|
|
|
222
246
|
@import '@riverbankcms/sdk/preview-next/chrome.css';
|
|
223
247
|
```
|
|
224
248
|
|
|
225
|
-
For non-Tailwind sites, use the legacy single import:
|
|
249
|
+
For non-Tailwind sites, use the legacy single preview-chrome import:
|
|
226
250
|
|
|
227
251
|
```css
|
|
228
252
|
@import '@riverbankcms/sdk/preview-next/styles.css';
|