diff --git a/Layout-Template-System-Guidelines.md b/Layout-Template-System-Guidelines.md index dbd14d1..dd4d7b5 100644 --- a/Layout-Template-System-Guidelines.md +++ b/Layout-Template-System-Guidelines.md @@ -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 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 +``` + +## 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. + + + + +