Update Layout Template System Guidelines
parent
7ecbb5c4de
commit
410716276d
|
|
@ -38,3 +38,150 @@ The Layout System is comprised of following modules:
|
||||||
### Goal
|
### Goal
|
||||||
* **Only the Json File** is responsible for layout and design for the pages
|
* **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**.
|
* 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 JSON‑driven 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`: route‑specific 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:13–28`
|
||||||
|
- Component map: `src/vibentec/component-map.tsx:76–112`
|
||||||
|
- Renderer: `src/vibentec/renderer.tsx:8–28`
|
||||||
|
- App layout usage: `src/app/[countryCode]/(main)/layout.tsx:34–45`
|
||||||
|
- Page usage (Home): `src/app/[countryCode]/(main)/page.tsx:27–42`
|
||||||
|
- Page usage (Product): `src/app/[countryCode]/(main)/products/[handle]/page.tsx:102–121`
|
||||||
|
|
||||||
|
## 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:2–18, 188–236`.
|
||||||
|
|
||||||
|
## Render Flow
|
||||||
|
|
||||||
|
- App layout loads `layout` via `loadLayoutConfig` and renders it once for all routes: `src/app/[countryCode]/(main)/layout.tsx:34–45`.
|
||||||
|
- 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:27–42`.
|
||||||
|
|
||||||
|
### Example: Product
|
||||||
|
|
||||||
|
- Renders `ProductTemplate`, then appends `pages["Product"]` below: `src/app/[countryCode]/(main)/products/[handle]/page.tsx:115–121`.
|
||||||
|
|
||||||
|
## Configuring Components
|
||||||
|
|
||||||
|
- Components accept a `config` object and optional `children` arrays.
|
||||||
|
- Map of available keys is defined in `componentMap`: `src/vibentec/component-map.tsx:76–112`.
|
||||||
|
- 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 page’s own React content.
|
||||||
|
- Keep it in `layout` so page templates render inside the global shell.
|
||||||
|
|
||||||
|
## Adding Page‑Specific 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:76–112`.
|
||||||
|
|
||||||
|
## Selecting a Design File
|
||||||
|
|
||||||
|
- Switch the active JSON file name in `src/vibentec/devJsonFileNames.ts:1–8` and update `fileName` in `src/vibentec/configloader.ts:5` if needed.
|
||||||
|
- Current active file: `jsonFileNames.namStarter`.
|
||||||
|
|
||||||
|
## Backward Compatibility
|
||||||
|
|
||||||
|
- If the JSON is a top‑level 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:16–22`.
|
||||||
|
- 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 route‑specific UI under `pages[Key]`.
|
||||||
|
- Verify page files call `loadPageConfig("Key")` and render `DynamicLayoutRenderer`.
|
||||||
|
- Confirm `componentMap` includes the JSON keys you use.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue