@se-studio/contentful-cms 1.0.28 → 1.0.29
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 +6 -0
- package/INSTALL.md +80 -55
- package/dist/commands/set.d.ts.map +1 -1
- package/dist/commands/set.js +20 -1
- package/dist/commands/set.js.map +1 -1
- package/dist/validation/allowed-types.d.ts +1 -1
- package/dist/validation/allowed-types.d.ts.map +1 -1
- package/dist/validation/allowed-types.js +4 -3
- package/dist/validation/allowed-types.js.map +1 -1
- package/package.json +4 -4
- package/skills/cms-guidelines/README.md +22 -3
- package/skills/cms-guidelines/html-component-authoring.md +259 -0
package/CHANGELOG.md
CHANGED
package/INSTALL.md
CHANGED
|
@@ -8,6 +8,9 @@ This guide sets up Claude Desktop so it can read and edit your Contentful conten
|
|
|
8
8
|
|
|
9
9
|
- **Contentful Space ID** — a short code that identifies your project in Contentful
|
|
10
10
|
- **Contentful Management Token** — a secret key that gives Claude permission to edit content
|
|
11
|
+
- **Staging site URL** — the Vercel preview URL for your project (e.g. `https://my-project.vercel.app`)
|
|
12
|
+
- **Vercel bypass token** *(optional)* — only needed if your staging site has deployment protection enabled
|
|
13
|
+
- **Node.js** — required for screenshot support. Download the LTS version from [nodejs.org](https://nodejs.org) if you don't have it
|
|
11
14
|
|
|
12
15
|
---
|
|
13
16
|
|
|
@@ -29,72 +32,108 @@ This guide sets up Claude Desktop so it can read and edit your Contentful conten
|
|
|
29
32
|
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
## Step 2 —
|
|
35
|
+
## Step 2 — Run the setup script
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
The setup script will ask for your details and configure everything automatically.
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
### Windows
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
Open **PowerShell** (search for it in the Start menu) and paste this command:
|
|
39
42
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
```powershell
|
|
44
|
+
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\Downloads\install.ps1"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> First, download [install.ps1](./install.ps1) and save it to your Downloads folder.
|
|
48
|
+
|
|
49
|
+
### Mac
|
|
50
|
+
|
|
51
|
+
Open **Terminal** (search for it in Spotlight) and paste this command:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bash ~/Downloads/install.sh
|
|
52
55
|
```
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
> First, download [install.sh](./install.sh) and save it to your Downloads folder.
|
|
58
|
+
|
|
59
|
+
### Linux
|
|
60
|
+
|
|
61
|
+
Open a terminal and paste this command:
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
```bash
|
|
64
|
+
bash ~/Downloads/install.sh
|
|
65
|
+
```
|
|
61
66
|
|
|
62
|
-
|
|
67
|
+
> The script automatically detects Linux and uses the correct config location (`~/.config/Claude/`).
|
|
63
68
|
|
|
64
69
|
---
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
The script will ask you three things:
|
|
72
|
+
1. A short name for your project (e.g. `my-project`) — no spaces
|
|
73
|
+
2. Your Contentful Space ID
|
|
74
|
+
3. Your Contentful Management Token
|
|
75
|
+
|
|
76
|
+
It will then create your config file and update Claude Desktop automatically.
|
|
67
77
|
|
|
68
|
-
|
|
78
|
+
---
|
|
69
79
|
|
|
70
|
-
|
|
80
|
+
## Step 3 — Restart Claude Desktop
|
|
71
81
|
|
|
72
|
-
|
|
82
|
+
Fully quit Claude Desktop and reopen it.
|
|
73
83
|
|
|
74
|
-
**Mac:**
|
|
84
|
+
- **Mac:** Right-click the Dock icon and choose **Quit** (just closing the window isn't enough)
|
|
85
|
+
- **Windows/Linux:** Close the window and reopen from the Start menu / app launcher
|
|
75
86
|
|
|
76
|
-
|
|
87
|
+
---
|
|
77
88
|
|
|
78
|
-
|
|
89
|
+
## Step 4 — Test it
|
|
90
|
+
|
|
91
|
+
In a new Claude conversation, type:
|
|
92
|
+
|
|
93
|
+
> What Contentful spaces do you have access to?
|
|
94
|
+
|
|
95
|
+
Claude should respond with the space name you chose. If it does, you're all set.
|
|
96
|
+
|
|
97
|
+
---
|
|
79
98
|
|
|
80
|
-
|
|
99
|
+
## Manual setup (if you'd prefer not to use the script)
|
|
81
100
|
|
|
82
|
-
|
|
101
|
+
<details>
|
|
102
|
+
<summary>Click to expand manual instructions</summary>
|
|
103
|
+
|
|
104
|
+
### Create your config file
|
|
105
|
+
|
|
106
|
+
Create a file called `.contentful-cms.json` in your home folder:
|
|
107
|
+
- **Windows:** `C:\Users\YourName\.contentful-cms.json`
|
|
108
|
+
- **Mac/Linux:** `~/.contentful-cms.json`
|
|
83
109
|
|
|
84
|
-
**Windows:**
|
|
85
110
|
```json
|
|
86
111
|
{
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
"
|
|
112
|
+
"defaultSpace": "my-project",
|
|
113
|
+
"spaces": {
|
|
114
|
+
"my-project": {
|
|
115
|
+
"spaceId": "YOUR_SPACE_ID",
|
|
116
|
+
"environment": "master",
|
|
117
|
+
"managementToken": "YOUR_MANAGEMENT_TOKEN",
|
|
118
|
+
"defaultLocale": "en-US"
|
|
92
119
|
}
|
|
93
120
|
}
|
|
94
121
|
}
|
|
95
122
|
```
|
|
96
123
|
|
|
97
|
-
|
|
124
|
+
Replace `my-project` (both places), `YOUR_SPACE_ID`, and `YOUR_MANAGEMENT_TOKEN` with your values.
|
|
125
|
+
|
|
126
|
+
**Windows tip:** In Notepad's Save dialog, set "Save as type" to **All Files** so it doesn't add `.txt`.
|
|
127
|
+
|
|
128
|
+
### Configure Claude Desktop
|
|
129
|
+
|
|
130
|
+
Edit the Claude Desktop config file:
|
|
131
|
+
- **Windows:** `C:\Users\YourName\AppData\Roaming\Claude\claude_desktop_config.json`
|
|
132
|
+
- **Mac:** `/Users/YourName/Library/Application Support/Claude/claude_desktop_config.json`
|
|
133
|
+
- **Linux:** `~/.config/Claude/claude_desktop_config.json`
|
|
134
|
+
|
|
135
|
+
Add (or merge) this into the file:
|
|
136
|
+
|
|
98
137
|
```json
|
|
99
138
|
{
|
|
100
139
|
"mcpServers": {
|
|
@@ -107,23 +146,9 @@ Add the `mcpServers` section shown below. If the file already has content, you'l
|
|
|
107
146
|
}
|
|
108
147
|
```
|
|
109
148
|
|
|
110
|
-
Replace
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Step 4 — Restart Claude Desktop
|
|
115
|
-
|
|
116
|
-
Fully quit Claude Desktop and reopen it. On Mac, right-click the Dock icon and choose **Quit** (just closing the window isn't enough).
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Step 5 — Test it
|
|
121
|
-
|
|
122
|
-
In a new Claude conversation, type:
|
|
123
|
-
|
|
124
|
-
> What Contentful spaces do you have access to?
|
|
149
|
+
Replace `/Users/YourName` with your actual home folder path.
|
|
125
150
|
|
|
126
|
-
|
|
151
|
+
</details>
|
|
127
152
|
|
|
128
153
|
---
|
|
129
154
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2NzD"}
|
package/dist/commands/set.js
CHANGED
|
@@ -13,6 +13,7 @@ export function registerSetCommand(program) {
|
|
|
13
13
|
.description('Set a field on an entry.\n' +
|
|
14
14
|
'Scalar (default): pass a string, boolean, or number as <value>.\n' +
|
|
15
15
|
'Object/JSON: use --file <path> to read JSON from a file, or --json <json> for inline JSON.\n' +
|
|
16
|
+
'Plain text file: use --text-file <path> to read a file as a plain string (for rawHtml, customCss, etc.).\n' +
|
|
16
17
|
'Entry link: use --link (value = linked entry ID).\n' +
|
|
17
18
|
'Asset link: use --asset (value = asset ID).\n' +
|
|
18
19
|
'Content array: use --links (value = comma-separated refs or IDs); use --append to append.\n' +
|
|
@@ -22,6 +23,7 @@ export function registerSetCommand(program) {
|
|
|
22
23
|
.option('--links', 'Value is comma-separated refs or entry IDs; field must be topContent, content, bottomContent, or contents')
|
|
23
24
|
.option('--append', 'With --links: append to existing array instead of replacing')
|
|
24
25
|
.option('--file <path>', 'Read JSON from a file and set the field as an Object value')
|
|
26
|
+
.option('--text-file <path>', 'Read a plain text file and set the field as a Text value (for rawHtml, customCss, etc.)')
|
|
25
27
|
.option('--json <json>', 'Inline JSON string to set the field as an Object value')
|
|
26
28
|
.action(async (ref, field, rawValue, opts, cmd) => {
|
|
27
29
|
const parentOpts = cmd.parent?.opts() ?? {};
|
|
@@ -47,6 +49,10 @@ export function registerSetCommand(program) {
|
|
|
47
49
|
errorMsg('Cannot combine --file/--json with --link, --asset, or --links.');
|
|
48
50
|
process.exit(1);
|
|
49
51
|
}
|
|
52
|
+
if (opts.textFile && (opts.file || opts.json || opts.link || opts.asset || opts.links)) {
|
|
53
|
+
errorMsg('Cannot combine --text-file with --file, --json, --link, --asset, or --links.');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
50
56
|
if (opts.append && !opts.links) {
|
|
51
57
|
errorMsg('--append is only valid with --links.');
|
|
52
58
|
process.exit(1);
|
|
@@ -70,8 +76,21 @@ export function registerSetCommand(program) {
|
|
|
70
76
|
: `Set ${field} on ${ref} to inline JSON object.`);
|
|
71
77
|
return;
|
|
72
78
|
}
|
|
79
|
+
if (opts.textFile) {
|
|
80
|
+
const text = readFileStrict(opts.textFile);
|
|
81
|
+
if (!entry.fields[field]) {
|
|
82
|
+
entry.fields[field] = {};
|
|
83
|
+
}
|
|
84
|
+
entry.fields[field][locale] = text;
|
|
85
|
+
if (!session.modifiedEntryIds.includes(entry.sys.id)) {
|
|
86
|
+
session.modifiedEntryIds.push(entry.sys.id);
|
|
87
|
+
}
|
|
88
|
+
saveSession(session);
|
|
89
|
+
successMsg(`Set ${field} on ${ref} from text file "${opts.textFile}".`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
73
92
|
if (!rawValue && !opts.links) {
|
|
74
|
-
errorMsg('Missing value. Provide a <value> argument, or use --file <path> / --json <json> for Object fields.');
|
|
93
|
+
errorMsg('Missing value. Provide a <value> argument, or use --file <path> / --json <json> for Object fields, or --text-file <path> for plain text fields.');
|
|
75
94
|
process.exit(1);
|
|
76
95
|
}
|
|
77
96
|
if (!isObjectMode && !opts.link && !opts.asset && !opts.links) {
|
package/dist/commands/set.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAEpB,mCAAmC,GACpC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,2BAA2B,CAAC;SACpC,WAAW,CACV,4BAA4B;QAC1B,mEAAmE;QACnE,8FAA8F;QAC9F,qDAAqD;QACrD,+CAA+C;QAC/C,6FAA6F;QAC7F,kDAAkD,CACrD;SACA,MAAM,CAAC,QAAQ,EAAE,oDAAoD,CAAC;SACtE,MAAM,CAAC,SAAS,EAAE,oDAAoD,CAAC;SACvE,MAAM,CACL,SAAS,EACT,2GAA2G,CAC5G;SACA,MAAM,CAAC,UAAU,EAAE,6DAA6D,CAAC;SACjF,MAAM,CAAC,eAAe,EAAE,4DAA4D,CAAC;SACrF,MAAM,CAAC,eAAe,EAAE,wDAAwD,CAAC;SACjF,MAAM,CACL,KAAK,EACH,GAAW,EACX,KAAa,EACb,QAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Content type IDs allowed when adding entries to page/article/template content arrays.
|
|
3
3
|
* Used by the add command to refuse unsupported types with a clear error.
|
|
4
4
|
*/
|
|
5
|
-
export declare const ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE: readonly ["
|
|
5
|
+
export declare const ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE: readonly ["collection", "component", "externalComponent", "externalVideo", "htmlComponent", "media", "person"];
|
|
6
6
|
export declare function isAllowedContentTypeForAdd(contentTypeId: string): boolean;
|
|
7
7
|
//# sourceMappingURL=allowed-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowed-types.d.ts","sourceRoot":"","sources":["../../src/validation/allowed-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sCAAsC
|
|
1
|
+
{"version":3,"file":"allowed-types.d.ts","sourceRoot":"","sources":["../../src/validation/allowed-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sCAAsC,gHAQzC,CAAC;AAEX,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEzE"}
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* Used by the add command to refuse unsupported types with a clear error.
|
|
4
4
|
*/
|
|
5
5
|
export const ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE = [
|
|
6
|
-
'component',
|
|
7
6
|
'collection',
|
|
7
|
+
'component',
|
|
8
8
|
'externalComponent',
|
|
9
|
-
'person',
|
|
10
|
-
'media',
|
|
11
9
|
'externalVideo',
|
|
10
|
+
'htmlComponent',
|
|
11
|
+
'media',
|
|
12
|
+
'person',
|
|
12
13
|
];
|
|
13
14
|
export function isAllowedContentTypeForAdd(contentTypeId) {
|
|
14
15
|
return ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE.includes(contentTypeId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowed-types.js","sourceRoot":"","sources":["../../src/validation/allowed-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,WAAW;IACX,
|
|
1
|
+
{"version":3,"file":"allowed-types.js","sourceRoot":"","sources":["../../src/validation/allowed-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,YAAY;IACZ,WAAW;IACX,mBAAmB;IACnB,eAAe;IACf,eAAe;IACf,OAAO;IACP,QAAQ;CACA,CAAC;AAEX,MAAM,UAAU,0BAA0B,CAAC,aAAqB;IAC9D,OAAQ,sCAA4D,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAC/F,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/contentful-cms",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.29",
|
|
4
4
|
"description": "CLI tool for AI agents to read and edit Contentful draft content without publish permissions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@contentful/rich-text-types": "^17.2.5",
|
|
32
|
-
"@modelcontextprotocol/sdk": "1.
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
33
|
"commander": "^14.0.3",
|
|
34
|
-
"contentful-management": "^12.
|
|
34
|
+
"contentful-management": "^12.2.0",
|
|
35
35
|
"dotenv": "^17.3.1",
|
|
36
36
|
"picocolors": "^1.1.1",
|
|
37
37
|
"zod": "^4.3.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@biomejs/biome": "^2.4.
|
|
40
|
+
"@biomejs/biome": "^2.4.10",
|
|
41
41
|
"@types/node": "^22.19.15",
|
|
42
42
|
"typescript": "^6.0.2",
|
|
43
43
|
"vitest": "^4.1.2"
|
|
@@ -75,13 +75,31 @@ cms-merge-guidelines --app-dir apps/example-om1
|
|
|
75
75
|
|
|
76
76
|
| CLI | Purpose |
|
|
77
77
|
|---|---|
|
|
78
|
+
| `cms-generate-html-style-guide` | Generate `html-component-style-guide.md` from `tailwind.config.json` + `globals.css` |
|
|
78
79
|
| `cms-generate-field-list` | Parse TypeScript types → `field-list.json` |
|
|
79
80
|
| `cms-capture-screenshots` | Capture component screenshots for variant evaluation |
|
|
80
81
|
| `cms-update-colour-hints` | Upsert a colour hint in `colour-hints.json` |
|
|
81
|
-
| `cms-generate-collection-guidelines` |
|
|
82
|
+
| `cms-generate-collection-guidelines` | Generate all collection/external `.md` files from a discovery URL |
|
|
82
83
|
| `cms-merge-guidelines` | Merge all fragments → `COMPONENT_GUIDELINES_FOR_LLM.md` |
|
|
83
84
|
|
|
84
|
-
All CLIs are provided by `@se-studio/
|
|
85
|
+
All CLIs are provided by `@se-studio/project-build`. Run `pnpm build` from the repo root to ensure they are built and linked.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## `cms-generate-html-style-guide`
|
|
90
|
+
|
|
91
|
+
Generates `docs/cms-guidelines/html-component-style-guide.md` — a design system reference for any LLM or developer authoring HTML in `HtmlComponent` CMS entries.
|
|
92
|
+
|
|
93
|
+
Does not require a running dev server. Reads only local files:
|
|
94
|
+
- `tailwind.config.json` → colour palette, typography classes, grid configuration
|
|
95
|
+
- `src/app/globals.css` → custom utilities, RTF class names, CSS custom properties
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# From the app directory:
|
|
99
|
+
pnpm cms-generate-html-style-guide
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The output file is a **static fragment** — not generated by the LLM component pipeline. It is automatically included as a preamble in `COMPONENT_GUIDELINES_FOR_LLM.md` when `cms-merge-guidelines` runs. Regenerate it whenever the design system changes.
|
|
85
103
|
|
|
86
104
|
---
|
|
87
105
|
|
|
@@ -128,10 +146,11 @@ Outputs:
|
|
|
128
146
|
```
|
|
129
147
|
<appDir>/
|
|
130
148
|
docs/cms-guidelines/
|
|
149
|
+
html-component-style-guide.md # design system reference (auto-generated; static fragment)
|
|
131
150
|
components/ # one .md per componentType
|
|
132
151
|
collections/ # one .md per collectionType
|
|
133
152
|
externals/ # one .md per externalComponentType
|
|
134
|
-
COMPONENT_GUIDELINES_FOR_LLM.md # merged document
|
|
153
|
+
COMPONENT_GUIDELINES_FOR_LLM.md # merged document (includes style guide as preamble)
|
|
135
154
|
generated/cms-discovery/
|
|
136
155
|
field-list.json
|
|
137
156
|
colour-hints.json
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: html-component-authoring
|
|
3
|
+
description: Guidelines for authoring HTML content in HtmlComponent CMS entries. Covers how to use the project style guide, what classes to use, field semantics, and common layout patterns.
|
|
4
|
+
license: Private
|
|
5
|
+
metadata:
|
|
6
|
+
author: se-core-product
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# HtmlComponent Authoring Guide
|
|
11
|
+
|
|
12
|
+
`HtmlComponent` is a CMS content type that renders developer-authored HTML directly into the page. It bypasses the standard component registration system and is intended for one-off or highly custom layouts that the structured component library cannot produce.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Before You Start
|
|
17
|
+
|
|
18
|
+
**Read the project style guide.** Every app has an auto-generated HTML Component Style Guide at:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
docs/cms-guidelines/html-component-style-guide.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This file contains the exact colour names, typography class names, grid configuration, and custom utilities available for that specific project. It is derived from `tailwind.config.json` and `globals.css` — always consult it before writing any HTML.
|
|
25
|
+
|
|
26
|
+
If the file does not exist, generate it first:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# From the app directory:
|
|
30
|
+
pnpm cms-generate-html-style-guide
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## HtmlComponent Fields
|
|
36
|
+
|
|
37
|
+
| Field | Required | Type | Purpose |
|
|
38
|
+
|-------|----------|------|---------|
|
|
39
|
+
| `rawHtml` | ✓ | Text | The HTML markup. Use Tailwind classes; never inline `style=` for colours/typography/layout. |
|
|
40
|
+
| `customCss` | — | Text | Scoped CSS. Rules are automatically prefixed with `[data-hc-id="<id>"]` — they cannot pollute other components. |
|
|
41
|
+
| `customJs` | — | Text | JavaScript loaded via Next.js `<Script>`. Use sparingly. |
|
|
42
|
+
| `markdownContent` | — | Text | Plain text for search indexing. **Always fill this** so the component appears in site search. |
|
|
43
|
+
| `isHero` | — | Boolean | `true` if the HTML contains an `<h1>`. Moves this block to the top of the page content flow. |
|
|
44
|
+
| `fullWidth` | — | Boolean | `true` for edge-to-edge (full-bleed) layouts that break out of the column grid. |
|
|
45
|
+
| `excludeFromSearch` | — | Boolean | `true` to exclude from search even if `markdownContent` is set. |
|
|
46
|
+
| `loadScriptOnce` | — | Boolean | `true` (default) to deduplicate the script tag when the same entry appears multiple times. |
|
|
47
|
+
| `scriptStrategy` | — | Enum | `afterInteractive` (default), `lazyOnload`, `beforeInteractive`. |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## The Four Non-Negotiable Rules
|
|
52
|
+
|
|
53
|
+
1. **Use Tailwind classes, not inline styles.**
|
|
54
|
+
- ❌ `style="color: #FF5C00; font-size: 48px;"`
|
|
55
|
+
- ✓ `class="text-orange h2"`
|
|
56
|
+
|
|
57
|
+
2. **Use named colour classes from the palette.**
|
|
58
|
+
- ❌ `class="bg-[#1F2E32]"` or `style="background: #1F2E32"`
|
|
59
|
+
- ✓ `class="bg-dark text-light"`
|
|
60
|
+
|
|
61
|
+
3. **Use typography classes, not raw font sizes.**
|
|
62
|
+
- ❌ `class="text-[48px] font-semibold"`
|
|
63
|
+
- ✓ `class="h2"`
|
|
64
|
+
|
|
65
|
+
4. **Respect the grid.** Wrap content in `content-cols-grid` and use `col-span-*` / `col-start-*` to align with other sections.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Colour Usage
|
|
70
|
+
|
|
71
|
+
All colour names are defined in the style guide. Use lowercase in Tailwind:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Dark → bg-dark / text-dark / border-dark
|
|
75
|
+
Light → bg-light / text-light / border-light
|
|
76
|
+
Orange → bg-orange / text-orange
|
|
77
|
+
Blue → bg-blue / text-blue
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For dark backgrounds, pair with the contrast colour (`bg-dark text-light`). Check the "Contrast pair" column in the style guide to know which pairings are approved.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Typography Usage
|
|
85
|
+
|
|
86
|
+
Pick from the named type styles in the style guide. Apply directly to the element:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<h1 class="h1">Large display heading (uppercase, 96–200px)</h1>
|
|
90
|
+
<h2 class="h2">Section heading (45–48px)</h2>
|
|
91
|
+
<h3 class="h3">Sub-heading (21–44px, uppercase)</h3>
|
|
92
|
+
<p class="p1">Large body (20–24px)</p>
|
|
93
|
+
<p class="p2">Standard body (16px)</p>
|
|
94
|
+
<p class="p3">Small body (13px)</p>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**For rich text blocks** (content rendered from Markdown or the CMS), wrap in an RTF class:
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<div class="rtf-standard">
|
|
101
|
+
<h2>Auto-styled heading</h2>
|
|
102
|
+
<p>Auto-styled paragraph with list and link support.</p>
|
|
103
|
+
</div>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Available RTF classes: `rtf-standard`, `rtf-article`, `rtf-article-right`, `rtf-legal`.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Grid & Layout
|
|
111
|
+
|
|
112
|
+
HtmlComponent content lives inside the site's `Section` component, which provides the outer grid. To position content within the grid:
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<!-- Standard: wrap in content-cols-grid, span columns -->
|
|
116
|
+
<div class="content-cols-grid">
|
|
117
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10">
|
|
118
|
+
<!-- content -->
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Common column spans (all on a 12-column laptop grid):
|
|
124
|
+
|
|
125
|
+
| Use | Classes |
|
|
126
|
+
|-----|---------|
|
|
127
|
+
| Full width | `col-span-full` |
|
|
128
|
+
| Centered (one column margin) | `laptop:col-start-2 laptop:col-span-10` |
|
|
129
|
+
| Left half (text) | `laptop:col-start-2 laptop:col-span-4` |
|
|
130
|
+
| Right half (visual) | `laptop:col-start-7 laptop:col-span-5` |
|
|
131
|
+
|
|
132
|
+
For **full-bleed** content (background extends edge to edge), set `fullWidth: true` on the entry. The grid wrapper is removed and you control the full viewport width.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Breakpoints
|
|
137
|
+
|
|
138
|
+
All breakpoints are mobile-first. Use prefixes to override at larger sizes:
|
|
139
|
+
|
|
140
|
+
| Prefix | Min-width |
|
|
141
|
+
|--------|-----------|
|
|
142
|
+
| *(none)* | 0px (mobile default) |
|
|
143
|
+
| `tablet:` | 768px |
|
|
144
|
+
| `laptop:` | 1024px |
|
|
145
|
+
| `desktop:` | 1440px |
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<div class="flex flex-col laptop:flex-row gap-6">...</div>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Scoped CSS (`customCss`)
|
|
154
|
+
|
|
155
|
+
Use `customCss` only for styles impossible with Tailwind (complex `:hover`, `::before`/`::after`, third-party widget overrides).
|
|
156
|
+
|
|
157
|
+
Rules are automatically scoped to this entry's `data-hc-id` attribute — write selectors without the prefix:
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
/* In customCss — this gets scoped to [data-hc-id="<id>"] automatically */
|
|
161
|
+
.my-card:hover {
|
|
162
|
+
transform: translateY(-4px);
|
|
163
|
+
transition: transform 0.2s ease;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
::before {
|
|
167
|
+
content: '';
|
|
168
|
+
display: block;
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Never redeclare colours or typography in `customCss` — those already exist as Tailwind classes.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Common Patterns
|
|
177
|
+
|
|
178
|
+
### Centered text block
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<div class="content-cols-grid">
|
|
182
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10 space-y-6">
|
|
183
|
+
<h2 class="h2">Section Heading</h2>
|
|
184
|
+
<div class="rtf-standard">
|
|
185
|
+
<p>Body copy goes here.</p>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Two-column (text + image)
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<div class="content-cols-grid gap-y-12">
|
|
195
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-4 flex flex-col gap-6">
|
|
196
|
+
<h2 class="h2">Heading</h2>
|
|
197
|
+
<p class="p1">Supporting description.</p>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="col-span-full laptop:col-start-7 laptop:col-span-5">
|
|
200
|
+
<img src="..." alt="..." class="w-full rounded-lg" />
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Coloured card
|
|
206
|
+
|
|
207
|
+
```html
|
|
208
|
+
<div class="content-cols-grid">
|
|
209
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10">
|
|
210
|
+
<div class="bg-orange text-dark p-8 laptop:p-12 rounded-lg flex flex-col gap-4">
|
|
211
|
+
<h3 class="h3">Card Title</h3>
|
|
212
|
+
<p class="p2">Supporting text.</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Hero (set `isHero: true`)
|
|
219
|
+
|
|
220
|
+
```html
|
|
221
|
+
<!-- fullWidth: true → background goes edge-to-edge -->
|
|
222
|
+
<div class="bg-dark text-light">
|
|
223
|
+
<div class="content-cols-grid py-16 laptop:py-32">
|
|
224
|
+
<div class="col-span-full laptop:col-start-2 laptop:col-span-10 flex flex-col gap-8">
|
|
225
|
+
<h1 class="h1">Hero Heading</h1>
|
|
226
|
+
<p class="p1 laptop:col-span-6">Subtitle or intro text.</p>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Checklist Before Saving
|
|
235
|
+
|
|
236
|
+
- [ ] `rawHtml` uses only Tailwind classes — no inline `style=` for colours/typography/layout
|
|
237
|
+
- [ ] All colour references use named classes (`text-dark`, `bg-orange`), not hex values
|
|
238
|
+
- [ ] Typography uses named classes (`h2`, `p1`), not raw `text-[Npx]`
|
|
239
|
+
- [ ] Content is wrapped in `content-cols-grid` and positioned with `col-span-*` / `col-start-*`
|
|
240
|
+
- [ ] `markdownContent` is filled with the plain-text equivalent for search indexing
|
|
241
|
+
- [ ] `isHero: true` if the HTML contains an `<h1>`
|
|
242
|
+
- [ ] `fullWidth: true` if the design needs an edge-to-edge background
|
|
243
|
+
- [ ] Tested at mobile, tablet, and laptop breakpoints
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Generating and Updating the Style Guide
|
|
248
|
+
|
|
249
|
+
The style guide is auto-generated and should be regenerated whenever the design system changes:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# From the app directory:
|
|
253
|
+
pnpm cms-generate-html-style-guide
|
|
254
|
+
|
|
255
|
+
# Then re-merge to include it in COMPONENT_GUIDELINES_FOR_LLM.md:
|
|
256
|
+
pnpm cms-guidelines:merge
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The style guide is also regenerated automatically as part of the `update-cms-guidelines` workflow (Step 3 in `fresh` mode, or any time you run a merge step).
|