@se-studio/project-build 1.0.61 → 1.0.63

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @se-studio/project-build
2
2
 
3
+ ## 1.0.63
4
+
5
+ ### Patch Changes
6
+
7
+ - Bulk version bump: patch for all packages
8
+
9
+ ## 1.0.62
10
+
11
+ ### Patch Changes
12
+
13
+ - Bulk version bump: patch for all packages
14
+
3
15
  ## 1.0.61
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/project-build",
3
- "version": "1.0.61",
3
+ "version": "1.0.63",
4
4
  "description": "Build tools and management scripts for SE Studio projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: cms-routes-and-appshared
3
+ description: Guide for the (cms-routes) route group and appShared pattern. Use when setting up or migrating CMS-driven routing, creating new route segments, or refactoring page structure.
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # CMS Routes and appShared Pattern
11
+
12
+ Reference apps: **example-se2026**, **example-brightline**.
13
+
14
+ ## Route Group: (cms-routes)
15
+
16
+ All CMS-driven pages live under `src/app/(cms-routes)/`. The layout enables dynamic params:
17
+
18
+ ```tsx
19
+ // layout.tsx
20
+ export const dynamicParams = true;
21
+
22
+ export default function CmsRoutesLayout({ children }: { children: React.ReactNode }) {
23
+ return children;
24
+ }
25
+ ```
26
+
27
+ ## Route Structure
28
+
29
+ | Path | File | Purpose |
30
+ |------|------|---------|
31
+ | `/` | `page.ts` | Home (slug: `index`) |
32
+ | `/{slug}/` | `[level1]/page.ts` | Single-level page |
33
+ | `/{slug1}/{slug2}/...` | `[level1]/[...slugs]/page.ts` | Multi-level pages |
34
+ | `/articles/` | `articles/page.ts` | Articles index (uses ARTICLES_BASE) |
35
+ | `/articles/{type}/` | `articles/[articleType]/page.ts` | Article type index |
36
+ | `/articles/{type}/{tag}/` | `articles/[articleType]/[tag]/page.ts` | Article type + tag index |
37
+ | `/articles/{type}/{tag}/{article}/` | `articles/[articleType]/[tag]/[...slugs]/page.ts` | Individual article |
38
+ | `/tags/`, `/tags/{tag}/` | `tags/` | Tag index (if enabled) |
39
+ | `/people/`, `/people/{person}/` | `people/` | People (if enabled) |
40
+
41
+ Base paths come from `@/lib/constants` (e.g. ARTICLES_BASE = `/learning-hub` or `/articles`).
42
+
43
+ ## appShared Modules
44
+
45
+ Route files are thin wrappers. Logic lives in `src/appShared/`:
46
+
47
+ | Module | Exports | Used by |
48
+ |--------|---------|---------|
49
+ | `pageShared.tsx` | `generatePage`, `generatePageMetadata` | `/`, `[level1]`, `[level1]/[...slugs]` |
50
+ | `articleShared.tsx` | `generateArticlePage`, `generateArticleMetadata` | Article detail |
51
+ | `articleTypeShared.tsx` | `generateArticleTypePage`, `generateArticleTypeMetadata` | Article type index |
52
+ | `articleTypesIndexShared.tsx` | `generateArticleTypesIndexPage`, `generateArticleTypesIndexMetadata` | Articles index |
53
+ | `articleTypeTagShared.tsx` | `generateArticleTypeTagPage`, `generateArticleTypeTagMetadata` | Article type + tag index |
54
+ | `customTypeShared.tsx` | `generateCustomTypePage`, `generateCustomTypeMetadata` | Custom types |
55
+ | `personShared.tsx` | `generatePersonPage`, `generatePersonMetadata` | Person page |
56
+ | `tagShared.tsx` | `generateTagPage`, `generateTagMetadata` | Tag index |
57
+ | `tagsIndexShared.tsx` | `generateTagsIndexPage`, `generateTagsIndexMetadata` | Tags index |
58
+ | `teamIndexShared.tsx` | `generateTeamIndexPage`, `generateTeamIndexMetadata` | People index |
59
+
60
+ ## Route Page Pattern
61
+
62
+ Each route page:
63
+
64
+ 1. Exports `generateStaticParams() { return []; }` for dynamic routes
65
+ 2. Defines `extractDetails(props)` to derive slug/path from params
66
+ 3. Exports `generateMetadata(props, parent)` calling the shared metadata function
67
+ 4. Exports default async function calling the shared page function
68
+
69
+ ```typescript
70
+ import type { ResolvingMetadata } from 'next';
71
+ import { generatePage, generatePageMetadata } from '@/appShared/pageShared';
72
+
73
+ export function generateStaticParams() {
74
+ return [];
75
+ }
76
+
77
+ async function extractDetails(props: PageProps<'/[level1]'>) {
78
+ const params = await props.params;
79
+ const { level1 } = params;
80
+ return { slug: level1, path: `/${level1}/` };
81
+ }
82
+
83
+ export async function generateMetadata(props: PageProps<'/[level1]'>, parent: ResolvingMetadata) {
84
+ const { slug, path } = await extractDetails(props);
85
+ return generatePageMetadata(slug, path, true, parent);
86
+ }
87
+
88
+ export default async function (props: PageProps<'/[level1]'>) {
89
+ const { slug, path } = await extractDetails(props);
90
+ return generatePage(slug, path, true);
91
+ }
92
+ ```
93
+
94
+ For article routes, use `converterContext.urlCalculators.article`, `articleType`, `articleTypeTag` from `@/lib/cms-server` to compute the path.
95
+
96
+ ## See Also
97
+
98
+ - **create-page** – Creating new pages and routes
99
+ - **lib-cms-structure** – lib directory layout
@@ -87,7 +87,7 @@ import {
87
87
  import { SectionLinks } from '@/elements/SectionLinks';
88
88
  import { Section } from '@/framework/Section';
89
89
  import type { ICollection, IComponent, IContent } from '@/lib/cms';
90
- import { getPreviewFieldIdProps } from '@/lib/cms';
90
+ import { getPreviewFieldIdProps } from '@/lib/cms-server';
91
91
  import { getSizingInformation } from '@/lib/SizingInformation';
92
92
  // import MyCollectionClient from './MyCollectionClient'; // If needed
93
93
 
@@ -280,4 +280,4 @@ export const MyCollectionRegistration = defineCollection({
280
280
  * If a carousel/slider/filter is needed, move that logic to `[Name]Client.tsx`.
281
281
  * Pass server-rendered cards as `children` to the client wrapper.
282
282
  5. **Register**:
283
- * Add to `componentRegistrations` in `src/lib/cms.ts`.
283
+ * Add to `collectionRegistrations` in `src/lib/registrations.ts`.
@@ -78,7 +78,7 @@ import {
78
78
  import { SectionLinks } from '@/elements/SectionLinks';
79
79
  import { Section } from '@/framework/Section';
80
80
  import type { IComponent, IContent } from '@/lib/cms';
81
- import { getPreviewFieldIdProps } from '@/lib/cms';
81
+ import { getPreviewFieldIdProps } from '@/lib/cms-server';
82
82
  import { getSizingInformation } from '@/lib/SizingInformation';
83
83
  // If interactivity is needed:
84
84
  // import MyNewComponentClient from './MyNewComponentClient';
@@ -242,4 +242,4 @@ export const MyNewRegistration = defineComponent({
242
242
  * **CRITICAL**: `name` must match CMS `componentType` exactly.
243
243
  * Provide mock data for showcase.
244
244
  8. **Register Component**:
245
- * Add to `componentRegistrations` array in `src/lib/cms.ts`.
245
+ * Add to `componentRegistrations` in `src/lib/registrations.ts`.
@@ -1,134 +1,127 @@
1
1
  ---
2
2
  name: create-page-route
3
- description: Guide for creating new Next.js App Router pages and dynamic routes in the SE Core Product framework.
3
+ description: Guide for creating new Next.js App Router pages and dynamic routes in the SE Core Product framework. Use when creating CMS-driven pages, adding route segments, or setting up routing.
4
4
  license: Private
5
5
  metadata:
6
6
  author: se-core-product
7
- version: "1.0.0"
7
+ version: "2.0.0"
8
8
  ---
9
9
 
10
10
  # Creating Pages and Routes
11
11
 
12
12
  This guide explains how to create new pages and handle routing in the SE Core Product Next.js framework. The system uses Next.js App Router with Contentful-driven dynamic routing.
13
13
 
14
- ## Page Architecture
14
+ Reference apps: **example-se2026**, **example-brightline**.
15
15
 
16
- ### 1. Dynamic Catch-All Route (`[...slugs]`)
16
+ ## Page Architecture
17
17
 
18
- Most CMS pages are handled by a single catch-all route at `app/(pages)/[...slugs]/page.tsx`. This component:
19
- 1. Receives the URL slug.
20
- 2. Fetches the page data from Contentful.
21
- 3. Renders the `<CmsContent>` component.
18
+ ### 1. (cms-routes) Route Group
22
19
 
23
- ### 2. Static Params Generation
20
+ All CMS-driven pages live under `src/app/(cms-routes)/`. The layout enables dynamic params:
24
21
 
25
- To enable Static Site Generation (SSG), the page exports `generateStaticParams`:
22
+ ```tsx
23
+ // layout.tsx
24
+ export const dynamicParams = true;
26
25
 
27
- ```typescript
28
- import { getAllPageLinks } from '@/lib/cms';
29
-
30
- export async function generateStaticParams() {
31
- const links = await getAllPageLinks();
32
- return links
33
- .filter(link => link.slug !== 'index')
34
- .map(link => ({
35
- slugs: link.href?.split('/').filter(Boolean)
36
- }));
26
+ export default function CmsRoutesLayout({ children }: { children: React.ReactNode }) {
27
+ return children;
37
28
  }
38
29
  ```
39
30
 
40
- ## Creating a New Specialized Route
31
+ ### 2. Route Structure
41
32
 
42
- Sometimes you need a route that behaves differently from standard CMS pages (e.g., a search page, a dashboard, or a specialized landing page).
33
+ | Path | File | Purpose |
34
+ |------|------|---------|
35
+ | `/` | `page.ts` | Home (slug: `index`) |
36
+ | `/{slug}/` | `[level1]/page.ts` | Single-level page |
37
+ | `/{slug1}/{slug2}/...` | `[level1]/[...slugs]/page.ts` | Multi-level pages |
38
+ | `/articles/` | `articles/page.ts` | Articles index (uses ARTICLES_BASE from constants) |
39
+ | `/articles/{type}/` | `articles/[articleType]/page.ts` | Article type index |
40
+ | `/articles/{type}/{tag}/` | `articles/[articleType]/[tag]/page.ts` | Article type + tag index |
41
+ | `/articles/{type}/{tag}/{article}/` | `articles/[articleType]/[tag]/[...slugs]/page.ts` | Individual article |
42
+ | `/tags/`, `/tags/{tag}/` | `tags/` | Tag index (if enabled) |
43
+ | `/people/`, `/people/{person}/` | `people/` | People (if enabled) |
43
44
 
44
- ### Step 1: Create the Route Directory
45
+ Base paths (e.g. `/articles` vs `/learning-hub`) come from `@/lib/constants`.
45
46
 
46
- Create a new directory in `src/app` matching your desired URL structure.
47
+ ### 3. appShared Pattern
47
48
 
48
- * Example: `src/app/search/page.tsx` -> `/search`
49
- * Example: `src/app/team/[slug]/page.tsx` -> `/team/john-doe`
49
+ Route files are thin wrappers. Data-fetching and rendering logic lives in `src/appShared/`:
50
50
 
51
- ### Step 2: Implement the Page Component
51
+ - `pageShared.tsx` `generatePage`, `generatePageMetadata`
52
+ - `articleShared.tsx` – articles
53
+ - `articleTypeShared.tsx`, `articleTypesIndexShared.tsx`, `articleTypeTagShared.tsx` – article indices
54
+ - `customTypeShared.tsx` – custom types
55
+ - `personShared.tsx`, `tagShared.tsx`, `tagsIndexShared.tsx`, `teamIndexShared.tsx`
56
+
57
+ ## Route Page Template
58
+
59
+ Each route page extracts params and delegates to the appropriate appShared function:
52
60
 
53
61
  ```typescript
54
- import type { Metadata } from 'next';
55
- import { notFound } from 'next/navigation';
56
- import { CmsContent } from '@se-studio/core-ui';
57
- import { contentfulPageRest, getContentfulConfig } from '@/lib/cms';
58
- import { projectRendererConfig } from '@/lib/cms';
59
-
60
- interface PageProps {
61
- params: { slug: string };
62
- searchParams: { [key: string]: string | string[] | undefined };
62
+ import type { ResolvingMetadata } from 'next';
63
+ import { generatePage, generatePageMetadata } from '@/appShared/pageShared';
64
+
65
+ export function generateStaticParams() {
66
+ return [];
63
67
  }
64
68
 
65
- export default async function Page({ params, searchParams }: PageProps) {
66
- const { slug } = params;
67
- const isPreview = searchParams.preview === 'true';
68
-
69
- // 1. Fetch content
70
- const response = await contentfulPageRest(
71
- getContentfulConfig(isPreview),
72
- slug,
73
- { preview: isPreview }
74
- );
75
-
76
- if (!response.data) {
77
- notFound();
78
- }
79
-
80
- // 2. Render content with CmsContent
81
- // This automatically handles the recursive rendering of components
82
- return (
83
- <main>
84
- <CmsContent
85
- content={response.data}
86
- config={projectRendererConfig}
87
- contentContext={{
88
- // Pass any required context
89
- analyticsContext: { ... }
90
- }}
91
- />
92
- </main>
93
- );
69
+ async function extractDetails(props: PageProps<'/[level1]'>) {
70
+ const params = await props.params;
71
+ const { level1 } = params;
72
+ return { slug: level1, path: `/${level1}/` };
94
73
  }
95
- ```
96
74
 
97
- ### Step 3: Add Metadata
75
+ export async function generateMetadata(props: PageProps<'/[level1]'>, parent: ResolvingMetadata) {
76
+ const { slug, path } = await extractDetails(props);
77
+ return generatePageMetadata(slug, path, true, parent);
78
+ }
98
79
 
99
- Always export metadata for SEO:
80
+ export default async function (props: PageProps<'/[level1]'>) {
81
+ const { slug, path } = await extractDetails(props);
82
+ return generatePage(slug, path, true);
83
+ }
84
+ ```
100
85
 
101
- ```typescript
102
- export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
103
- const response = await contentfulPageRest(/* ... */);
104
- const page = response.data;
86
+ For the home page (`/`), use slug `'index'` and path `'/'` directly.
105
87
 
106
- if (!page) return {};
88
+ ## CmsContent Usage
107
89
 
108
- return {
109
- title: page.seoTitle || page.title,
110
- description: page.seoDescription,
111
- // ... maps to Next.js metadata format
112
- };
113
- }
90
+ The appShared modules render content with:
91
+
92
+ ```tsx
93
+ <CmsContent
94
+ contents={page.contents}
95
+ rendererConfig={projectRendererConfig}
96
+ pageContext={{ page }}
97
+ />
114
98
  ```
115
99
 
116
- ## Custom Layouts
100
+ - `contents` – array of page/article contents (not the full page object)
101
+ - `rendererConfig` – from `@/lib/cms-server`
102
+ - `pageContext` – provides page/article/customType to child components
117
103
 
118
- If your new route needs a different layout (e.g., no header/footer), create a `layout.tsx` in your route directory.
104
+ ## Creating a Specialized Route
119
105
 
120
- ```typescript
121
- export default function CustomLayout({ children }: { children: React.ReactNode }) {
122
- return (
123
- <div className="custom-layout">
124
- {children}
125
- </div>
126
- );
127
- }
128
- ```
106
+ For a route that behaves differently from standard CMS pages (e.g. search, dashboard):
107
+
108
+ 1. Create the route under `(cms-routes)` or a separate route group.
109
+ 2. Either create a new appShared module (if the pattern is reusable) or implement inline.
110
+ 3. Use `getPageWithErrors`, `getArticleWithErrors`, etc. from `@/lib/cms-server`.
111
+ 4. Use `projectRendererConfig` from `@/lib/cms-server`.
112
+ 5. Render with `CmsContent` using `contents`, `rendererConfig`, and `pageContext`.
113
+
114
+ ## Custom Layouts
115
+
116
+ If a route needs a different layout (e.g. no header/footer), create `layout.tsx` in that route directory.
129
117
 
130
118
  ## Troubleshooting
131
119
 
132
- * **404 on new route**: Ensure you've re-run the dev server or build if you added a new dynamic route segment.
133
- * **Static params missing**: Check if your new content is published in Contentful and reachable via `getAllPageLinks` (or your custom fetcher).
134
- * **Preview mode not working**: Ensure you are passing `preview: true` to the fetcher functions when `searchParams.preview` is set.
120
+ - **404 on new route**: Re-run the dev server or build after adding a dynamic route segment.
121
+ - **Static params missing**: Dynamic routes use `generateStaticParams() { return []; }` for on-demand rendering.
122
+ - **Preview mode**: Handled by `draftOnly` in `@/lib/server-config`; appShared modules use it automatically.
123
+
124
+ ## See Also
125
+
126
+ - **cms-routes-and-appshared** – Full route structure and appShared pattern
127
+ - **lib-cms-structure** – lib directory layout and cms-server usage
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: lib-cms-structure
3
+ description: Guide for the lib directory structure in SE Core Product CMS apps. Use when setting up lib/, migrating from contentful-config, or adding new CMS configuration.
4
+ license: Private
5
+ metadata:
6
+ author: se-core-product
7
+ version: "1.0.0"
8
+ ---
9
+
10
+ # Lib Directory Structure
11
+
12
+ Reference apps: **example-se2026**, **example-brightline**.
13
+
14
+ ## File Responsibilities
15
+
16
+ | File | Client-safe? | Purpose |
17
+ |------|--------------|---------|
18
+ | `cms.ts` | Yes | Types, build maps from registrations, createConverterContext |
19
+ | `cms-server.ts` | No (server-only) | createAppHelpers, buildOptions, getContentfulConfig, projectRendererConfig |
20
+ | `client-config.ts` | Yes | isProduction, isDevelopment |
21
+ | `server-config.ts` | No | draftOnly, videoPrefix, baseUrl, revalidationSecret |
22
+ | `constants.ts` | Yes | ARTICLES_BASE, TAGS_BASE, PEOPLE_BASE, enable flags, customer name |
23
+ | `registrations.ts` | Yes | componentRegistrations, collectionRegistrations, externalComponentRegistrations |
24
+ | `SizingInformation.ts` | Yes | getSizingInformation for dynamic heading sizes |
25
+
26
+ ## Server vs Client Boundary
27
+
28
+ - **cms-server.ts** has `import 'server-only'`. Never import it in `'use client'` components.
29
+ - **cms.ts** is client-safe: types, maps, converter context factory (no env access).
30
+ - **registrations.ts** imports from cms.ts and project components; keep it client-safe.
31
+
32
+ ## constants.ts Shape
33
+
34
+ ```typescript
35
+ export const ARTICLES_SLUG = 'articles'; // or 'learning-hub'
36
+ export const TAGS_SLUG = 'tags';
37
+ export const PEOPLE_SLUG = 'people';
38
+ export const DEFAULT_TOPIC = 'other';
39
+
40
+ export const ARTICLES_BASE = `/${ARTICLES_SLUG}`;
41
+ export const TAGS_BASE = `/${TAGS_SLUG}`;
42
+ export const PEOPLE_BASE = `/${PEOPLE_SLUG}`;
43
+
44
+ export const customerName = '...';
45
+ export const applicationName = '...';
46
+ export const siteTitle = '...';
47
+ export const siteDescription = '...';
48
+ export const enablePerson = false;
49
+ export const enablePeopleIndex = false;
50
+ export const enableTag = false;
51
+ export const enableTagsIndex = false;
52
+ ```
53
+
54
+ ## Data Flow
55
+
56
+ ```
57
+ registrations.ts → cms.ts → builds maps → cms-server.ts
58
+
59
+ projectRendererConfig
60
+ ```
61
+
62
+ Add new components/collections in `registrations.ts`. The `cms.ts` imports from it and builds the maps used by `cms-server.ts`.
63
+
64
+ ## See Also
65
+
66
+ - **register-cms-features** – Adding components and collections
67
+ - **cms-routes-and-appshared** – Route structure and appShared
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: register-cms-features
3
- description: Guide for registering new components, collections, and external integrations in the CMS configuration (src/lib/cms.ts).
3
+ description: Guide for registering new components, collections, and external integrations in the CMS configuration (src/lib/registrations.ts).
4
4
  license: Private
5
5
  metadata:
6
6
  author: se-core-product
@@ -9,7 +9,7 @@ metadata:
9
9
 
10
10
  # Registering CMS Features
11
11
 
12
- The file `src/lib/cms.ts` is the central registry for the application. It connects Contentful content types to their React implementations.
12
+ The file `src/lib/registrations.ts` is where you add new components, collections, and external components. The `cms.ts` module imports from `registrations.ts` and builds the maps used by the renderer; add new registrations in `registrations.ts`.
13
13
 
14
14
  ## How Registration Works
15
15
 
@@ -22,14 +22,14 @@ The system uses "Registration Objects" created via `defineComponent` or `defineC
22
22
  ## Registering a New Component
23
23
 
24
24
  1. **Import the Registration**:
25
- At the top of `src/lib/cms.ts`, import your component's registration export.
25
+ At the top of `src/lib/registrations.ts`, import your component's registration export.
26
26
 
27
27
  ```typescript
28
28
  import { MyNewComponentRegistration } from '@/project/components/MyNewComponent';
29
29
  ```
30
30
 
31
31
  2. **Add to `componentRegistrations`**:
32
- Find the `componentRegistrations` array and add your component.
32
+ Find the `componentRegistrations` array in `registrations.ts` and add your component.
33
33
 
34
34
  ```typescript
35
35
  const componentRegistrations = [
@@ -43,13 +43,13 @@ The system uses "Registration Objects" created via `defineComponent` or `defineC
43
43
 
44
44
  ## Registering a New Collection
45
45
 
46
- 1. **Import the Registration**:
46
+ 1. **Import the Registration** in `src/lib/registrations.ts`:
47
47
 
48
48
  ```typescript
49
49
  import { MyCollectionRegistration } from '@/project/collections/MyCollection';
50
50
  ```
51
51
 
52
- 2. **Add to `collectionRegistrations`**:
52
+ 2. **Add to `collectionRegistrations`** in `registrations.ts`:
53
53
 
54
54
  ```typescript
55
55
  const collectionRegistrations = [
@@ -61,14 +61,14 @@ The system uses "Registration Objects" created via `defineComponent` or `defineC
61
61
 
62
62
  ## Adding External Components
63
63
 
64
- External components (like 3rd party forms or iframes) use a separate registry.
64
+ External components (like 3rd party forms or iframes) use a separate registry in `src/lib/registrations.ts`.
65
65
 
66
66
  1. **Import**:
67
67
  ```typescript
68
68
  import { MyExternalWidgetRegistration } from '@/project/externalComponents/MyExternalWidget';
69
69
  ```
70
70
 
71
- 2. **Add to `externalComponentRegistrations`**:
71
+ 2. **Add to `externalComponentRegistrations`** in `registrations.ts`:
72
72
  ```typescript
73
73
  const externalComponentRegistrations = [
74
74
  ExternalIFrameRegistration,
@@ -78,7 +78,7 @@ External components (like 3rd party forms or iframes) use a separate registry.
78
78
 
79
79
  ## Extending Type Definitions
80
80
 
81
- If you introduce new Color names, Button variants, or other enumerations, update the type definitions in `src/lib/cms.ts`:
81
+ If you introduce new Color names, Button variants, or other enumerations, update the type definitions in `src/lib/cms.ts` (types are defined there; registrations live in `registrations.ts`):
82
82
 
83
83
  ```typescript
84
84
  export type CmsColourName = NonNullable<TypeComponentFields['backgroundColour']>['values'];
@@ -37,14 +37,18 @@ Styles are responsive and scale automatically based on the breakpoints defined i
37
37
 
38
38
  ### Best Practice: Dynamic Sizing
39
39
 
40
- Use `getSizingInformation(index)` to dynamically assign the correct heading class based on the component's position on the page or the CMS configuration.
40
+ Use `getSizingInformation(index)` from `@/lib/SizingInformation` to dynamically assign the correct heading class based on the component's position on the page.
41
41
 
42
42
  ```typescript
43
+ import { getSizingInformation } from '@/lib/SizingInformation';
44
+
43
45
  // Example usage in a component renderer
44
- const { Element, sizingInformation } = getSizingInformation(size, index);
46
+ const { Element, sizingInformation } = getSizingInformation(index);
45
47
  <Element className={sizingInformation.h1}>{title}</Element>
46
48
  ```
47
49
 
50
+ For embedded content (e.g. inside rich text), pass `embedded: true` as the second argument.
51
+
48
52
  ## Colors
49
53
 
50
54
  Colors are defined in `colorOptions` within `tailwind.config.json`. The build system generates TypeScript helpers in `@/generated/colors` to access these colors safely.