@dotcms/client 1.0.0 → 1.0.2
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/CLAUDE.md +253 -0
- package/MIGRATION.md +329 -0
- package/README.md +250 -434
- package/dotcms-client-1.0.1.tgz +0 -0
- package/index.cjs.js +1 -0
- package/index.esm.js +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,36 +17,40 @@ The `@dotcms/client` is a powerful JavaScript/TypeScript SDK designed to simplif
|
|
|
17
17
|
- **Security First**: Handles authentication and requests securely
|
|
18
18
|
- **Developer Experience**: Rich autocompletion and documentation
|
|
19
19
|
|
|
20
|
+
> **📋 Migrating from Alpha Version?** If you're upgrading from the alpha version of `@dotcms/client`, please see our [Migration Guide](./MIGRATION.md) for step-by-step instructions and troubleshooting tips.
|
|
21
|
+
|
|
20
22
|
## Table of Contents
|
|
21
23
|
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [Create a dotCMS API Key](#create-a-dotcms-api-key)
|
|
24
|
+
- [Getting Started](#getting-started)
|
|
25
|
+
- [Prerequisites & Setup](#prerequisites--setup)
|
|
25
26
|
- [Installation](#installation)
|
|
26
|
-
- [
|
|
27
|
+
- [Your First API Call](#your-first-api-call)
|
|
27
28
|
- [Example Projects](#example-projects)
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
29
|
+
- [How-to Guides](#how-to-guides)
|
|
30
|
+
- [How to Fetch Complete Pages](#how-to-fetch-complete-pages)
|
|
31
|
+
- [How to Query Content Collections](#how-to-query-content-collections)
|
|
32
|
+
- [How to Work with GraphQL](#how-to-work-with-graphql)
|
|
33
|
+
- [How to Use with TypeScript](#how-to-use-with-typescript)
|
|
34
|
+
- [How to Enable Page Editing](#how-to-enable-page-editing)
|
|
31
35
|
- [API Reference](#api-reference)
|
|
32
36
|
- [Client Initialization](#client-initialization)
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
- [
|
|
37
|
-
- [
|
|
38
|
-
- [
|
|
39
|
-
- [
|
|
40
|
-
|
|
41
|
-
- [dotCMS Support](#dotcms-support)
|
|
42
|
-
- [How To Contribute](#how-to-contribute)
|
|
43
|
-
- [Licensing Information](#licensing-information)
|
|
37
|
+
- [page.get() Method](#pageget-method)
|
|
38
|
+
- [content.getCollection() Method](#contentgetcollection-method)
|
|
39
|
+
- [navigation.get() Method](#navigationget-method)
|
|
40
|
+
- [Concepts & Architecture](#concepts--architecture)
|
|
41
|
+
- [Key Concepts](#key-concepts)
|
|
42
|
+
- [Choosing the Right Method](#choosing-the-right-method)
|
|
43
|
+
- [Architecture Overview](#architecture-overview)
|
|
44
|
+
- [Support & Contributing](#support--contributing)
|
|
45
|
+
- [dotCMS Support](#dotcms-support)
|
|
46
|
+
- [How To Contribute](#how-to-contribute)
|
|
47
|
+
- [Licensing Information](#licensing-information)
|
|
44
48
|
|
|
45
|
-
##
|
|
49
|
+
## Getting Started
|
|
46
50
|
|
|
47
|
-
###
|
|
51
|
+
### Prerequisites & Setup
|
|
48
52
|
|
|
49
|
-
####
|
|
53
|
+
#### Get a dotCMS Environment
|
|
50
54
|
|
|
51
55
|
- **Recommended**: dotCMS Evergreen
|
|
52
56
|
- **Minimum**: dotCMS v25.05
|
|
@@ -70,7 +74,7 @@ The `@dotcms/client` is a powerful JavaScript/TypeScript SDK designed to simplif
|
|
|
70
74
|
- 🐳 [Docker setup guide](https://github.com/dotCMS/core/tree/main/docker/docker-compose-examples/single-node-demo-site)
|
|
71
75
|
- 💻 [Local installation guide](https://dev.dotcms.com/docs/quick-start-guide)
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
#### Create a dotCMS API Key
|
|
74
78
|
|
|
75
79
|
> [!TIP]
|
|
76
80
|
> Make sure your API Token has read-only permissions for Pages, Folders, Assets, and Content. Using a key with minimal permissions follows security best practices.
|
|
@@ -84,7 +88,7 @@ This integration requires an API Key with read-only permissions for security bes
|
|
|
84
88
|
|
|
85
89
|
For detailed instructions, please refer to the [dotCMS API Documentation - Read-only token](https://dev.dotcms.com/docs/rest-api-authentication#ReadOnlyToken).
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
#### Installation
|
|
88
92
|
|
|
89
93
|
Install the SDK and required dependencies:
|
|
90
94
|
|
|
@@ -95,7 +99,7 @@ npm install @dotcms/client@latest @dotcms/types@latest
|
|
|
95
99
|
> [!TIP]
|
|
96
100
|
> If you are working with pure JavaScript, you can avoid installing the `@dotcms/types` package.
|
|
97
101
|
|
|
98
|
-
|
|
102
|
+
### Your First API Call
|
|
99
103
|
|
|
100
104
|
Here's a basic setup of the dotCMS Client SDK to help you get started:
|
|
101
105
|
|
|
@@ -114,7 +118,7 @@ const { pageAsset } = await client.page.get('/about-us');
|
|
|
114
118
|
console.log(pageAsset.page.title);
|
|
115
119
|
```
|
|
116
120
|
|
|
117
|
-
###
|
|
121
|
+
### Example Projects
|
|
118
122
|
|
|
119
123
|
While there isn't a dedicated example project specifically for the client SDK, you can see it in action within these full-stack examples:
|
|
120
124
|
|
|
@@ -124,95 +128,22 @@ While there isn't a dedicated example project specifically for the client SDK, y
|
|
|
124
128
|
|
|
125
129
|
These examples demonstrate how to use the client SDK as part of a complete web application.
|
|
126
130
|
|
|
127
|
-
##
|
|
128
|
-
|
|
129
|
-
| Term | Description | Documentation |
|
|
130
|
-
| ------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
131
|
-
| `pageAsset` | The page data structure containing layout and content | [Page API](https://dev.dotcms.com/docs/page-rest-api-layout-as-a-service-laas) |
|
|
132
|
-
| `contentlet` | A single piece of content in dotCMS | [Content API](https://dev.dotcms.com/docs/content) |
|
|
133
|
-
| `collection` | A group of contentlets of the same type | [Content API](https://dev.dotcms.com/docs/search) |
|
|
134
|
-
| `graphql` | Query language used to extend API responses | [GraphQL](https://dev.dotcms.com/docs/graphql) |
|
|
135
|
-
|
|
136
|
-
## Choosing the Right Method
|
|
137
|
-
|
|
138
|
-
The dotCMS Client SDK provides three core methods for fetching data. Use this quick guide to decide which one is best for your use case:
|
|
139
|
-
|
|
140
|
-
| Method | Use When You Need... | Best For |
|
|
141
|
-
| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
142
|
-
| [`client.page.get()`](#clientpageget-fetching-page-content) | A full page with layout, containers, and related content | **Rendering entire pages** with a single request. Ideal for headless setups, SSR/SSG frameworks, and cases where you want everything—page structure, content, and navigation—tied to a URL path. |
|
|
143
|
-
| [`client.content.getCollection()`](#clientcontentgetcollection-fetching-content-collections) | A filtered list of content items from a specific content type | Populating dynamic blocks, lists, search results, widgets, or reusable components. |
|
|
144
|
-
| [`client.navigation.get()`](#clientnavigationget-fetching-navigation-structure) | Only the site's navigation structure (folders and links) | Standalone menus or use cases where navigation is needed outside of page context. |
|
|
145
|
-
|
|
146
|
-
### Start with `page.get()`: The One-Request Solution
|
|
147
|
-
|
|
148
|
-
For most use cases, `client.page.get()` is all you need. It lets you retrieve:
|
|
149
|
-
|
|
150
|
-
- The full page layout
|
|
151
|
-
- Related content
|
|
152
|
-
- Navigation structure
|
|
153
|
-
|
|
154
|
-
All in a single request using GraphQL.
|
|
155
|
-
|
|
156
|
-
Only use `content.getCollection()` or `navigation.get()` if you have advanced needs, like real-time data fetching or building custom dynamic components.
|
|
157
|
-
|
|
158
|
-
> 🔍 **For an example of how to bundle content and navigation in one `page.get()` call,** see the [advanced usage](#fetching-additional-content-with-graphql) section under `client.page.get()`.
|
|
159
|
-
|
|
160
|
-
## API Reference
|
|
161
|
-
|
|
162
|
-
### createDotCMSClient: Client Initialization
|
|
131
|
+
## How-to Guides
|
|
163
132
|
|
|
164
|
-
|
|
133
|
+
### How to Fetch Complete Pages
|
|
165
134
|
|
|
166
|
-
|
|
167
|
-
| ---------------- | -------------- | -------- | ------------------------------------------------------------- |
|
|
168
|
-
| `dotcmsUrl` | string | ✅ | Your dotCMS instance URL |
|
|
169
|
-
| `authToken` | string | ✅ | Authentication token |
|
|
170
|
-
| `siteId` | string | ❌ | Site identifier (falls back to default site if not specified) |
|
|
171
|
-
| `requestOptions` | RequestOptions | ❌ | Additional fetch options |
|
|
172
|
-
|
|
173
|
-
#### Initialization Example
|
|
135
|
+
The `client.page.get()` method is your primary tool for retrieving full page content. Here's how to use it effectively:
|
|
174
136
|
|
|
137
|
+
#### Basic Page Fetching
|
|
175
138
|
```typescript
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const client = createDotCMSClient({
|
|
179
|
-
dotcmsUrl: 'https://your-dotcms-instance.com',
|
|
180
|
-
authToken: 'your-auth-token',
|
|
181
|
-
siteId: 'your-site-id',
|
|
182
|
-
requestOptions: {
|
|
183
|
-
headers: { 'Custom-Header': 'value' },
|
|
184
|
-
cache: 'default'
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### client.page.get(): Fetching Page Content
|
|
190
|
-
|
|
191
|
-
The `client.page.get()` method is your primary way to retrieve page content from dotCMS using the SDK. It abstracts away the complexity of raw REST or GraphQL calls, letting you fetch structured page data with just a single method.
|
|
192
|
-
|
|
193
|
-
#### Why Use `page.get()`?
|
|
194
|
-
|
|
195
|
-
- Fetch everything needed to render a page with one call
|
|
196
|
-
- Avoid building multiple API queries manually
|
|
197
|
-
- Type-safe, customizable, and extensible with GraphQL
|
|
198
|
-
- Works with dotCMS content localization and personalization out of the box
|
|
199
|
-
|
|
200
|
-
#### Basic Usage
|
|
201
|
-
|
|
202
|
-
Here's the simplest way to fetch a page by its URL:
|
|
203
|
-
|
|
204
|
-
```ts
|
|
139
|
+
// Fetch a page with its layout and content
|
|
205
140
|
const { pageAsset } = await client.page.get('/about-us');
|
|
206
141
|
console.log(pageAsset.page.title);
|
|
207
142
|
```
|
|
208
143
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
You can customize the request to fetch different languages, rendering modes, or user personas:
|
|
214
|
-
|
|
215
|
-
```ts
|
|
144
|
+
#### Customizing Page Requests
|
|
145
|
+
```typescript
|
|
146
|
+
// Fetch with specific language and persona
|
|
216
147
|
const { pageAsset } = await client.page.get('/about-us', {
|
|
217
148
|
languageId: '2',
|
|
218
149
|
fireRules: true,
|
|
@@ -220,19 +151,11 @@ const { pageAsset } = await client.page.get('/about-us', {
|
|
|
220
151
|
});
|
|
221
152
|
```
|
|
222
153
|
|
|
223
|
-
####
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```ts
|
|
154
|
+
#### Fetching Related Content
|
|
155
|
+
```typescript
|
|
156
|
+
// Pull in additional content with GraphQL
|
|
228
157
|
const { pageAsset, content } = await client.page.get('/about-us', {
|
|
229
158
|
graphql: {
|
|
230
|
-
page: `
|
|
231
|
-
title
|
|
232
|
-
vanityUrl {
|
|
233
|
-
url
|
|
234
|
-
}
|
|
235
|
-
`,
|
|
236
159
|
content: {
|
|
237
160
|
blogPosts: `
|
|
238
161
|
BlogCollection(limit: 3) {
|
|
@@ -244,10 +167,6 @@ const { pageAsset, content } = await client.page.get('/about-us', {
|
|
|
244
167
|
DotNavigation(uri: "/", depth: 2) {
|
|
245
168
|
href
|
|
246
169
|
title
|
|
247
|
-
children {
|
|
248
|
-
href
|
|
249
|
-
title
|
|
250
|
-
}
|
|
251
170
|
}
|
|
252
171
|
`
|
|
253
172
|
}
|
|
@@ -255,384 +174,281 @@ const { pageAsset, content } = await client.page.get('/about-us', {
|
|
|
255
174
|
});
|
|
256
175
|
```
|
|
257
176
|
|
|
258
|
-
|
|
177
|
+
### How to Query Content Collections
|
|
259
178
|
|
|
260
|
-
The `
|
|
179
|
+
The `client.content.getCollection()` method uses a fluent builder pattern for querying content:
|
|
261
180
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
| `personaId` | string | Personalize content based on persona ID |
|
|
267
|
-
| `graphql` | DotCMSGraphQLParams | GraphQL options for extending the response |
|
|
268
|
-
| `fireRules` | boolean | Whether to trigger page rules |
|
|
269
|
-
|
|
270
|
-
The `graphql` option allows you to customize the page and content data returned. It accepts:
|
|
271
|
-
|
|
272
|
-
| Property | Type | Description |
|
|
273
|
-
| ----------- | -------- | ----------------------------------------------------- |
|
|
274
|
-
| `page` | string | GraphQL partial query that will be automatically wrapped with the page context. (you don't need to include the `page(url:"/")` wrapper in your query) |
|
|
275
|
-
| `content` | object | Named queries to fetch additional content |
|
|
276
|
-
| `fragments` | string[] | GraphQL fragments that can be reused across queries |
|
|
277
|
-
| `variables` | object | Variables to pass into the GraphQL queries |
|
|
278
|
-
|
|
279
|
-
> 💡 See [`DotCMSPageRequestParams`](https://github.com/dotCMS/core/blob/6e003eb697554ea9636a1fec59bc0fa020b84390/core-web/libs/sdk/types/src/lib/client/public.ts#L5-L54) for a full list of supported options.
|
|
280
|
-
|
|
281
|
-
#### Method Signature
|
|
282
|
-
|
|
283
|
-
```ts
|
|
284
|
-
get<T extends DotCMSExtendedPageResponse = DotCMSPageResponse>(
|
|
285
|
-
url: string,
|
|
286
|
-
options?: DotCMSPageRequestParams
|
|
287
|
-
): Promise<DotCMSComposedPageResponse<T>>;
|
|
181
|
+
#### Basic Collection Queries
|
|
182
|
+
```typescript
|
|
183
|
+
// Fetch first 10 blog posts
|
|
184
|
+
const blogs = await client.content.getCollection('Blog').limit(10).page(1);
|
|
288
185
|
```
|
|
289
186
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
187
|
+
#### Filtering and Sorting
|
|
188
|
+
```typescript
|
|
189
|
+
// Filter by title and sort by date
|
|
190
|
+
const filtered = await client.content
|
|
191
|
+
.getCollection('Blog')
|
|
192
|
+
.query((qb) => qb.field('title').equals('dotCMS*'))
|
|
193
|
+
.limit(5)
|
|
194
|
+
.sortBy([{ field: 'publishDate', direction: 'desc' }]);
|
|
195
|
+
```
|
|
297
196
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
197
|
+
#### Complex Queries
|
|
198
|
+
```typescript
|
|
199
|
+
// Multiple filters with operators
|
|
200
|
+
const products = await client.content
|
|
201
|
+
.getCollection('Product')
|
|
202
|
+
.query((qb) => qb
|
|
203
|
+
.field('category').equals('electronics')
|
|
204
|
+
.and()
|
|
205
|
+
.field('price').raw(':[100 TO 500]')
|
|
206
|
+
.not()
|
|
207
|
+
.field('discontinued').equals('true')
|
|
208
|
+
)
|
|
209
|
+
.limit(10);
|
|
301
210
|
```
|
|
302
211
|
|
|
303
|
-
|
|
212
|
+
### How to Work with GraphQL
|
|
304
213
|
|
|
305
|
-
|
|
214
|
+
GraphQL allows you to fetch exactly the data you need in a single request:
|
|
306
215
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
216
|
+
#### Fetching All Page Fields
|
|
217
|
+
```typescript
|
|
218
|
+
// Use _map to get all page fields including custom ones
|
|
219
|
+
const { pageAsset } = await client.page.get('/about-us', {
|
|
220
|
+
graphql: {
|
|
221
|
+
page: '_map'
|
|
222
|
+
}
|
|
311
223
|
});
|
|
312
224
|
```
|
|
313
225
|
|
|
314
|
-
####
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
226
|
+
#### Querying Relationships
|
|
227
|
+
```typescript
|
|
228
|
+
// Fetch related content using fragments
|
|
229
|
+
const { pageAsset } = await client.page.get('/blog-post', {
|
|
230
|
+
graphql: {
|
|
231
|
+
page: `
|
|
232
|
+
containers {
|
|
233
|
+
containerContentlets {
|
|
234
|
+
contentlets {
|
|
235
|
+
... on Blog {
|
|
236
|
+
author {
|
|
237
|
+
title
|
|
238
|
+
email
|
|
239
|
+
}
|
|
240
|
+
category {
|
|
241
|
+
categoryName
|
|
242
|
+
}
|
|
243
|
+
tags {
|
|
244
|
+
tagName
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
`
|
|
251
|
+
}
|
|
252
|
+
});
|
|
335
253
|
```
|
|
336
254
|
|
|
337
|
-
####
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
255
|
+
#### Using Variables and Fragments
|
|
256
|
+
```typescript
|
|
257
|
+
// Reusable fragments with variables
|
|
258
|
+
const response = await client.page.get('/about-us', {
|
|
259
|
+
graphql: {
|
|
260
|
+
content: {
|
|
261
|
+
blogPosts: `
|
|
262
|
+
BlogCollection(limit: $limit) {
|
|
263
|
+
...blogFragment
|
|
264
|
+
}
|
|
265
|
+
`
|
|
266
|
+
},
|
|
267
|
+
fragments: [
|
|
268
|
+
`fragment blogFragment on Blog {
|
|
269
|
+
title
|
|
270
|
+
urlTitle
|
|
271
|
+
blogContent {
|
|
272
|
+
json
|
|
273
|
+
}
|
|
274
|
+
}`
|
|
275
|
+
],
|
|
276
|
+
variables: { limit: 5 }
|
|
277
|
+
}
|
|
278
|
+
});
|
|
361
279
|
```
|
|
362
280
|
|
|
363
|
-
#### Filtering and Querying Content
|
|
364
281
|
|
|
365
|
-
|
|
282
|
+
## API Reference
|
|
366
283
|
|
|
367
|
-
|
|
368
|
-
const filtered = await client.content
|
|
369
|
-
.getCollection('Blog')
|
|
370
|
-
.query((qb) => qb.field('title').equals('dotCMS*'))
|
|
371
|
-
.limit(5)
|
|
372
|
-
.sortBy([{ field: 'publishDate', direction: 'desc' }]);
|
|
373
|
-
```
|
|
284
|
+
### Client Initialization
|
|
374
285
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
| QueryBuilder Method | Type | Result | Explanation |
|
|
378
|
-
|------------------------|-------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
379
|
-
| `.field('foo')` | Field | `foo:{bar}` | Defines a [field name](https://dev.dotcms.com/docs/field-properties#VariableNames) to query, awaiting a value to be supplied via the `.equals()` method. Multiple such assignments can be made if joined together via operator methods such as `or()`. |
|
|
380
|
-
| `.excludeField('foo')` | Field | `-foo:{bar}` | Defines a field name to exclude from the query, awaiting a value to be supplied via the `.equals()` method, or several combined through operators. |
|
|
381
|
-
| `.equals('bar')` | Assignment | `{foo:}bar` | Supplies a value to a preceding field method. Multiple `.equals()` calls may be joined through operator methods. |
|
|
382
|
-
| `.raw('foo')` | Raw | `foo` | Adds raw input as output to the query; requires use of Lucene syntax directly. |
|
|
383
|
-
| `.and()` | Operator | ` AND ` | Joins two query clauses — whether assignments or field/assignment pairs — such that results will be returned when both halves apply. |
|
|
384
|
-
| `.or()` | Operator | ` OR ` | Joins two query clauses such that results will be returned when at least one half applies. |
|
|
385
|
-
| `.not()` | Operator | ` NOT ` | Unary operator; query will return only results where the subsequent clause does not apply. |
|
|
386
|
-
| `.build()` | Constructor | *n/a* | Outputs query string. |
|
|
387
|
-
|
|
388
|
-
The following example displays all of the builder class's methods, generating a complex Lucene query:
|
|
389
|
-
|
|
390
|
-
```js
|
|
391
|
-
let queryBuilder = new QueryBuilder();
|
|
392
|
-
const myQuery = queryBuilder
|
|
393
|
-
.field('contentType')
|
|
394
|
-
.equals('Blog')
|
|
395
|
-
.or()
|
|
396
|
-
.equals('Activity')
|
|
397
|
-
.excludeField('conhost')
|
|
398
|
-
.equals('my-super-cool-site')
|
|
399
|
-
.field('languageId')
|
|
400
|
-
.equals('2') // spanish
|
|
401
|
-
.and()
|
|
402
|
-
.field('deleted')
|
|
403
|
-
.equals('false')
|
|
404
|
-
.raw('+summary:Snowboard')
|
|
405
|
-
.not()
|
|
406
|
-
.equals('Swiss Alps')
|
|
407
|
-
.build();
|
|
286
|
+
```typescript
|
|
287
|
+
createDotCMSClient(config: DotCMSClientConfig): DotCMSClient
|
|
408
288
|
```
|
|
409
289
|
|
|
410
|
-
|
|
411
|
-
> +contentType:Blog OR Activity -conhost:my-super-cool-site +languageId:2 AND +deleted:false +summary:Snowboard NOT "Swiss Alps"
|
|
412
|
-
|
|
413
|
-
For additional examples, see the [specification page](src/lib/client/content/builders/query/query.spec.ts), or the examples below.
|
|
290
|
+
#### Parameters
|
|
414
291
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
.sortBy([{ field: 'price', order: 'asc' }])
|
|
422
|
-
.limit(10)
|
|
423
|
-
.page(2);
|
|
292
|
+
| Option | Type | Required | Description |
|
|
293
|
+
| ---------------- | -------------- | -------- | ------------------------------------------------------------- |
|
|
294
|
+
| `dotcmsUrl` | string | ✅ | Your dotCMS instance URL |
|
|
295
|
+
| `authToken` | string | ✅ | Authentication token |
|
|
296
|
+
| `siteId` | string | ❌ | Site identifier (falls back to default site if not specified) |
|
|
297
|
+
| `requestOptions` | RequestOptions | ❌ | Additional fetch options |
|
|
424
298
|
|
|
425
|
-
|
|
299
|
+
#### Example
|
|
300
|
+
```typescript
|
|
301
|
+
const client = createDotCMSClient({
|
|
302
|
+
dotcmsUrl: 'https://your-dotcms-instance.com',
|
|
303
|
+
authToken: 'your-auth-token',
|
|
304
|
+
siteId: 'your-site-id'
|
|
305
|
+
});
|
|
426
306
|
```
|
|
427
307
|
|
|
428
|
-
|
|
308
|
+
### page.get() Method
|
|
429
309
|
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
.limit(5);
|
|
436
|
-
|
|
437
|
-
console.log(events);
|
|
310
|
+
```typescript
|
|
311
|
+
get<T extends DotCMSExtendedPageResponse = DotCMSPageResponse>(
|
|
312
|
+
url: string,
|
|
313
|
+
options?: DotCMSPageRequestParams
|
|
314
|
+
): Promise<DotCMSComposedPageResponse<T>>
|
|
438
315
|
```
|
|
439
316
|
|
|
440
|
-
####
|
|
317
|
+
#### Parameters
|
|
441
318
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
.sortBy([{ field: 'publishDate', order: 'desc' }])
|
|
447
|
-
.limit(10)
|
|
448
|
-
.page(1);
|
|
319
|
+
| Parameter | Type | Required | Description |
|
|
320
|
+
| --------- | ------------------------ | -------- | ------------------------------- |
|
|
321
|
+
| `url` | string | ✅ | Page URL path |
|
|
322
|
+
| `options` | DotCMSPageRequestParams | ❌ | Request customization options |
|
|
449
323
|
|
|
450
|
-
|
|
451
|
-
```
|
|
324
|
+
#### Options
|
|
452
325
|
|
|
453
|
-
|
|
326
|
+
| Option | Type | Description |
|
|
327
|
+
| ------------ | ------------------- | ---------------------------------------- |
|
|
328
|
+
| `languageId` | string \| number | Language version of the page |
|
|
329
|
+
| `mode` | string | Rendering mode: `LIVE`, `PREVIEW_MODE` |
|
|
330
|
+
| `personaId` | string | Personalize content based on persona ID |
|
|
331
|
+
| `graphql` | DotCMSGraphQLParams | GraphQL options for extending response |
|
|
332
|
+
| `fireRules` | boolean | Whether to trigger page rules |
|
|
454
333
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
| `query()` | `string` \| `BuildQuery` | Filter content using query builder or raw query |
|
|
460
|
-
| `limit()` | `number` | Set number of items to return |
|
|
461
|
-
| `page()` | `number` | Set which page of results to fetch |
|
|
462
|
-
| `sortBy()` | `SortBy[]` | Sort by one or more fields |
|
|
463
|
-
| `render()` | None | Enable server-side rendering of widgets |
|
|
464
|
-
| `draft()` | None | Retrieve draft content |
|
|
465
|
-
| `variant()` | `string` | Filter content by variant ID |
|
|
466
|
-
| `depth()` | `number` | Set depth of related content |
|
|
467
|
-
| `language()` | `number \| string` | Set content language |
|
|
468
|
-
| `then()` | `OnFullfilled<T>, OnRejected` | Handle promise fulfillment or rejection. Not needed if using async/await. |
|
|
334
|
+
#### Example
|
|
335
|
+
```typescript
|
|
336
|
+
const { pageAsset } = await client.page.get('/about-us');
|
|
337
|
+
```
|
|
469
338
|
|
|
470
|
-
|
|
339
|
+
### content.getCollection() Method
|
|
471
340
|
|
|
472
|
-
```
|
|
341
|
+
```typescript
|
|
473
342
|
getCollection<T = DotCMSBasicContentlet>(
|
|
474
343
|
contentType: string
|
|
475
|
-
): CollectionBuilder<T
|
|
344
|
+
): CollectionBuilder<T>
|
|
476
345
|
```
|
|
477
346
|
|
|
478
|
-
|
|
347
|
+
#### Parameters
|
|
479
348
|
|
|
480
|
-
|
|
349
|
+
| Parameter | Type | Required | Description |
|
|
350
|
+
| ------------- | ------ | -------- | ------------------------------ |
|
|
351
|
+
| `contentType` | string | ✅ | Content type variable name |
|
|
481
352
|
|
|
482
|
-
|
|
353
|
+
#### Builder Methods
|
|
483
354
|
|
|
484
|
-
|
|
355
|
+
| Method | Arguments | Description |
|
|
356
|
+
| ------------ | ----------------------------- | ---------------------------------------- |
|
|
357
|
+
| `query()` | `string` \| `BuildQuery` | Filter content using query builder |
|
|
358
|
+
| `limit()` | `number` | Set number of items to return |
|
|
359
|
+
| `page()` | `number` | Set which page of results to fetch |
|
|
360
|
+
| `sortBy()` | `SortBy[]` | Sort by one or more fields |
|
|
361
|
+
| `language()` | `number \| string` | Set content language |
|
|
362
|
+
| `depth()` | `number` | Set depth of related content |
|
|
485
363
|
|
|
364
|
+
#### Example
|
|
486
365
|
```typescript
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
// Define the page structure by extending the base DotCMSPageAsset
|
|
491
|
-
interface AboutUsPage extends DotCMSPageAsset {
|
|
492
|
-
vanityUrl: {
|
|
493
|
-
url: string;
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// Define interfaces for your content types
|
|
498
|
-
interface BlogPost extends DotCMSBasicContentlet {
|
|
499
|
-
title: string;
|
|
500
|
-
identifier: string;
|
|
501
|
-
urlTitle: string;
|
|
502
|
-
blogContent: {
|
|
503
|
-
json: string;
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
interface TeamMember {
|
|
508
|
-
name: string;
|
|
509
|
-
position: string;
|
|
510
|
-
bio?: string;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Define the content response structure
|
|
514
|
-
interface AboutUsContent {
|
|
515
|
-
blogPosts: BlogPost[];
|
|
516
|
-
teamMembers: TeamMember[];
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// Use the type parameters to get fully typed responses
|
|
520
|
-
const response = await client.page.get<{ pageAsset: AboutUsPage; content: AboutUsContent }>(
|
|
521
|
-
'/about-us',
|
|
522
|
-
{
|
|
523
|
-
languageId: '1',
|
|
524
|
-
fireRules: true,
|
|
525
|
-
graphql: {
|
|
526
|
-
page: `
|
|
527
|
-
title
|
|
528
|
-
pageId
|
|
529
|
-
vanityUrl {
|
|
530
|
-
url
|
|
531
|
-
}
|
|
532
|
-
`,
|
|
533
|
-
content: {
|
|
534
|
-
blogPosts: `
|
|
535
|
-
BlogCollection(limit: 3) {
|
|
536
|
-
title
|
|
537
|
-
identifier
|
|
538
|
-
...blogFragment
|
|
539
|
-
}
|
|
540
|
-
`,
|
|
541
|
-
teamMembers: `
|
|
542
|
-
TeamMemberCollection(limit: 5) {
|
|
543
|
-
name
|
|
544
|
-
position
|
|
545
|
-
bio
|
|
546
|
-
}
|
|
547
|
-
`
|
|
548
|
-
},
|
|
549
|
-
fragments: [
|
|
550
|
-
`
|
|
551
|
-
fragment blogFragment on Blog {
|
|
552
|
-
urlTitle
|
|
553
|
-
blogContent {
|
|
554
|
-
json
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
`
|
|
558
|
-
]
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
);
|
|
366
|
+
const blogs = await client.content.getCollection('Blog').limit(10).page(1);
|
|
367
|
+
```
|
|
562
368
|
|
|
563
|
-
|
|
369
|
+
### navigation.get() Method
|
|
564
370
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
371
|
+
```typescript
|
|
372
|
+
get(
|
|
373
|
+
uri: string,
|
|
374
|
+
options?: {
|
|
375
|
+
depth?: number;
|
|
376
|
+
languageId?: number;
|
|
377
|
+
}
|
|
378
|
+
): Promise<DotCMSNavigationItem[]>
|
|
569
379
|
```
|
|
570
380
|
|
|
571
|
-
|
|
381
|
+
#### Parameters
|
|
572
382
|
|
|
573
|
-
|
|
383
|
+
| Parameter | Type | Required | Description |
|
|
384
|
+
| --------- | ------ | -------- | ------------------------------- |
|
|
385
|
+
| `uri` | string | ✅ | Navigation root URI |
|
|
386
|
+
| `options` | object | ❌ | Navigation options |
|
|
574
387
|
|
|
575
|
-
|
|
576
|
-
import { DotCMSBasicContentlet } from '@dotcms/types';
|
|
388
|
+
#### Options
|
|
577
389
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
blogContent: {
|
|
583
|
-
json: string;
|
|
584
|
-
};
|
|
585
|
-
urlTitle: string;
|
|
586
|
-
tags: string[];
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
const response = await client.content.getCollection<BlogPost>('Blog');
|
|
390
|
+
| Option | Type | Description |
|
|
391
|
+
| ------------ | ------ | ------------------------------------------ |
|
|
392
|
+
| `depth` | number | Number of child levels to include |
|
|
393
|
+
| `languageId` | number | Language ID for localized navigation names |
|
|
590
394
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
console.log(post.tags.join(', '));
|
|
595
|
-
});
|
|
395
|
+
#### Example
|
|
396
|
+
```typescript
|
|
397
|
+
const nav = await client.navigation.get('/', { depth: 2 });
|
|
596
398
|
```
|
|
597
399
|
|
|
598
|
-
##
|
|
400
|
+
## Concepts & Architecture
|
|
599
401
|
|
|
600
|
-
|
|
402
|
+
### Key Concepts
|
|
601
403
|
|
|
602
|
-
|
|
404
|
+
| Term | Description | Documentation |
|
|
405
|
+
| ------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
406
|
+
| `pageAsset` | The page data structure containing layout and content | [Page API](https://dev.dotcms.com/docs/page-rest-api-layout-as-a-service-laas) |
|
|
407
|
+
| `contentlet` | A single piece of content in dotCMS | [Content API](https://dev.dotcms.com/docs/content) |
|
|
408
|
+
| `collection` | A group of contentlets of the same type | [Content API](https://dev.dotcms.com/docs/search) |
|
|
409
|
+
| `graphql` | Query language used to extend API responses | [GraphQL](https://dev.dotcms.com/docs/graphql) |
|
|
410
|
+
|
|
411
|
+
### Choosing the Right Method
|
|
412
|
+
|
|
413
|
+
The dotCMS Client SDK provides three core methods for fetching data. Use this quick guide to decide which one is best for your use case:
|
|
414
|
+
|
|
415
|
+
| Method | Use When You Need... | Best For |
|
|
416
|
+
| ------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
417
|
+
| `client.page.get()` | A full page with layout, containers, and related content | **Rendering entire pages** with a single request. Ideal for headless setups, SSR/SSG frameworks, and cases where you want everything—page structure, content, and navigation—tied to a URL path. |
|
|
418
|
+
| `client.content.getCollection()` | A filtered list of content items from a specific content type | Populating dynamic blocks, lists, search results, widgets, or reusable components. |
|
|
419
|
+
| `client.navigation.get()` | Only the site's navigation structure (folders and links) | Standalone menus or use cases where navigation is needed outside of page context. |
|
|
603
420
|
|
|
604
|
-
|
|
421
|
+
#### Start with `page.get()`: The One-Request Solution
|
|
605
422
|
|
|
606
|
-
|
|
423
|
+
For most use cases, `client.page.get()` is all you need. It lets you retrieve:
|
|
607
424
|
|
|
608
|
-
|
|
609
|
-
|
|
425
|
+
- The full page layout
|
|
426
|
+
- Related content
|
|
427
|
+
- Navigation structure
|
|
610
428
|
|
|
611
|
-
|
|
429
|
+
All in a single request using GraphQL.
|
|
612
430
|
|
|
613
|
-
|
|
614
|
-
* [Angular Example](https://github.com/dotCMS/core/tree/main/examples/angular)
|
|
615
|
-
* [Astro Example](https://github.com/dotCMS/core/tree/main/examples/astro)
|
|
431
|
+
Only use `content.getCollection()` or `navigation.get()` if you have advanced needs, like real-time data fetching or building custom dynamic components.
|
|
616
432
|
|
|
617
|
-
|
|
433
|
+
> 🔍 **For comprehensive examples of advanced GraphQL querying including relationships and custom fields,** see the [How to Work with GraphQL](#how-to-work-with-graphql) section.
|
|
618
434
|
|
|
619
|
-
|
|
620
|
-
* Render layouts and content containers
|
|
621
|
-
* Fetch page and content data using `@dotcms/client`
|
|
435
|
+
### Architecture Overview
|
|
622
436
|
|
|
623
|
-
|
|
437
|
+
The SDK follows a client-builder pattern with three main APIs:
|
|
624
438
|
|
|
625
|
-
|
|
439
|
+
- **Page API** (`client.page.get()`) - Fetches complete page content with layout and containers
|
|
440
|
+
- **Content API** (`client.content.getCollection()`) - Builder pattern for querying content collections
|
|
441
|
+
- **Navigation API** (`client.navigation.get()`) - Fetches site navigation structure
|
|
626
442
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
443
|
+
All APIs support:
|
|
444
|
+
- Type-safe responses with TypeScript
|
|
445
|
+
- GraphQL query extensions
|
|
446
|
+
- Localization and personalization
|
|
447
|
+
- Browser and Node.js compatibility
|
|
632
448
|
|
|
633
|
-
|
|
449
|
+
## Support & Contributing
|
|
634
450
|
|
|
635
|
-
|
|
451
|
+
### dotCMS Support
|
|
636
452
|
|
|
637
453
|
We offer multiple channels to get help with the dotCMS Client SDK:
|
|
638
454
|
|
|
@@ -649,7 +465,7 @@ When reporting issues, please include:
|
|
|
649
465
|
|
|
650
466
|
Enterprise customers can access premium support through the [dotCMS Support Portal](https://dev.dotcms.com/docs/help).
|
|
651
467
|
|
|
652
|
-
|
|
468
|
+
### How To Contribute
|
|
653
469
|
|
|
654
470
|
GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the DotCMS UVE SDK! If you'd like to contribute, please follow these steps:
|
|
655
471
|
|
|
@@ -661,7 +477,7 @@ GitHub pull requests are the preferred method to contribute code to dotCMS. We w
|
|
|
661
477
|
|
|
662
478
|
Please ensure your code follows the existing style and includes appropriate tests.
|
|
663
479
|
|
|
664
|
-
|
|
480
|
+
### Licensing Information
|
|
665
481
|
|
|
666
482
|
dotCMS comes in multiple editions and as such is dual-licensed. The dotCMS Community Edition is licensed under the GPL 3.0 and is freely available for download, customization, and deployment for use within organizations of all stripes. dotCMS Enterprise Editions (EE) adds several enterprise features and is available via a supported, indemnified commercial license from dotCMS. For the differences between the editions, see [the feature page](http://www.dotcms.com/cms-platform/features).
|
|
667
483
|
|