@uniformdev/uniform-mcp 20.14.2-alpha.69 → 20.20.3
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/dist/index.mjs
CHANGED
|
@@ -61438,8 +61438,7 @@ var ChipContainer = css`
|
|
|
61438
61438
|
}
|
|
61439
61439
|
|
|
61440
61440
|
&:hover {
|
|
61441
|
-
[role='presentation']
|
|
61442
|
-
[role='separator'] {
|
|
61441
|
+
[role='presentation'] {
|
|
61443
61442
|
transition: opacity var(--duration-fast) var(--timing-ease-out);
|
|
61444
61443
|
opacity: var(--opacity-100);
|
|
61445
61444
|
}
|
|
@@ -61451,8 +61450,7 @@ var ChipContainer = css`
|
|
|
61451
61450
|
}
|
|
61452
61451
|
|
|
61453
61452
|
:where([aria-disabled='true'], :disabled):hover {
|
|
61454
|
-
[role='presentation']
|
|
61455
|
-
[role='separator'] {
|
|
61453
|
+
[role='presentation'] {
|
|
61456
61454
|
opacity: var(--opacity-50);
|
|
61457
61455
|
cursor: not-allowed;
|
|
61458
61456
|
}
|
|
@@ -61469,12 +61467,6 @@ var ChipIcon = css`
|
|
|
61469
61467
|
display: flex;
|
|
61470
61468
|
opacity: var(--opacity-50);
|
|
61471
61469
|
`;
|
|
61472
|
-
var ChipSeparator = css`
|
|
61473
|
-
display: flex;
|
|
61474
|
-
border-right: 1px solid var(--white);
|
|
61475
|
-
opacity: var(--opacity-50);
|
|
61476
|
-
margin-left: -1px;
|
|
61477
|
-
`;
|
|
61478
61470
|
var ChipSmall = css`
|
|
61479
61471
|
font-size: var(--fs-sm);
|
|
61480
61472
|
padding-inline: var(--spacing-sm);
|
|
@@ -66515,7 +66507,7 @@ async function applyCompositionPatches(existingComposition, deletedComponentsInS
|
|
|
66515
66507
|
type: parameterEdit.update.parameterType
|
|
66516
66508
|
};
|
|
66517
66509
|
const property = properties[parameterEdit.update.parameterId];
|
|
66518
|
-
const newValue = parameterEdit.propertyDefinition.type === "richText" ? convertMarkdownToLexical(parameterEdit.result.newValue) : parameterEdit.result.treatNewValueAsJson ? JSON.parse(parameterEdit.result.newValue) : parameterEdit.result.newValue;
|
|
66510
|
+
const newValue = parameterEdit.propertyDefinition.type === "richText" ? convertMarkdownToLexical(parameterEdit.result.newValue) : parameterEdit.propertyDefinition.type === "number" ? Number(parameterEdit.result.newValue) : parameterEdit.result.treatNewValueAsJson ? JSON.parse(parameterEdit.result.newValue) : parameterEdit.result.newValue;
|
|
66519
66511
|
if (parameterEdit.update.locale) {
|
|
66520
66512
|
property.locales ??= {};
|
|
66521
66513
|
property.locales[parameterEdit.update.locale] = newValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniformdev/uniform-mcp",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.20.3",
|
|
4
4
|
"description": "Uniform MCP Server",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"bin": {
|
|
@@ -28,21 +28,22 @@
|
|
|
28
28
|
"@lexical/rich-text": "0.25.0",
|
|
29
29
|
"@lexical/table": "0.25.0",
|
|
30
30
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
31
|
-
"@uniformdev/canvas": "20.
|
|
31
|
+
"@uniformdev/canvas": "20.20.3",
|
|
32
32
|
"fast-json-patch": "^3.1.1",
|
|
33
33
|
"immer": "10.1.1",
|
|
34
34
|
"lexical": "0.25.0",
|
|
35
35
|
"zod": "3.23.8"
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
|
-
"/dist"
|
|
38
|
+
"/dist",
|
|
39
|
+
"/references/*.mdc"
|
|
39
40
|
],
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"access": "public"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
|
-
"@uniformdev/design-system": "^20.
|
|
45
|
+
"@uniformdev/design-system": "^20.20.3",
|
|
45
46
|
"vitest": "^3.1.4"
|
|
46
47
|
},
|
|
47
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "3e58ece2c26439f3ee48d2ff445898a3be59b349"
|
|
48
49
|
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Uniform React Next Page Router Developer Reference - details how to use Uniform with React.js with Next Page Router
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
[uniform.mdc](mdc:.cursor/rules/uniform.mdc) describes general Uniform principles and practices.
|
|
8
|
+
[uniform-sdk.mdc](mdc:.cursor/rules/uniform-sdk.mdc) describes framework-agnostic developer principles.
|
|
9
|
+
[uniform-context-sdk.mdc](mdc:references/uniform-context-sdk.mdc) describes personalization and a/b testing developer practices.
|
|
10
|
+
|
|
11
|
+
### Required npm packages
|
|
12
|
+
|
|
13
|
+
The following npm packages must be installed to wire Uniform CMS to Next Page Router:
|
|
14
|
+
|
|
15
|
+
@uniformdev/canvas
|
|
16
|
+
@uniformdev/canvas-react
|
|
17
|
+
@uniformdev/canvas-next
|
|
18
|
+
@uniformdev/context-react
|
|
19
|
+
|
|
20
|
+
### Fetching and rendering the composition
|
|
21
|
+
|
|
22
|
+
In your dynamic catch-all route file (`pages/[[...path]].{tsx|jsx}`), it is necessary to fetch the Uniform composition instance for the current route. This is done for server-side rendering using the `withUniformGetServerSideProps` function:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import type { UniformCompositionNextPage } from "@uniformdev/canvas-next";
|
|
26
|
+
import { withUniformGetServerSideProps } from "@uniformdev/canvas-next/route";
|
|
27
|
+
import { UniformComposition } from "@uniformdev/canvas-react";
|
|
28
|
+
|
|
29
|
+
// fetch the composition using SSR
|
|
30
|
+
export const getServerSideProps = withUniformGetServerSideProps();
|
|
31
|
+
|
|
32
|
+
// the function provides the composition to the route component as the `data` prop
|
|
33
|
+
// the UniformCompositionNextPage type provides typings to make sure that is clear
|
|
34
|
+
const page: UniformCompositionNextPage = ({ data }) => {
|
|
35
|
+
// the UniformComposition component takes over rendering the components on the composition data
|
|
36
|
+
return <UniformComposition data={data} />;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { page as default };
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Rendering Uniform Components using React Components
|
|
43
|
+
|
|
44
|
+
> IMPORTANT: before generating Uniform component code, always fetch available component definitions from Uniform to be aware of the schema.
|
|
45
|
+
|
|
46
|
+
The `UniformComposition` component needs to know how to map a Uniform Component instance's `type` to a React component that implements the UI for that component. This is done using the Component Registry. To use the component registry, create a component and register it:
|
|
47
|
+
|
|
48
|
+
`components/Hero.tsx`:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { registerUniformComponent } from "@uniformdev/canvas-react";
|
|
52
|
+
|
|
53
|
+
function Hero() {
|
|
54
|
+
return <div>Hero Component Content</div>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
registerUniformComponent({
|
|
58
|
+
type: "hero",
|
|
59
|
+
component: Hero,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
Conventionally Uniform components (like Hero.tsx above) are imported to a barrel file in `components/uniformComponents.ts` (e.g. `import 'componentFileName';`), and that barrel file is imported into `_app.tsx` (e.g. `import '../components/uniformComponents';`) to ensure the registrations are processed.
|
|
63
|
+
|
|
64
|
+
#### Mapping Uniform Components to React Components
|
|
65
|
+
|
|
66
|
+
React components that receive Uniform Component data are passed props that correspond to the shape of the component definition they render. The `ComponentProps` type can be used to make the mapping explicit:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import {
|
|
70
|
+
AssetParamValue,
|
|
71
|
+
LinkParamValue,
|
|
72
|
+
RichTextParamValue,
|
|
73
|
+
} from "@uniformdev/canvas";
|
|
74
|
+
|
|
75
|
+
type HeroProps = ComponentProps<{
|
|
76
|
+
textParameter?: string;
|
|
77
|
+
richTextParameter?: RichTextParamValue;
|
|
78
|
+
linkParameter?: LinkParamValue;
|
|
79
|
+
assetParameter?: AssetParamValue;
|
|
80
|
+
// it is critical that all parameter props values are optional, because they can be undefined - even if 'required' on the component definition
|
|
81
|
+
}>;
|
|
82
|
+
|
|
83
|
+
function Hero(props: HeroProps) {
|
|
84
|
+
return <div>{props.textParameter}</div>;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Rendering child slots
|
|
89
|
+
|
|
90
|
+
If a Uniform Component definition has slots defined, the components in those slots can be rendered using the `UniformSlot` component.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { UniformSlot } from "@uniformdev/canvas-react";
|
|
94
|
+
|
|
95
|
+
function Hero() {
|
|
96
|
+
return (
|
|
97
|
+
<div>
|
|
98
|
+
<div>
|
|
99
|
+
<UniformSlot name="start" />
|
|
100
|
+
</div>
|
|
101
|
+
<div>
|
|
102
|
+
<UniformSlot name="end" />
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Rendering parameter/field values
|
|
110
|
+
|
|
111
|
+
##### Text parameters/fields
|
|
112
|
+
|
|
113
|
+
When rendering a `text` type parameter, always use the `UniformText` component to render the value. This will enable authors to edit the value within the Uniform preview directly. Text parameters that do not have a visible component, such as alt text, should be rendered as their raw text value:
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { UniformText } from "@uniformdev/canvas-react";
|
|
117
|
+
|
|
118
|
+
function Hero() {
|
|
119
|
+
return (
|
|
120
|
+
<div>
|
|
121
|
+
{/* always specify placeholder text that an author will see in the visual editor when the value is empty */}
|
|
122
|
+
<UniformText parameterId="textParameter" placeholder="Enter text" />
|
|
123
|
+
{/* optionally you can specify a className or wrapping tag, as well as placeholder text that an author will see in the visual editor when the value is empty */}
|
|
124
|
+
<UniformText parameterId="textParameter" as="h1" className="excellent" placeholder="Enter text" />
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
##### Rich text parameters/fields
|
|
131
|
+
|
|
132
|
+
For richText parameters, always use the `UniformRichText` component to automatically render the rich text (stored as Lexical JSON) to HTML:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { UniformRichText } from "@uniformdev/canvas-react";
|
|
136
|
+
|
|
137
|
+
function Hero() {
|
|
138
|
+
return (
|
|
139
|
+
<div>
|
|
140
|
+
<UniformRichText parameterId="richTextParameter" placeholder="Prompt for author when value is empty" />
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
##### Asset parameters/fields
|
|
147
|
+
|
|
148
|
+
When rendering asset parameters, use the `flattenValues` helper to simplify value access:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { AssetParamValue, flattenValues } from "@uniformdev/canvas";
|
|
152
|
+
|
|
153
|
+
interface MyComponentProps {
|
|
154
|
+
multipleImagesAssetParam: AssetParamValue;
|
|
155
|
+
singleImageAssetParam: AssetParamValue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function MyComponent({
|
|
159
|
+
multipleImagesAssetParam,
|
|
160
|
+
singleImageAssetParam,
|
|
161
|
+
}: MyComponentProps) {
|
|
162
|
+
// when multiple assets are allowed, flatten to an array
|
|
163
|
+
const images = flattenValues(multipleImagesAssetParam);
|
|
164
|
+
// when only one asset is allowed, flatten to a single object
|
|
165
|
+
const image = flattenValues(singleImageAssetParam, { toSingle: true });
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<>
|
|
169
|
+
{images?.map((img, index) => (
|
|
170
|
+
<img key={index} src={img?.url} width={img?.width} height={img?.height} />
|
|
171
|
+
))}
|
|
172
|
+
<img src={image?.url} width={image?.width} height={image?.height} />
|
|
173
|
+
</>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Configuring Contextual Editing Live Preview
|
|
179
|
+
|
|
180
|
+
To enable contextual editing and live preview to operate within the Uniform application, we need to register a _preview handler_ and _playground page_. The preview handler is an API endpoint that Uniform invokes when preview starts. It is responsible for mapping the composition ID under preview to a redirect to the correct frontend route to display that composition. The default handler does this using project map hierarchy.
|
|
181
|
+
|
|
182
|
+
`pages/api/preview.ts`:
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import { createPreviewHandler } from "@uniformdev/canvas-next";
|
|
186
|
+
|
|
187
|
+
const handler = createPreviewHandler({
|
|
188
|
+
// this is set in .env to an arbitrary value
|
|
189
|
+
secret: () => process.env.UNIFORM_PREVIEW_SECRET,
|
|
190
|
+
// optionally configure the playground route to enable previewing patterns
|
|
191
|
+
playgroundPath: "/playground",
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
export default handler;
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The preview playground is a special route used to preview Uniform Patterns (reusable chunks of a page). The playground route includes the global page shell of the application:
|
|
198
|
+
|
|
199
|
+
`pages/playground.tsx`:
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { UniformPlayground } from "@uniformdev/canvas-react";
|
|
203
|
+
|
|
204
|
+
export default function Playground() {
|
|
205
|
+
// wrap UniformPlayground in your page shell/styles to wrap the pattern previews with
|
|
206
|
+
return <UniformPlayground behaviorTracking="onLoad" />;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Configuring Personalization and A/B Testing (Uniform Context)
|
|
211
|
+
|
|
212
|
+
### Required Context Packages
|
|
213
|
+
|
|
214
|
+
The following npm packages must be installed to enable Uniform Context on Next Page Router:
|
|
215
|
+
|
|
216
|
+
@uniformdev/context
|
|
217
|
+
@uniformdev/context-next
|
|
218
|
+
@uniformdev/context-react
|
|
219
|
+
@uniformdev/cli
|
|
220
|
+
|
|
221
|
+
### Pulling the Uniform Context Manifest
|
|
222
|
+
|
|
223
|
+
Uniform Context relies on a static _manifest_ that defines user classification criteria and active test names. This manifest is downloaded using an API endpoint to a local file that is built into the application. The following package.json script can be used to invoke the manifest download:
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
"uniform:pull:manifest": "uniform context manifest download --output ./src/uniform/contextManifest.json"
|
|
227
|
+
```
|
|
228
|
+
The "dev" and "build" npm scripts should run "uniform:pull:manifest" before beginning their regular tasks.
|
|
229
|
+
|
|
230
|
+
### Enable Uniform Context SDK
|
|
231
|
+
|
|
232
|
+
In order to initialize Uniform Context, we need to configure it and provide the manifest to it:
|
|
233
|
+
|
|
234
|
+
`src/uniform/createUniformContext.ts`:
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
import {
|
|
238
|
+
Context,
|
|
239
|
+
ManifestV2,
|
|
240
|
+
ContextPlugin,
|
|
241
|
+
enableDebugConsoleLogDrain,
|
|
242
|
+
enableContextDevTools
|
|
243
|
+
} from "@uniformdev/context";
|
|
244
|
+
import { NextCookieTransitionDataStore } from "@uniformdev/context-next";
|
|
245
|
+
import { NextPageContext } from "next";
|
|
246
|
+
import manifest from "./contextManifest.json";
|
|
247
|
+
|
|
248
|
+
export function createUniformContext(
|
|
249
|
+
serverContext?: NextPageContext
|
|
250
|
+
): Context {
|
|
251
|
+
const plugins: ContextPlugin[] = [
|
|
252
|
+
// optional, but smart defaults to help with debugging setup
|
|
253
|
+
enableContextDevTools(),
|
|
254
|
+
enableDebugConsoleLogDrain("debug"),
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
const context = new Context({
|
|
258
|
+
// disables needing visitor consent before storing data (for testing)
|
|
259
|
+
defaultConsent: true,
|
|
260
|
+
manifest: manifest as ManifestV2,
|
|
261
|
+
transitionStore: new NextCookieTransitionDataStore({
|
|
262
|
+
serverContext,
|
|
263
|
+
}),
|
|
264
|
+
plugins,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return context;
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The context instance must then be provided to the `_app.tsx` so Uniform knows about it when rendering:
|
|
272
|
+
|
|
273
|
+
`pages/_app.tsx`:
|
|
274
|
+
```tsx
|
|
275
|
+
import { UniformContext } from "@uniformdev/context-react";
|
|
276
|
+
import { UniformAppProps } from "@uniformdev/context-next";
|
|
277
|
+
import { createUniformContext } from "../uniform/createUniformContext";
|
|
278
|
+
|
|
279
|
+
const clientContext = createUniformContext();
|
|
280
|
+
|
|
281
|
+
function MyApp({
|
|
282
|
+
Component,
|
|
283
|
+
pageProps,
|
|
284
|
+
serverUniformContext,
|
|
285
|
+
}: UniformAppProps) {
|
|
286
|
+
return (
|
|
287
|
+
<UniformContext
|
|
288
|
+
context={serverUniformContext ?? clientContext}
|
|
289
|
+
outputType={"standard"}
|
|
290
|
+
>
|
|
291
|
+
<Component {...pageProps} />
|
|
292
|
+
</UniformContext>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export default MyApp;
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
We must also configure the server-side Uniform Context instance when using server-side rendering:
|
|
300
|
+
|
|
301
|
+
`pages/_document.tsx`:
|
|
302
|
+
```tsx
|
|
303
|
+
import { enableNextSsr } from "@uniformdev/context-next";
|
|
304
|
+
import { createUniformContext } from "../uniform/uniformContext";
|
|
305
|
+
|
|
306
|
+
// required to enable SSR personalization
|
|
307
|
+
static async getInitialProps(
|
|
308
|
+
ctx: DocumentContext
|
|
309
|
+
): Promise<DocumentInitialProps> {
|
|
310
|
+
const serverTracker = createUniformContext(ctx);
|
|
311
|
+
enableNextSsr(ctx, serverTracker);
|
|
312
|
+
return await Document.getInitialProps(ctx);
|
|
313
|
+
}
|
|
314
|
+
```
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
description:
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Uniform React Next App Router Developer Reference
|
|
7
|
+
|
|
8
|
+
This document details how to use Uniform with React.js with Next App Router.
|
|
9
|
+
|
|
10
|
+
@uniform.mdc describes general Uniform principles and practices.
|
|
11
|
+
@uniform-sdk.mdc describes framework-agnostic developer principles.
|
|
12
|
+
|
|
13
|
+
### Required npm packages
|
|
14
|
+
|
|
15
|
+
The following npm packages must be installed to wire Uniform to Next App Router:
|
|
16
|
+
|
|
17
|
+
@uniformdev/canvas-next-rsc
|
|
18
|
+
@uniformdev/canvas
|
|
19
|
+
|
|
20
|
+
### Fetching and rendering the composition
|
|
21
|
+
|
|
22
|
+
In your dynamic route file (`app/[[...path]]/page.{tsx|jsx}`), it is necessary to fetch the Uniform composition instance for the current route.
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import {
|
|
26
|
+
UniformComposition,
|
|
27
|
+
PageParameters,
|
|
28
|
+
retrieveRoute,
|
|
29
|
+
} from "@uniformdev/canvas-next-rsc";
|
|
30
|
+
import { resolveComponent } from "@/uniform/resolve";
|
|
31
|
+
|
|
32
|
+
export default async function Page(props: PageParameters) {
|
|
33
|
+
const route = await retrieveRoute(props);
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<UniformComposition
|
|
37
|
+
{...props}
|
|
38
|
+
route={route}
|
|
39
|
+
resolveComponent={resolveComponent}
|
|
40
|
+
mode="server"
|
|
41
|
+
/>
|
|
42
|
+
</>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Wrapping page in Uniform Context
|
|
48
|
+
|
|
49
|
+
In order for personalization and A/B testing functionality to work client side, we must wrap the entire page in the UniformContext component. This should modify `app/layout.tsx` and wrap `{children}`.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { UniformContext } from "@uniformdev/canvas-next-rsc";
|
|
53
|
+
|
|
54
|
+
export default function RootLayout({
|
|
55
|
+
children,
|
|
56
|
+
}: {
|
|
57
|
+
children: React.ReactNode;
|
|
58
|
+
}) {
|
|
59
|
+
return (
|
|
60
|
+
<html lang="en">
|
|
61
|
+
<body>
|
|
62
|
+
<main className="main">
|
|
63
|
+
<UniformContext>{children}</UniformContext>
|
|
64
|
+
</main>
|
|
65
|
+
</body>
|
|
66
|
+
</html>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Rendering Uniform Components using React Components
|
|
72
|
+
|
|
73
|
+
The `UniformComposition` component needs to know how to map a Uniform Component instance's `type` to a React component that implements the UI for that component. This is done using resolveComponent. To use the component registry, first create a component:
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
export const HeaderComponent = () => {
|
|
77
|
+
return <>Header</>;
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Then register it in the resolveComponent function:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import {
|
|
85
|
+
DefaultNotImplementedComponent,
|
|
86
|
+
ResolveComponentFunction,
|
|
87
|
+
ResolveComponentResult,
|
|
88
|
+
} from "@uniformdev/canvas-next-rsc/component";
|
|
89
|
+
import { HeaderComponent } from "@/components/header";
|
|
90
|
+
|
|
91
|
+
export const resolveComponent: ResolveComponentFunction = ({ component }) => {
|
|
92
|
+
let result: ResolveComponentResult = {
|
|
93
|
+
component: DefaultNotImplementedComponent,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (component.type === "header") {
|
|
97
|
+
result = {
|
|
98
|
+
component: HeaderComponent,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return result;
|
|
103
|
+
};
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Mapping Uniform Components to React Components
|
|
107
|
+
|
|
108
|
+
React components that receive Uniform Component data are passed props that correspond to the shape of the component definition they render. The `ComponentProps` type can be used to make the mapping explicit:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { ComponentProps } from "@uniformdev/canvas-next-rsc/component";
|
|
112
|
+
import { RichTextParamValue } from "@uniformdev/canvas";
|
|
113
|
+
|
|
114
|
+
type HeaderParameters = {
|
|
115
|
+
textParameter?: string;
|
|
116
|
+
richTextParameter?: RichTextParamValue;
|
|
117
|
+
// it is critical that all parameter props values are optional, because they can be undefined - even if 'required' on the component definition
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type HeaderProps = ComponentProps<HeaderParameters>;
|
|
121
|
+
|
|
122
|
+
export const HeaderComponent = ({ textParameter }: HeaderProps) => {
|
|
123
|
+
return (
|
|
124
|
+
<>
|
|
125
|
+
<span>{textParameter}</span>
|
|
126
|
+
</>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Rendering child slots
|
|
132
|
+
|
|
133
|
+
If a Uniform Component definition has slots defined, the components in those slots can be rendered using the `UniformSlot` component.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import {
|
|
137
|
+
ComponentProps,
|
|
138
|
+
UniformSlot,
|
|
139
|
+
} from "@uniformdev/canvas-next-rsc/component";
|
|
140
|
+
import { RichTextParamValue } from "@uniformdev/canvas";
|
|
141
|
+
|
|
142
|
+
type HeaderParameters = {
|
|
143
|
+
textParameter?: string;
|
|
144
|
+
richTextParameter?: RichTextParamValue;
|
|
145
|
+
// it is critical that all parameter props values are optional, because they can be undefined - even if 'required' on the component definition
|
|
146
|
+
};
|
|
147
|
+
type HeaderSlots = "logo" | "navigation";
|
|
148
|
+
|
|
149
|
+
type HeaderProps = ComponentProps<HeaderParameters, HeaderSlots>;
|
|
150
|
+
|
|
151
|
+
export const HeaderComponent = ({ slots, context, component }: HeaderProps) => {
|
|
152
|
+
return (
|
|
153
|
+
<>
|
|
154
|
+
<UniformSlot context={context} data={component} slot={slots.logo} />
|
|
155
|
+
<UniformSlot context={context} data={component} slot={slots.navigation} />
|
|
156
|
+
</>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Rendering parameter values
|
|
162
|
+
|
|
163
|
+
When rendering a `text` type parameter, using the `UniformText` component will enable authors to edit the value within the Uniform preview directly. Text parameters that do not have a visible component, such as alt text, should be rendered as their raw text value:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import {
|
|
167
|
+
ComponentProps,
|
|
168
|
+
UniformText,
|
|
169
|
+
} from "@uniformdev/canvas-next-rsc/component";
|
|
170
|
+
import { RichTextParamValue } from "@uniformdev/canvas";
|
|
171
|
+
|
|
172
|
+
type HeaderParameters = {
|
|
173
|
+
textParameter?: string;
|
|
174
|
+
richTextParameter?: RichTextParamValue;
|
|
175
|
+
// it is critical that all parameter props values are optional, because they can be undefined - even if 'required' on the component definition
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
type HeaderProps = ComponentProps<HeaderParameters>;
|
|
179
|
+
|
|
180
|
+
export const HeaderComponent = ({ component, context }: HeaderProps) => {
|
|
181
|
+
return (
|
|
182
|
+
<>
|
|
183
|
+
<UniformText
|
|
184
|
+
component={component}
|
|
185
|
+
context={context}
|
|
186
|
+
parameterId="textParameter"
|
|
187
|
+
as="h1"
|
|
188
|
+
/>
|
|
189
|
+
</>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
For rich text parameters, the `UniformRichText` component will automatically render the rich text stored as JSON to HTML:
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
import {
|
|
198
|
+
ComponentProps,
|
|
199
|
+
UniformRichText,
|
|
200
|
+
} from "@uniformdev/canvas-next-rsc/component";
|
|
201
|
+
import { RichTextParamValue } from "@uniformdev/canvas";
|
|
202
|
+
|
|
203
|
+
type HeaderParameters = {
|
|
204
|
+
textParameter?: string;
|
|
205
|
+
richTextParameter?: RichTextParamValue;
|
|
206
|
+
// it is critical that all parameter props values are optional, because they can be undefined - even if 'required' on the component definition
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
type HeaderProps = ComponentProps<HeaderParameters>;
|
|
210
|
+
|
|
211
|
+
export const HeaderComponent = ({ component, context }: HeaderProps) => {
|
|
212
|
+
return (
|
|
213
|
+
<>
|
|
214
|
+
<UniformRichText
|
|
215
|
+
component={component}
|
|
216
|
+
context={context}
|
|
217
|
+
parameterId="richTextParameter"
|
|
218
|
+
/>
|
|
219
|
+
</>
|
|
220
|
+
);
|
|
221
|
+
};
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Note: asset parameters are rendered directly from props, there is no `UniformAsset` component.
|
|
225
|
+
|
|
226
|
+
### Configuring Contextual Editing Live Preview
|
|
227
|
+
|
|
228
|
+
To enable contextual editing and live preview to operate within the Uniform application, we need to register a _preview handler_ and _playground page_. The preview handler is an API endpoint that Uniform invokes when preview starts. It is responsible for mapping the composition ID under preview to a redirect to the correct frontend route to display that composition. The default handler does this using project map hierarchy.
|
|
229
|
+
|
|
230
|
+
`app/api/preview/route.ts`:
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import {
|
|
234
|
+
createPreviewGETRouteHandler,
|
|
235
|
+
createPreviewPOSTRouteHandler,
|
|
236
|
+
createPreviewOPTIONSRouteHandler,
|
|
237
|
+
} from '@uniformdev/canvas-next-rsc/handler';
|
|
238
|
+
|
|
239
|
+
export const GET = createPreviewGETRouteHandler({
|
|
240
|
+
playgroundPath: '/playground',
|
|
241
|
+
resolveFullPath: ({ path }) => (path ? path : '/playground'),
|
|
242
|
+
});
|
|
243
|
+
export const POST = createPreviewPOSTRouteHandler();
|
|
244
|
+
export const OPTIONS = createPreviewOPTIONSRouteHandler();
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The preview playground is a special route used to preview Uniform Patterns (reusable chunks of a page). It should use the same resolveComponent function. The playground route includes the global page shell of the application:
|
|
248
|
+
|
|
249
|
+
`app/playground/page.tsx`:
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
import {
|
|
253
|
+
UniformPlayground,
|
|
254
|
+
UniformPlaygroundProps,
|
|
255
|
+
} from "@uniformdev/canvas-next-rsc";
|
|
256
|
+
import { resolveComponent } from "@/uniform/resolve";
|
|
257
|
+
|
|
258
|
+
export default function PlaygroundPage(props: {
|
|
259
|
+
searchParams: UniformPlaygroundProps["searchParams"];
|
|
260
|
+
}) {
|
|
261
|
+
return <UniformPlayground {...props} resolveComponent={resolveComponent} />;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
description:
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Uniform SDK Developer Reference
|
|
7
|
+
|
|
8
|
+
This document details general information and practices about how Uniform works for developers writing frontend applications.
|
|
9
|
+
|
|
10
|
+
[uniform.mdc](mdc:.cursor/rules/uniform.mdc) describes general Uniform principles and practices.
|
|
11
|
+
|
|
12
|
+
## Authenticating to Uniform
|
|
13
|
+
|
|
14
|
+
To fetch a composition, you need a Uniform API key configured. API keys are commonly stored as `UNIFORM_API_KEY` in a `.env` file. They follow the format `uf......`. The API key requires "Read Published Compositions" permission.
|
|
15
|
+
|
|
16
|
+
## How Uniform transfers layout data to frontend applications
|
|
17
|
+
|
|
18
|
+
Uniform provides _composition instances_, a hierarchical JSON structure of components that define screens or pages in an application. A composition is made up of any number of _components_ which have a type that we map to a frontend component.
|
|
19
|
+
|
|
20
|
+
### Routing
|
|
21
|
+
|
|
22
|
+
Uniform's _Project Map_ feature enables automatic dynamic route delegation to Uniform authors. Frontend applications define a wildcard route that delegates routing to the Uniform _Route API_, which takes a dynamic path and resolves the correct composition instance data to display for that path.
|
|
23
|
+
|
|
24
|
+
### Syncing data with the Uniform CLI
|
|
25
|
+
|
|
26
|
+
Uniform provides a CLI which can be used to sync the state of a Uniform project, such as component definitions, pattern definitions, or compositions, to files on disk. These files may be committed to source control and used to ensure the states of environment or developer-specific projects are kept up to date to reduce the chance of errors.
|
|
27
|
+
|
|
28
|
+
#### Required package for Uniform CLI
|
|
29
|
+
|
|
30
|
+
The Uniform CLI is contained in the `@uniformdev/cli` npm package.
|
|
31
|
+
|
|
32
|
+
#### Authenticating with the Uniform CLI
|
|
33
|
+
|
|
34
|
+
The Uniform CLI requires a Uniform API key to authenticate. The API key and other connectivity details are stored in a `.env` file. When creating an API key for the CLI, the user can use the "Copy as .env" function in the Uniform dashboard to get the appropriate environment variable values.
|
|
35
|
+
API keys used for the Uniform CLI require read and write permissions to any entity types that are to be synced. The default 'developer' role is a shortcut to full permissions.
|
|
36
|
+
|
|
37
|
+
#### Configuring the Uniform CLI
|
|
38
|
+
|
|
39
|
+
Uniform CLI is configured using the `uniform.config.{ts,js}` file in the root of a project. The file can be configured in two ways: to sync everything (choose this for initial setup), or to pick specific entity types to sync. Sync operates as a mirror by default, meaning creates, updates, and deletes are all synced.
|
|
40
|
+
|
|
41
|
+
`uniform.config.ts` (sync all):
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { uniformConfig } from "@uniformdev/cli/config";
|
|
45
|
+
|
|
46
|
+
export default uniformConfig({ preset: "all" });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`uniform.config.ts` (sync explicit types and customization options):
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { uniformConfig } from "@uniformdev/cli/config";
|
|
53
|
+
|
|
54
|
+
export default uniformConfig({
|
|
55
|
+
// 'none' starts with no entities, and each entity type to sync is added explicitly
|
|
56
|
+
preset: "none",
|
|
57
|
+
config: {
|
|
58
|
+
serialization: {
|
|
59
|
+
// optionally override the default `./uniform-data` to store serialized files
|
|
60
|
+
directory: "./custom-path-to-serialized-files",
|
|
61
|
+
// optionally change the default yaml format to json
|
|
62
|
+
format: "json",
|
|
63
|
+
entitiesConfig: {
|
|
64
|
+
// specify entity types to sync. Each type can optionally override
|
|
65
|
+
// the defaults just for itself, i.e. directory, format
|
|
66
|
+
component: {},
|
|
67
|
+
componentPattern: { publish: true },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Invoking the Uniform CLI
|
|
75
|
+
|
|
76
|
+
The Uniform CLI operates using two primary commands:
|
|
77
|
+
|
|
78
|
+
`uniform sync push` - takes the serialized state of entities (files on disk) and pushes that state into a Uniform project online.
|
|
79
|
+
|
|
80
|
+
`uniform sync pull` - takes the online state of a Uniform project and pulls it into serialized files.
|
|
81
|
+
|
|
82
|
+
Conventionally these commands are registered as package scripts to make it unnecessary to install the CLI package globally:
|
|
83
|
+
|
|
84
|
+
`package.json`:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"scripts": {
|
|
89
|
+
"uniform:pull": "uniform sync pull",
|
|
90
|
+
"uniform:push": "uniform sync push"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Getting Uniform CLI help
|
|
96
|
+
|
|
97
|
+
The Uniform CLI has a built-in help system. To get help on a command, run `uniform <command> --help`, for example `uniform sync pull --help`.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Uniform Content Modeling Reference - details content modeling options and techniques in Uniform CMS
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Uniform Core Concepts
|
|
8
|
+
|
|
9
|
+
Uniform is a modern, headless, component-based Content Management System (CMS). Its primary purpose is to allow non-technical authors (marketers, etc) to create and maintain websites and other similar experiences in a visual editor.
|
|
10
|
+
|
|
11
|
+
### Uniform Compositions
|
|
12
|
+
|
|
13
|
+
A composition instance in Uniform is roughly equivalent to a page. Composition definitions define a reusable schema for composition instances. Composition definitions have a structure identical to a Uniform Component, i.e. parameters and slots. Composition instances differ from components in that they also define a route or page. Instances of a composition create pages or routes within an application. The term "Composition" can be used to refer either to a definition or instance of a composition, you will need to infer which is meant (schema/reusable template = definition, page/route = instance).
|
|
14
|
+
|
|
15
|
+
Composition parameters should only be used for global content that will never need to be personalized.
|
|
16
|
+
Good example: OpenGraph data and meta tags (if they exist)
|
|
17
|
+
Bad example: "hero title" belongs in a Hero component in the content slot.
|
|
18
|
+
|
|
19
|
+
A single composition definition called 'Page' is generally a good starting point. Additional composition definitions are only required if the page shell is different (e.g. Page, Popup, Minimal Page), or if there are different parameters needed on the composition definition
|
|
20
|
+
|
|
21
|
+
In developer terms, a composition instance is a dynamic layout that is defined by non-technical authors; a composition definition is a hierarchical content schema definition.
|
|
22
|
+
|
|
23
|
+
### Uniform Components
|
|
24
|
+
|
|
25
|
+
Uniform Components are used to allow CMS authors to create and manipulate visual elements on a composition. Each property of a Uniform Component, such as a title or image, is called a _Component Parameter_. See _Uniform Parameter/Field Types_ for the exact types of parameter that are allowed. Components have both a definition (their schema) and instances (when an instance of that schema is placed within a slot on a composition).
|
|
26
|
+
|
|
27
|
+
Uniform Components can define named _slots_.
|
|
28
|
+
|
|
29
|
+
- A slot allows additional components to be inserted within the Uniform Component. For example an accordion component could have an 'items' slot that allows adding Accordion Item components.
|
|
30
|
+
- Each named slot has 0..n child components. The order in the slot determines the order of rendering.
|
|
31
|
+
- Each slot definition allows only specific Uniform Components to be placed within it (by public id). It can also define the minimum and maximum number of components allowed.
|
|
32
|
+
- Components allowed within slots can also have their own slots, with no depth limit - but it is generally undesirable to nest more than 2-3 levels deep to improve author understanding.
|
|
33
|
+
- When a Uniform Composition is defined, it almost always has a generic 'content' slot added to it that allows using various components to define the layout.
|
|
34
|
+
|
|
35
|
+
Uniform Component Definition attributes:
|
|
36
|
+
|
|
37
|
+
- _name_
|
|
38
|
+
- _public ID_
|
|
39
|
+
- _parameters_
|
|
40
|
+
- _slots_
|
|
41
|
+
|
|
42
|
+
Uniform Slot Definition attributes:
|
|
43
|
+
|
|
44
|
+
- _name_
|
|
45
|
+
- _public ID_
|
|
46
|
+
- _allowed components_
|
|
47
|
+
- _min components_
|
|
48
|
+
- _max components_
|
|
49
|
+
|
|
50
|
+
In technical terms, a Uniform Component maps directly to a presentational frontend component such as a React component. The parameters are component props. Slots are component props that contain rendered child components.
|
|
51
|
+
|
|
52
|
+
### Uniform Content Types
|
|
53
|
+
|
|
54
|
+
Uniform Content Types define a reusable structure for individual reusable pieces of content. A Uniform content type differs from a Uniform component because a component represents a specific visual element on a composition/page, but a content type is an abstract, reusable content schema. An instance of a Uniform Content Type is called an _Entry_. Entries each have their own built-in slug: there is no need to define an explicit slug field.
|
|
55
|
+
|
|
56
|
+
For example a Product might be a Uniform Content Type, and the data from instances of that Product could be presented in different contexts by Uniform Patterns such as Product List, Product Detail, or Product Card.
|
|
57
|
+
|
|
58
|
+
Uniform Content Types define content properties called _Fields_ (e.g. a blog post could have a single-line text input for title, and a rich text editor for body). See _Uniform Parameter/Field Types_ for the exact types of field that are allowed.
|
|
59
|
+
|
|
60
|
+
Uniform Content Type attributes:
|
|
61
|
+
|
|
62
|
+
- _name_
|
|
63
|
+
- _public ID_
|
|
64
|
+
- _fields_
|
|
65
|
+
|
|
66
|
+
### Uniform Patterns
|
|
67
|
+
|
|
68
|
+
Patterns allow reusing the same content across compositions. The simplest way to think of a pattern is that it is a _shared component instance_ that can be placed within a slot to insert the pattern's content there. The pattern, like any other component instance, can have values in its parameters and child components in its slots. All usages of the same pattern reference the same shared content. Updates made to patterns are immediately reflected to all usages. Patterns may be nested within each other (e.g. a Blog Post Hero pattern could include a Author Bio pattern in one of its slots). Nesting beyond 2-3 levels can cause performance issues.
|
|
69
|
+
|
|
70
|
+
#### Uniform Pattern Overrides
|
|
71
|
+
|
|
72
|
+
Parameters on patterns can be defined _overridable_ by the pattern definition. Overridable parameter values default to using the value defined on the pattern, but consumers of the pattern may choose to break the inheritance of that parameter value and replace it with their own instance-specific value. Patterns that contain other patterns may not alter the overridability of nested pattern parameters: once overridable, any consumer of the pattern can change the value. Overrides are used to allow partial content sharing and exception cases.
|
|
73
|
+
|
|
74
|
+
#### Using Uniform Patterns as Shared Content Snippets
|
|
75
|
+
|
|
76
|
+
Patterns can be used to reuse shared content, for example the same legal disclaimer might be required on every press release. Both patterns and components allow content reuse: the difference is that patterns reuse exact content, whereas components reuse content schemas but do not provide content values.
|
|
77
|
+
|
|
78
|
+
#### Using Uniform Patterns as Data Binding Templates
|
|
79
|
+
|
|
80
|
+
Patterns can be used to create bindings between structured data (from Uniform Entries or external data sources, like REST APIs or other CMSes) and presentation parameters. A pattern can define a _Data Resource_ which is the result of fetching from a data source. Then parameters in the pattern can use _Dynamic Tokens_ to bind to elements within the data resource. For example, we might have a Card component that has a title and image. Then we create a Product Card pattern, based on the Card component, which has a Uniform Entry Data Resource that fetches an entry specified by the pattern consumer. The Product Card automatically binds the title and image from the product entry to the Card component's parameters. As an author, one can then insert a Product Card pattern, choose the product to use, and have the title and image automatically set up for them.
|
|
81
|
+
|
|
82
|
+
Example of a resolved Data Resource (named 'myEntry'):
|
|
83
|
+
{ "myEntry": { "fields": { "title": "hello world" } } }
|
|
84
|
+
|
|
85
|
+
Example of a Dynamic Token in a text parameter referencing the myEntry title:
|
|
86
|
+
"today's greeting: ${#jptr:/myEntry/fields/title}" (this resolves to "today's greeting: hello world")
|
|
87
|
+
|
|
88
|
+
#### Uniform Pattern attributes
|
|
89
|
+
|
|
90
|
+
- _name_
|
|
91
|
+
- _type_ - public ID of the base Uniform Component
|
|
92
|
+
- _public id_ - id of the pattern
|
|
93
|
+
- _data resources_ (name, type)
|
|
94
|
+
- _parameters_ (value, overridable)
|
|
95
|
+
- _slots_
|
|
96
|
+
|
|
97
|
+
## Conventions
|
|
98
|
+
|
|
99
|
+
### Uniform Field/Parameter Types
|
|
100
|
+
|
|
101
|
+
Uniform Fields or Uniform Parameters attributes:
|
|
102
|
+
|
|
103
|
+
- _name_
|
|
104
|
+
- _public ID_. Must be unique within a Uniform Component or Uniform Content Type (including the ID of group fields/parameters)
|
|
105
|
+
- _localizable_. Localizable values have a distinct value for each locale; otherwise the value is the same for all locales.
|
|
106
|
+
- _required_. Required means that a CMS author must input a value in order to be considered valid.
|
|
107
|
+
- _type_. See list below.
|
|
108
|
+
- _guidance_. Brief LLM instructions used when generating or editing values.
|
|
109
|
+
- _overridable_. Only applies for fields/parameters on a pattern definition. Allows consumers of the pattern to break inheritance and change the pattern definition's value for the field/parameter.
|
|
110
|
+
|
|
111
|
+
Exhaustive list of allowed field/parameter types:
|
|
112
|
+
|
|
113
|
+
- _text_: Plain text content
|
|
114
|
+
- _richText_: Formatted text with styling (Lexical JSON format)
|
|
115
|
+
- _select_: Choose between a controlled vocabulary of options
|
|
116
|
+
- _multi-select_: Choose between a controlled vocabulary of options, allowing multiple selections
|
|
117
|
+
- _number_: Numeric value
|
|
118
|
+
- _date_: Calendar date
|
|
119
|
+
- _dateTime_: Date with timezone
|
|
120
|
+
- _checkbox_: Boolean toggle
|
|
121
|
+
- _link_: URL or internal reference
|
|
122
|
+
- _asset_: Image, video, audio, or other file
|
|
123
|
+
- _json_: A JSON object. Not for use in author-facing fields/parameters, who will have trouble editing JSON.
|
|
124
|
+
- _contentReference_: References a single or multiple Entries of a specified type. Can only be used in Fields on Content Types (not Parameters on Components)
|
|
125
|
+
- _enrichmentTag_: Tag content with enrichments (relevant segments) to make viewing the content alter the classification of the visitor that saw it.
|
|
126
|
+
- _group_: Group multiple fields/parameters together visually, for example a group of address fields. IMPORTANT: fields added to a group must come directly after the group in the fields list.
|
|
127
|
+
|
|
128
|
+
### Uniform Naming Conventions
|
|
129
|
+
|
|
130
|
+
- All names should be title-cased prose, not technical shorthand (e.g. "Main Header" not "main-header" or "MainHeader"). There is no need to include the type of entity in a name (e.g. 'Hero' not 'Hero Component').
|
|
131
|
+
- Do not name Uniform Components, Uniform Content Types, or Fields/Parameters based on visible content found in inputs; treat it as FPO (e.g. <h1>Hello</h1> does not mean name the component 'Hello' - describe its meaning instead, such as 'Headline').
|
|
132
|
+
- _Public ID_ are developer-facing identifiers for Uniform entities. They are based on a slugified version of the name. Use a camel case, for example if the name is "Main Header", the public ID is "mainHeader". Public IDs must be unique within a given entity type (e.g. Uniform Components). You cannot alter public IDs after creating an entity.
|
|
133
|
+
- Descriptions or help text should be no longer than 1 short sentence. It is not necessary to write help text unless we have specific expectations for authors. For example a 'Title' doesn't need help text. But if we identify an image that needs to be 250x250px, that expectation belongs in help text. Descriptions and help text are plain text, no markdown or HTML.
|
|
134
|
+
|
|
135
|
+
## Tool Usage Tips
|
|
136
|
+
|
|
137
|
+
- Before creating or updating Uniform Patterns, fetch Uniform Component Definitions to ensure you know about valid component types and parameters.
|
|
138
|
+
- When making multiple updates to the same Uniform Pattern, such as adding a component and setting a parameter value, batch changes together into a single tool call to improve performance and consistency.
|
|
139
|
+
- When a Uniform tool provides you with an edit URL offer it to the user as a link, unless you already have recently.
|
|
140
|
+
- Before inserting, removing, or reordering parameters or fields from a Uniform Component or Uniform Content Type, make sure to fetch the latest definition data to ensure you target the correct location.
|
|
141
|
+
- If you are tasked with reordering fields or parameters, you must remove them and re-add them in the new order
|
|
142
|
+
|
|
143
|
+
## Unsupported Features
|
|
144
|
+
|
|
145
|
+
The following Uniform features cannot currently be changed using MCP/AI. If asked to perform the following actions, explain you cannot yet do that, and when possible offer a link to perform the task in the Uniform web app.
|
|
146
|
+
|
|
147
|
+
- Managing Uniform locales, both global registration and enablement on compositions or entries
|
|
148
|
+
- Managing the project map, including adding or fetching nodes, or attaching compositions to project map nodes.
|
|
149
|
+
- Managing compositions or entries (creating, updating)
|
|
150
|
+
- Managing entry patterns
|
|
151
|
+
- Managing block fields/parameters, or block type definitions
|
|
152
|
+
- Setting the value of asset or reference type fields/parameters
|
|
153
|
+
- Data sources, data types, and data resources
|