Update Layout Template System Guidelines

namds29 2025-12-25 03:25:09 +00:00
parent 7ecbb5c4de
commit 410716276d
1 changed files with 147 additions and 0 deletions

@ -38,3 +38,150 @@ The Layout System is comprised of following modules:
### Goal
* **Only the Json File** is responsible for layout and design for the pages
* Dynamic Render System uses json-file to build layout and page using **shared dynamic components**.
# Layout Template System Guidelines
This guide explains how to configure and use the JSONdriven layout and page template system so UI components render only on the routes you intend.
## Concepts
- `layout`: global UI rendered around all pages (header, nav, `PropsChildren`, footer).
- `pages`: routespecific UI, configured per page key (e.g., `Home`, `Product`).
- `DynamicLayoutRenderer`: reads nodes and renders mapped React components.
- `componentMap`: maps JSON keys to components and determines how `config` and `children` are passed.
## Files
- Design JSON: `config/nam.mds-starter-design.json`
- Loader functions: `src/vibentec/configloader.ts:1328`
- Component map: `src/vibentec/component-map.tsx:76112`
- Renderer: `src/vibentec/renderer.tsx:828`
- App layout usage: `src/app/[countryCode]/(main)/layout.tsx:3445`
- Page usage (Home): `src/app/[countryCode]/(main)/page.tsx:2742`
- Page usage (Product): `src/app/[countryCode]/(main)/products/[handle]/page.tsx:102121`
## JSON Schema
Structure of the design file:
```json
{
"layout": [
{ "Header": { "config": { "sticky": true }, "children": [/* ... */] } },
{ "PropsChildren": {} },
{ "Footer": { "config": { /* footer columns */ } } }
],
"pages": {
"Home": [
{ "Hero": { "config": { "variant": "default", "className": "bg-custom-gradient" } } },
{ "VtFeaturedProducts": { "config": { "title": "best-seller" } } },
{ "FreeShippingPriceNudge": { "config": { "variant": "popup" } } }
],
"Product": [
{ "VtFeaturedProducts": { "config": { "title": "best-seller" } } }
]
}
}
```
See: `config/nam.mds-starter-design.json:218, 188236`.
## Render Flow
- App layout loads `layout` via `loadLayoutConfig` and renders it once for all routes: `src/app/[countryCode]/(main)/layout.tsx:3445`.
- Each page loads its array via `loadPageConfig("Key")` and renders it where needed.
### Example: Home
- Loads and renders `pages["Home"]` with a layout context containing `region` and `countryCode`: `src/app/[countryCode]/(main)/page.tsx:2742`.
### Example: Product
- Renders `ProductTemplate`, then appends `pages["Product"]` below: `src/app/[countryCode]/(main)/products/[handle]/page.tsx:115121`.
## Configuring Components
- Components accept a `config` object and optional `children` arrays.
- Map of available keys is defined in `componentMap`: `src/vibentec/component-map.tsx:76112`.
- Two mapping strategies:
- `configOnly(Component)`: passes `config` props directly (e.g., banners like `CartMismatchBanner`).
- `nodesContextRenderer(Component)`: passes both `nodes` and rendering `context` (most layout templates).
### `VtFeaturedProducts`
- Place it under a page key to control visibility.
- `config.title` can be a collection `handle` or `title` to filter rails.
- Uses `region` and `countryCode` from the page context.
Example:
```json
{
"pages": {
"Home": [
{ "VtFeaturedProducts": { "config": { "title": "best-seller" } } }
],
"Product": [
{ "VtFeaturedProducts": { "config": { "title": "best-seller" } } }
]
}
}
```
### `Hero`
- Configure variant and class names under the `Home` page to show only on the front page.
### `PropsChildren`
- Acts as a slot for the pages own React content.
- Keep it in `layout` so page templates render inside the global shell.
## Adding PageSpecific UI
- Choose a page key like `Home`, `Product`, `Category`, `Collection`, `Store`.
- Add an array under `pages[Key]` with your components.
- In the corresponding page file, load and render:
```ts
import { DynamicLayoutRenderer } from "@vibentec/renderer"
import { loadPageConfig } from "@vibentec/configloader"
import { LayoutContext } from "@vibentec/component-map"
const nodes = await loadPageConfig("Home")
const context: LayoutContext = { /* region, countryCode, etc. */ }
return <DynamicLayoutRenderer nodes={nodes} context={context} />
```
## Adding New Components
- Implement a template component that accepts `{ nodes, context }`.
- Register the JSON key in `componentMap` using either `nodesContextRenderer` or `configOnly`.
- Example map entry: `src/vibentec/component-map.tsx:76112`.
## Selecting a Design File
- Switch the active JSON file name in `src/vibentec/devJsonFileNames.ts:18` and update `fileName` in `src/vibentec/configloader.ts:5` if needed.
- Current active file: `jsonFileNames.namStarter`.
## Backward Compatibility
- If the JSON is a toplevel array (legacy schema), loaders treat it as `layout` and `pages` resolve to empty arrays. Migrate incrementally by introducing `pages` per route.
## Troubleshooting
- Unknown component key logs a warning in the renderer: `src/vibentec/renderer.tsx:1622`.
- Empty or missing `pages[Key]` renders nothing for that route.
- Ensure page context includes `region` and `countryCode` when components depend on them.
## Configuration Checklist
- Update your design JSON with `layout` and `pages` keys.
- Keep global UI under `layout`; place routespecific UI under `pages[Key]`.
- Verify page files call `loadPageConfig("Key")` and render `DynamicLayoutRenderer`.
- Confirm `componentMap` includes the JSON keys you use.