cms-renderer 0.0.0

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.
@@ -0,0 +1,2 @@
1
+
2
+ $ tsc --noEmit
package/README.md ADDED
@@ -0,0 +1,362 @@
1
+ # Website
2
+
3
+ **CMS-powered website built with Next.js 15 and App Router**
4
+
5
+ ```
6
+ CMS (authors content) --> tRPC API --> Website (renders blocks)
7
+ ```
8
+
9
+ The website app fetches structured page data via tRPC and renders blocks using the ComponentMap pattern. Article content uses WASM-powered markdown rendering for performance.
10
+
11
+ ---
12
+
13
+ ## Quick Start
14
+
15
+ **Prerequisites**
16
+
17
+ | Tool | Version | Check Command |
18
+ |------|---------|---------------|
19
+ | Bun | 1.2.8+ | `bun --version` |
20
+ | Node.js | 18+ | `node --version` |
21
+
22
+ **Installation**
23
+
24
+ ```bash
25
+ # From monorepo root
26
+ bun install
27
+
28
+ # Start the website dev server
29
+ cd apps/website
30
+ bun run dev
31
+ ```
32
+
33
+ **Verification**
34
+
35
+ Open [http://localhost:3001](http://localhost:3001). You should see:
36
+
37
+ ```
38
+ Website
39
+ CMS-powered website built with Next.js 15 and App Router.
40
+ ```
41
+
42
+ Visit [http://localhost:3001/demo](http://localhost:3001/demo) to see the complete demo page with navigation, header, and article blocks.
43
+
44
+ ---
45
+
46
+ ## Architecture
47
+
48
+ ### How This App Fits in the Monorepo
49
+
50
+ ```
51
+ auteur/
52
+ ├── apps/
53
+ │ ├── cms/ # Content authoring (Lexical editor)
54
+ │ └── website/ # This app - renders CMS content
55
+ └── packages/
56
+ ├── cms-schema/ # Shared Zod schemas
57
+ └── markdown-wasm/ # WASM markdown renderer
58
+ ```
59
+
60
+ The website consumes schemas from `@repo/cms-schema` and uses `@repo/markdown-wasm` for article body rendering. It does not import from `apps/cms/` directly.
61
+
62
+ ### Key Directories
63
+
64
+ ```
65
+ apps/website/
66
+ ├── app/ # Next.js App Router pages
67
+ │ ├── [slug]/ # Dynamic page routes
68
+ │ │ ├── page.tsx # Server Component fetches via tRPC
69
+ │ │ ├── loading.tsx # Skeleton loading state
70
+ │ │ └── error.tsx # Error boundary
71
+ │ ├── api/trpc/[trpc]/ # tRPC API handler
72
+ │ ├── layout.tsx # Root layout with CSS imports
73
+ │ ├── globals.css # CSS reset
74
+ │ └── page.tsx # Homepage
75
+ ├── components/
76
+ │ ├── blocks/ # Block components + registry
77
+ │ │ ├── navigation-block.tsx
78
+ │ │ ├── header-block.tsx
79
+ │ │ ├── article-block.tsx
80
+ │ │ ├── block-renderer.tsx # Dispatcher component
81
+ │ │ ├── types.ts # BlockData discriminated union
82
+ │ │ └── index.ts # Exports + blockComponents registry
83
+ │ ├── page-renderer.tsx # Renders array of blocks
84
+ │ └── trpc-provider.tsx # Client-side tRPC/React Query
85
+ ├── server/
86
+ │ ├── trpc.ts # tRPC initialization
87
+ │ └── routers/
88
+ │ ├── blocks/ # Block data procedures
89
+ │ │ ├── get-navigation.ts
90
+ │ │ ├── get-header.ts
91
+ │ │ └── get-article.ts
92
+ │ └── pages/ # Page composition procedures
93
+ │ └── get-page.ts
94
+ ├── seed/ # Mock data for development
95
+ │ └── index.ts
96
+ ├── styles/
97
+ │ └── blocks.css # Vanilla CSS for blocks
98
+ └── lib/
99
+ └── trpc.ts # Client-side tRPC hooks
100
+ ```
101
+
102
+ ### Data Flow
103
+
104
+ ```
105
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
106
+ │ Dynamic Route │────>│ tRPC Caller │────>│ Mock Data │
107
+ │ [slug]/page │ │ pages.getPage │ │ seed/index.ts │
108
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
109
+
110
+ v
111
+ ┌─────────────────┐ ┌─────────────────┐
112
+ │ PageRenderer │────>│ BlockRenderer │
113
+ │ (iterates) │ │ (dispatches) │
114
+ └─────────────────┘ └─────────────────┘
115
+
116
+ ┌──────────────────────┼──────────────────────┐
117
+ v v v
118
+ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐
119
+ │ NavigationBlock│ │ HeaderBlock │ │ ArticleBlock │
120
+ │ │ │ │ │ (WASM markdown)│
121
+ └───────────────┘ └───────────────┘ └───────────────┘
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Development Guide
127
+
128
+ ### Available Scripts
129
+
130
+ | Script | Command | Description |
131
+ |--------|---------|-------------|
132
+ | `dev` | `bun run dev` | Start dev server on port 3001 |
133
+ | `build` | `bun run build` | Production build |
134
+ | `start` | `bun run start` | Start production server |
135
+ | `lint` | `bun run lint` | Run Biome linter |
136
+ | `check-types` | `bun run check-types` | TypeScript type checking |
137
+
138
+ ### Hot Reload Behavior
139
+
140
+ - **Page changes**: Instant hot reload
141
+ - **tRPC procedures**: Requires server restart
142
+ - **CSS changes**: Instant hot reload
143
+ - **Block components**: Instant hot reload
144
+
145
+ ### Environment Variables
146
+
147
+ No environment variables are required for development. The app uses mock data from `seed/index.ts`.
148
+
149
+ For production with a real database, you would add:
150
+
151
+ ```env
152
+ # .env.local (not required for development)
153
+ DATABASE_URL=your-database-url
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Key Concepts
159
+
160
+ ### ComponentMap Pattern
161
+
162
+ The website uses a registry-based pattern to map block types to React components:
163
+
164
+ ```typescript
165
+ // components/blocks/index.ts
166
+ export const blockComponents: BlockComponentRegistry = {
167
+ navigation: NavigationBlock,
168
+ header: HeaderBlock,
169
+ article: ArticleBlock,
170
+ } as const;
171
+ ```
172
+
173
+ The `BlockRenderer` uses this registry to dispatch blocks:
174
+
175
+ ```tsx
176
+ // Render any block by type
177
+ <BlockRenderer block={{ type: 'header', content: {...} }} />
178
+
179
+ // Render a page of blocks
180
+ {page.blocks.map((block, i) => (
181
+ <BlockRenderer key={i} block={block} />
182
+ ))}
183
+ ```
184
+
185
+ ### Block Types
186
+
187
+ | Block | Component | Content Fields |
188
+ |-------|-----------|----------------|
189
+ | `navigation` | `NavigationBlock` | logo, ariaLabel, links (3-level hierarchy) |
190
+ | `header` | `HeaderBlock` | headline, subheadline, backgroundImage, ctaButton, alignment |
191
+ | `article` | `ArticleBlock` | headline, author, publishedAt, body (markdown), tags |
192
+
193
+ ### tRPC Integration
194
+
195
+ **Server Component** (recommended):
196
+
197
+ ```tsx
198
+ // Direct procedure call in Server Components
199
+ import { createCaller } from '@/server/routers';
200
+ import { createContext } from '@/server/trpc';
201
+
202
+ export default async function Page({ params }: PageProps) {
203
+ const { slug } = await params;
204
+ const caller = createCaller(createContext());
205
+ const page = await caller.pages.getPage({ slug });
206
+
207
+ return <PageRenderer title={page.title} blocks={page.blocks} />;
208
+ }
209
+ ```
210
+
211
+ **Client Component** (when needed):
212
+
213
+ ```tsx
214
+ 'use client';
215
+ import { trpc } from '@/lib/trpc';
216
+
217
+ function PageClient({ slug }: { slug: string }) {
218
+ const { data, isLoading } = trpc.pages.getPage.useQuery({ slug });
219
+
220
+ if (isLoading) return <div>Loading...</div>;
221
+ return <PageRenderer title={data.title} blocks={data.blocks} />;
222
+ }
223
+ ```
224
+
225
+ ### WASM Markdown Rendering
226
+
227
+ The `ArticleBlock` uses `@repo/markdown-wasm` for fast markdown-to-React conversion:
228
+
229
+ ```tsx
230
+ import { MarkdownRenderer } from '@repo/markdown-wasm';
231
+
232
+ // Inside ArticleBlock
233
+ <MarkdownRenderer content={body} className="article-block__content" />
234
+ ```
235
+
236
+ md4w parses markdown 2.5x faster than JavaScript alternatives and outputs a traversable AST that maps directly to React components.
237
+
238
+ ---
239
+
240
+ ## API Routes Reference
241
+
242
+ ### tRPC Endpoints
243
+
244
+ | Endpoint | Method | Input | Returns |
245
+ |----------|--------|-------|---------|
246
+ | `blocks.getNavigation` | Query | None | Navigation data |
247
+ | `blocks.getHeader` | Query | None | Header data |
248
+ | `blocks.getArticle` | Query | None | Article data |
249
+ | `pages.getPage` | Query | `{ slug: string }` | Page with blocks array |
250
+
251
+ ### Testing Endpoints
252
+
253
+ ```bash
254
+ # Start the dev server
255
+ bun run dev
256
+
257
+ # Test endpoints (in another terminal)
258
+ curl "http://localhost:3001/api/trpc/blocks.getNavigation"
259
+ curl "http://localhost:3001/api/trpc/blocks.getHeader"
260
+ curl "http://localhost:3001/api/trpc/pages.getPage?input=%7B%22json%22%3A%7B%22slug%22%3A%22demo%22%7D%7D"
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Testing
266
+
267
+ The website app does not currently have unit tests. Integration testing is done via the tRPC endpoints.
268
+
269
+ ```bash
270
+ # Type check
271
+ bun run check-types
272
+
273
+ # Lint
274
+ bun run lint
275
+ ```
276
+
277
+ Test files would live at:
278
+ - `components/blocks/*.test.tsx` for block components
279
+ - `server/routers/**/*.test.ts` for tRPC procedures
280
+
281
+ ---
282
+
283
+ ## Troubleshooting
284
+
285
+ ### Port 3001 Already in Use
286
+
287
+ ```bash
288
+ # Find and kill the process
289
+ lsof -i :3001
290
+ kill -9 <PID>
291
+
292
+ # Or use a different port
293
+ bun run dev -- --port 3002
294
+ ```
295
+
296
+ ### Cannot Find Module '@repo/cms-schema'
297
+
298
+ ```bash
299
+ # Run bun install from monorepo root
300
+ cd ../..
301
+ bun install
302
+ ```
303
+
304
+ ### TypeScript Errors on First Run
305
+
306
+ The `.next/types` directory is generated on first dev server run:
307
+
308
+ ```bash
309
+ bun run dev # Run once to generate types
310
+ bun run check-types # Now type checking works
311
+ ```
312
+
313
+ ### WASM Module Not Found
314
+
315
+ If you see errors about md4w:
316
+
317
+ ```bash
318
+ # Rebuild the markdown-wasm package
319
+ cd ../../packages/markdown-wasm
320
+ bun install
321
+ bun run build
322
+ ```
323
+
324
+ ### tRPC 'NOT_FOUND' Error
325
+
326
+ The mock data only includes pages with slugs: `demo`, `about`, `blog`. Requesting other slugs returns a 404.
327
+
328
+ ---
329
+
330
+ ## Related Documentation
331
+
332
+ - **Tutorial**: [`_docs/cms-website-integration/`](../../_docs/cms-website-integration/00-overview.md) - Full 11-chapter tutorial
333
+ - **CMS App**: [`apps/cms/README.md`](../cms/README.md) - Content authoring application
334
+ - **Schema Package**: [`packages/cms-schema/`](../../packages/cms-schema/) - Shared Zod schemas
335
+ - **Markdown Package**: [`packages/markdown-wasm/`](../../packages/markdown-wasm/) - WASM renderer
336
+
337
+ ---
338
+
339
+ ## Contributing
340
+
341
+ ### Code Style
342
+
343
+ This project uses [Biome](https://biomejs.dev/) for linting and formatting:
344
+
345
+ ```bash
346
+ bun run lint # Check for issues
347
+ bun run lint --fix # Auto-fix issues
348
+ ```
349
+
350
+ ### Adding a New Block Type
351
+
352
+ 1. Define the schema in `apps/cms/app/schemas/`
353
+ 2. Add mock data to `seed/index.ts`
354
+ 3. Create the component in `components/blocks/`
355
+ 4. Add to `blockComponents` registry in `components/blocks/index.ts`
356
+ 5. Add the type to `BlockData` union in `components/blocks/types.ts`
357
+
358
+ ### Pull Requests
359
+
360
+ - Run `bun run check-types` before submitting
361
+ - Run `bun run lint` to ensure code style compliance
362
+ - Test the demo page at `/demo` renders correctly