@dotcms/angular 0.0.1-beta.32 → 0.0.1-beta.34

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/README.md CHANGED
@@ -1,229 +1,689 @@
1
- # @dotcms/angular
1
+ # dotCMS Angular SDK
2
2
 
3
- `@dotcms/angular` is the official Angular library designed to work seamlessly with dotCMS. This library simplifies the process of rendering dotCMS pages and integrating with the [Universal Visual Editor](https://www.dotcms.com/docs/latest/universal-visual-editor) in your Angular applications.
3
+ The `@dotcms/angular` SDK is the DotCMS official Angular library. It empowers Angular developers to build powerful, editable websites and applications in no time.
4
4
 
5
5
  ## Table of Contents
6
6
 
7
- - [Features](#features)
8
- - [Installation](#installation)
9
- - [Configuration](#provider-setup)
10
- - [Provider Setup](#provider-setup)
11
- - [Client Usage](#client-usage)
12
- - [Components](#components)
13
- - [DotcmsLayoutComponent](#dotcmslayoutcomponent)
14
- - [Best Practices](#best-practices)
15
- - [Troubleshooting](#troubleshooting)
16
- - [Contributing](#contributing)
17
- - [Licensing](#licensing)
7
+ - [Prerequisites & Setup](#prerequisites--setup)
8
+ - [dotCMS Instance](#dotcms-instance)
9
+ - [Create a dotCMS API Key](#create-a-dotcms-api-key)
10
+ - [Configure The Universal Visual Editor App](#configure-the-universal-visual-editor-app)
11
+ - [Installation](#installation)
12
+ - [dotCMS Client Configuration](#dotcms-client-configuration)
13
+ - [Proxy Configuration for Static Assets](#proxy-configuration-for-static-assets)
14
+ - [Using dotCMS Images with Angular’s `NgOptimizedImage` Directive (Recommended)](#using-dotcms-images-with-angulars-ngoptimizedimage-directive-recommended)
15
+ - [Quickstart: Render a Page with dotCMS](#quickstart-render-a-page-with-dotcms)
16
+ - [Example Project](#example-project-)
17
+ - [SDK Reference](#sdk-reference)
18
+ - [DotCMSLayoutBody](#dotcmslayoutbody)
19
+ - [DotCMSEditableText](#dotcmseditabletext)
20
+ - [DotCMSBlockEditorRenderer](#dotcmsblockeditorrenderer)
21
+ - [DotCMSShowWhen](#dotcmsshowwhen)
22
+ - [DotCMSEditablePageService](#dotcmseditablepageservice)
23
+ - [Troubleshooting](#troubleshooting)
24
+ - [Common Issues & Solutions](#common-issues--solutions)
25
+ - [Debugging Tips](#debugging-tips)
26
+ - [Still Having Issues?](#still-having-issues)
27
+ - [dotCMS Support](#dotcms-support)
28
+ - [How To Contribute](#how-to-contribute)
29
+ - [Licensing Information](#licensing-information)
18
30
 
19
- ## Features
31
+ ## Prerequisites & Setup
20
32
 
21
- - A set of Angular components developed for dotCMS page rendering and editor integration.
22
- - Enhanced development workflow with full TypeScript support.
23
- - Optimized performance for efficient rendering of dotCMS pages in Angular applications.
24
- - Flexible customization options to adapt to various project requirements.
33
+ ### Get a dotCMS Environment
25
34
 
26
- ## Installation
35
+ #### Version Compatibility
27
36
 
28
- Install the package using npm:
37
+ - **Recommended**: dotCMS Evergreen
38
+ - **Minimum**: dotCMS v25.05
39
+ - **Best Experience**: Latest Evergreen release
29
40
 
30
- ```bash
31
- npm install @dotcms/angular
32
- ```
41
+ #### Environment Setup
33
42
 
34
- Or using Yarn:
43
+ **For Production Use:**
35
44
 
36
- ```bash
37
- yarn add @dotcms/angular
38
- ```
45
+ - ☁️ [Cloud hosting options](https://www.dotcms.com/pricing) - managed solutions with SLA
46
+ - 🛠️ [Self-hosted options](https://dev.dotcms.com/docs/current-releases) - deploy on your infrastructure
39
47
 
40
- ## Configuration
41
- ### Provider Setup
42
- We need to provide the information of our dotCMS instance
48
+ **For Testing & Development:**
43
49
 
44
- ```javascript
50
+ - 🧑🏻‍💻 [dotCMS demo site](https://demo.dotcms.com/dotAdmin/#/public/login) - perfect for trying out the SDK
51
+ - 📘 [Learn how to use the demo site](https://dev.dotcms.com/docs/demo-site)
52
+ - 📝 Read-only access, ideal for building proof-of-concepts
45
53
 
46
- import { ClientConfig } from '@dotcms/client';
54
+ **For Local Development:**
47
55
 
48
- const DOTCMS_CLIENT_CONFIG: ClientConfig = {
49
- dotcmsUrl: environment.dotcmsUrl,
50
- authToken: environment.authToken,
51
- siteId: environment.siteId
52
- };
56
+ - 🐳 [Docker setup guide](https://github.com/dotCMS/core/tree/main/docker/docker-compose-examples/single-node-demo-site)
57
+ - 💻 [Local installation guide](https://dev.dotcms.com/docs/quick-start-guide)
58
+
59
+ ### Configure The Universal Visual Editor App
60
+
61
+ For a step-by-step guide on setting up the Universal Visual Editor, check out our [easy-to-follow instructions](https://dev.dotcms.com/docs/uve-headless-config) and get started in no time!
62
+
63
+ ### Create a dotCMS API Key
64
+
65
+ > [!TIP]
66
+ > 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.
67
+
68
+ This integration requires an API Key with read-only permissions for security best practices:
69
+
70
+ 1. Go to the **dotCMS admin panel**.
71
+ 2. Click on **System** > **Users**.
72
+ 3. Select the user you want to create the API Key for.
73
+ 4. Go to **API Access Key** and generate a new key.
74
+
75
+ For detailed instructions, please refer to the [dotCMS API Documentation - Read-only token](https://dev.dotcms.com/docs/rest-api-authentication#ReadOnlyToken).
76
+
77
+ ### Installation
78
+
79
+ ```bash
80
+ npm install @dotcms/angular@next @dotcms/uve@next @dotcms/client@next @dotcms/types@next @tinymce/tinymce-angular
53
81
  ```
54
82
 
55
- Add this configuration to `ApplicationConfig` in your Angular app.
83
+ ### dotCMS Client Configuration
56
84
 
57
- `src/app/app.config.ts`
58
85
  ```typescript
86
+ import { createDotCMSClient } from '@dotcms/client';
59
87
  import { InjectionToken } from '@angular/core';
60
- import { ClientConfig, DotCmsClient } from '@dotcms/client';
61
88
 
62
- export const DOTCMS_CLIENT_TOKEN = new InjectionToken<DotCmsClient>('DOTCMS_CLIENT');
89
+ export type DotCMSClient = ReturnType<typeof createDotCMSClient>;
90
+
91
+ const dotCMSClient: DotCMSClient = createDotCMSClient({
92
+ dotcmsUrl: 'https://your-dotcms-instance.com',
93
+ authToken: 'your-auth-token', // Optional for public content
94
+ siteId: 'your-site-id' // Optional site identifier/name
95
+ });
96
+
97
+ export const DOTCMS_CLIENT_TOKEN = new InjectionToken<DotCMSClient>('DOTCMS_CLIENT');
63
98
 
64
99
  export const appConfig: ApplicationConfig = {
65
100
  providers: [
66
- provideRouter(routes),
67
101
  {
68
102
  provide: DOTCMS_CLIENT_TOKEN,
69
- useValue: DotCmsClient.init(DOTCMS_CLIENT_CONFIG),
103
+ useValue: dotCMSClient
70
104
  }
71
- ],
105
+ ]
72
106
  };
73
107
  ```
74
108
 
75
- This way, we will have access to `DOTCMS_CLIENT_TOKEN` from anywhere in our application.
109
+ This configuration makes the dotCMS client service available throughout your Angular application, allowing you to inject it wherever needed. For more details on how Angular's InjectionToken works, you can refer to the [Angular InjectionToken documentation](https://angular.dev/api/core/InjectionToken).
110
+
111
+ ### Proxy Configuration for Static Assets
112
+
113
+ Configure a proxy to leverage the powerful dotCMS image API, allowing you to resize and serve optimized images efficiently. This enhances application performance and improves user experience, making it a strategic enhancement for your project.
76
114
 
77
- ### Client Usage
78
- To interact with the client and obtain information from, for example, our pages
115
+ #### 1. Create a Proxy Configuration
116
+
117
+ Create a `proxy.conf.json` file in your project:
118
+
119
+ ```json
120
+ // proxy.conf.json
121
+ {
122
+ "/dA": {
123
+ "target": "http://localhost:8080", // Your dotCMS instance URL
124
+ "secure": false, // Set to true if using HTTPS
125
+ "changeOrigin": true // Required for hosting scenarios
126
+ }
127
+ }
128
+ ```
129
+
130
+ #### 2. Update Angular Configuration
131
+
132
+ Add the proxy configuration to your `angular.json`:
133
+
134
+ ```json
135
+ // angular.json
136
+ {
137
+ "projects": {
138
+ "my-app": {
139
+ "architect": {
140
+ "serve": {
141
+ "builder": "@angular-devkit/build-angular:dev-server",
142
+ "options": {
143
+ "proxyConfig": "src/proxy.conf.json"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ #### 3. Usage in Components
153
+
154
+ Once configured, image URLs in your components will automatically be proxied to your dotCMS instance:
155
+
156
+ >📚 Learn more about [Image Resizing and Processing in dotCMS with Angular](https://www.dotcms.com/blog/image-resizing-and-processing-in-dotcms-with-angular-and-nextjs).
79
157
 
80
158
  ```typescript
81
- export class YourComponent {
82
- private readonly client = inject(DOTCMS_CLIENT_TOKEN);
83
-
84
- this.client.page
85
- .get({ ...pageParams })
86
- .then((response) => {
87
- // Use your response
88
- })
89
- .catch((e) => {
90
- const error: PageError = {
91
- message: e.message,
92
- status: e.status,
93
- };
94
- // Use the error response
95
- })
159
+ // /components/my-dotcms-image.component.ts
160
+ @Component({
161
+ template: `
162
+ <img [src]="'/dA/' + contentlet.inode" alt="Asset from dotCMS" />
163
+ `
164
+ })
165
+ class MyDotCMSImageComponent {
166
+ @Input() contentlet: DotCMSBasicContentlet;
96
167
  }
97
168
  ```
98
169
 
99
- For more information on how to use the dotCMS Client, you can visit the [documentation](https://www.github.com/dotCMS/core/blob/main/core-web/libs/sdk/client/README.md)
170
+ ### Using dotCMS Images with Angular’s `NgOptimizedImage` Directive (Recommended)
171
+
172
+ To optimize images served from dotCMS in your Angular app, we recommend using the built-in `NgOptimizedImage` directive. This integration supports automatic image preloading, lazy loading, and improved performance.
173
+
174
+ We provide a helper function `provideDotCMSImageLoader()` to configure image loading with your dotCMS instance.
100
175
 
101
- ## DotCMS Page API
176
+ #### Setup
102
177
 
103
- The `DotcmsLayoutComponent` requires a `DotCMSPageAsset` object to be passed in to it. This object represents a dotCMS page and can be fetched using the `@dotcms/client` library.
178
+ Add the image loader to your `app.config.ts`:
104
179
 
105
- - [DotCMS Official Angular Example](https://www.github.com/dotCMS/core/tree/main/examples/angular)
106
- - [`@dotcms/client` documentation](https://www.npmjs.com/package/@dotcms/client)
107
- - [Page API documentation](https://www.dotcms.com/docs/latest/page-api)
180
+ ```ts
181
+ // src/app/app.config.ts
182
+ import { provideDotCMSImageLoader } from '@dotcms/angular';
183
+ import { ApplicationConfig } from '@angular/core';
108
184
 
109
- ## Components
185
+ export const appConfig: ApplicationConfig = {
186
+ providers: [
187
+ provideDotCMSImageLoader(environment.dotcmsUrl)
188
+ ]
189
+ };
190
+ ```
110
191
 
111
- ### DotcmsLayoutComponent
192
+ #### Usage
112
193
 
113
- The `DotcmsLayoutComponent` is a crucial component for rendering dotCMS page layouts in your Angular application.
194
+ Once configured, you can use the `NgOptimizedImage` directive to render dotCMS images:
114
195
 
115
- #### Inputs
196
+ ```ts
197
+ // src/components/my-dotcms-image.component.ts
198
+ @Component({
199
+ selector: 'my-dotcms-image',
200
+ template: `
201
+ <img [ngSrc]="imagePath" alt="Asset from dotCMS" />
202
+ `,
203
+ standalone: true
204
+ })
205
+ export class MyDotCMSImageComponent {
206
+ @Input() contentlet!: DotCMSBasicContentlet;
207
+
208
+ get imagePath() {
209
+ return this.contentlet.image.versionPath;
210
+ }
211
+ }
212
+ ```
116
213
 
117
- | Name | Type | Description |
118
- |--------------|----------------------|-----------------------------------------------------------------------|
119
- | `pageAsset` | `DotCMSPageAsset` | The object representing a dotCMS page from PageAPI response. |
120
- | `components` | `DotCMSPageComponent`| An object mapping contentlets to their respective render components. |
121
- | `editor` | `EditorConfig` | Configuration for data fetching in Edit Mode. |
214
+ > 📚 Learn more about [`NgOptimizedImage`](https://angular.dev/guide/image-optimization)
122
215
 
123
- #### Usage Example
216
+ ## Quickstart: Render a Page with dotCMS
124
217
 
125
- In your component file (e.g., `pages.component.ts`):
218
+ The following example demonstrates how to quickly set up a basic dotCMS page renderer in your Angular application. This example shows how to:
219
+
220
+ - Create a standalone component that renders a dotCMS page
221
+ - Set up dynamic component loading for different content types
222
+ - Handle both regular page viewing and editor mode
223
+ - Subscribe to real-time page updates when in the Universal Visual Editor
126
224
 
127
225
  ```typescript
226
+ // /src/app/pages/dotcms-page.component.ts
128
227
  import { Component, signal } from '@angular/core';
129
- import { DotCMSPageComponent, EditorConfig } from '@dotcms/angular';
228
+
229
+ import { DotCMSLayoutBody, DotCMSEditablePageService} from '@dotcms/angular/next';
230
+ import { getUVEState } from '@dotcms/uve';
231
+ import { DotCMSPageAsset } from '@dotcms/types';
232
+
233
+ import { DOTCMS_CLIENT_TOKEN } from './app.config';
234
+
235
+ const DYNAMIC_COMPONENTS = {
236
+ Blog: import('./blog.component').then(c => c.BlogComponent),
237
+ Product: import('./product.component').then(c => c.ProductComponent)
238
+ };
130
239
 
131
240
  @Component({
132
241
  selector: 'app-pages',
133
- templateUrl: './pages.component.html',
242
+ standalone: true,
243
+ imports: [DotCMSLayoutBody],
244
+ providers: [DotCMSEditablePageService, DOTCMS_CLIENT_TOKEN],
245
+ template: `
246
+ @if (pageAsset()) {
247
+ <dotcms-layout-body
248
+ [pageAsset]="pageAsset"
249
+ [components]="components()"
250
+ />
251
+ } @else {
252
+ <div>Loading...</div>
253
+ }
254
+ `
134
255
  })
135
256
  export class PagesComponent {
136
- DYNAMIC_COMPONENTS: DotCMSPageComponent = {
137
- Activity: import('../pages/content-types/activity/activity.component').then(
138
- (c) => c.ActivityComponent
139
- ),
140
- Banner: import('../pages/content-types/banner/banner.component').then(
141
- (c) => c.BannerComponent
142
- ),
143
- // Add other components as needed
144
- };
145
-
146
- components = signal(this.DYNAMIC_COMPONENTS);
147
- editorConfig = signal<EditorConfig>({ params: { depth: 2 } });
148
-
149
- // Assume pageAsset is fetched or provided somehow
150
- pageAsset: DotCMSPageAsset;
257
+ private readonly dotCMSClient: DotCMSClient = inject(DOTCMS_CLIENT_TOKEN);
258
+ private readonly editablePageService = inject(DotCMSEditablePageService);
259
+ readonly components = signal(DYNAMIC_COMPONENTS);
260
+ readonly pageAsset = signal<DotCMSPageAsset | null>(null);
261
+
262
+ ngOnInit() {
263
+ this.dotCMSClient.page
264
+ .get({ url: '/my-page' })
265
+ .then(({ pageAsset }) => {
266
+ if(getUVEState()) {
267
+ this.#subscribeToPageUpdates(response);
268
+ return;
269
+ }
270
+
271
+ this.pageAsset.set(pageAsset);
272
+ });
273
+ }
274
+
275
+ #subscribeToPageUpdates(response: DotCMSPageResponse) {
276
+ this.editablePageService
277
+ .listen(response)
278
+ .subscribe({ pageAsset } => this.pageAsset.set(pageAsset));
279
+ }
280
+ }
281
+ ```
282
+
283
+ ### Example Project 🚀
284
+
285
+ Looking to get started quickly? We've got you covered! Our [Angular starter project](https://github.com/dotCMS/core/tree/main/examples/angular) is the perfect launchpad for your dotCMS + Angular journey. This production-ready template demonstrates everything you need:
286
+
287
+ 📦 Fetch and render dotCMS pages with best practices
288
+ 🧩 Register and manage components for different content types
289
+ 🔍 Listing pages with search functionality
290
+ 📝 Detail pages for blogs
291
+ 📈 Image and assets optimization for better performance
292
+ ✨ Enable seamless editing via the Universal Visual Editor (UVE)
293
+ ⚡️ Leverage Angular's dependency injection and signals for optimal performance
294
+
295
+ > [!TIP]
296
+ > This starter project is more than just an example, it follows all our best practices. We highly recommend using it as the base for your next dotCMS + Angular project!
297
+
298
+ ## SDK Reference
299
+
300
+ All components, directives, and services should be imported from `@dotcms/angular/next`.
301
+
302
+ ### DotCMSLayoutBody
303
+
304
+ `DotCMSLayoutBody` is a component used to render the layout for a DotCMS page, supporting both production and development modes.
305
+
306
+ | Input | Type | Required | Default | Description |
307
+ |--------------|--------------------------|----------|----------------|------------------------------------------------|
308
+ | `page` | `DotCMSPageAsset` | ✅ | - | The page asset containing the layout to render |
309
+ | `components` | `DotCMSPageComponent` | ✅ | `{}` | [Map of content type → Angular component](#component-mapping) |
310
+ | `mode` | `DotCMSPageRendererMode` | ❌ | `'production'` | [Rendering mode ('production' or 'development')](#layout-body-modes) |
311
+
312
+ #### Usage
313
+
314
+ ```typescript
315
+ import { Component, signal } from '@angular/core';
316
+ import { DotCMSPageAsset } from '@dotcms/types';
317
+ import { DotCMSLayoutBody } from '@dotcms/angular/next';
318
+
319
+ import { DOTCMS_CLIENT_TOKEN } from './app.config';
320
+
321
+ @Component({
322
+ template: `
323
+ <dotcms-layout-body [page]="pageAsset()" [components]="components()" mode="development" />
324
+ `
325
+ })
326
+ export class MyPageComponent {
327
+ protected readonly components = signal({
328
+ Blog: import('./blog.component').then((c) => c.BlogComponent)
329
+ });
330
+ protected readonly pageAsset = signal<DotCMSPageAsset | null>(null);
331
+ private readonly dotCMSClient = inject(DOTCMS_CLIENT_TOKEN);
332
+
333
+ ngOnInit() {
334
+ this.dotCMSClient.page.get({ url: '/my-page' }).then(({ pageAsset }) => {
335
+ this.pageAsset.set(pageAsset);
336
+ });
337
+ }
338
+ }
339
+ ```
340
+
341
+ #### Layout Body Modes
342
+
343
+ - `production`: Performance-optimized mode that only renders content with explicitly mapped components, leaving unmapped content empty.
344
+ - `development`: Debug-friendly mode that renders default components for unmapped content types and provides visual indicators and console logs for empty containers and missing mappings.
345
+
346
+ #### Component Mapping
347
+
348
+ The `DotCMSLayoutBody` component uses a `components` input to map content type variable names to Angular components. This allows you to render different components for different content types. Example:
349
+
350
+ ```typescript
351
+ const DYNAMIC_COMPONENTS = {
352
+ Blog: import('./blog.component').then((c) => c.BlogComponent),
353
+ Product: import('./product.component').then((c) => c.ProductComponent)
354
+ };
355
+ ```
356
+
357
+ - Keys (e.g., `Blog`, `Product`): Match your [content type variable names](https://dev.dotcms.com/docs/content-types#VariableNames) in dotCMS
358
+ - Values: Dynamic imports of your Angular components that render each content type
359
+ - Supports lazy loading through dynamic imports
360
+ - Components must be standalone or declared in a module
361
+
362
+ > [!TIP]
363
+ > Always use the exact content type variable name from dotCMS as the key. You can find this in the Content Types section of your dotCMS admin panel.
364
+
365
+ ### DotCMSEditableText
366
+
367
+ `DotCMSEditableText` is a component for inline editing of text fields in dotCMS, supporting plain text, text area, and WYSIWYG fields.
368
+
369
+ | Input | Type | Required | Description |
370
+ |--------------|---------------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
371
+ | `contentlet` | `T extends DotCMSBasicContentlet` | ✅ | The contentlet containing the editable field |
372
+ | `fieldName` | `keyof T` | ✅ | Name of the field to edit, which must be a valid key of the contentlet type `T` |
373
+ | `mode` | `'plain' \| 'full'` | ❌ | `plain` (default): Support text editing. Does not show style controls. <br/> `full`: Enables a bubble menu with style options. This mode only works with [`WYSIWYG` fields](https://dev.dotcms.com/docs/the-wysiwyg-field). |
374
+ | `format` | `'text' \| 'html'` | ❌ | `text` (default): Renders HTML tags as plain text <br/> `html`: Interprets and renders HTML markup |
375
+
376
+ #### Usage
377
+
378
+ ```typescript
379
+ import { Component, Input } from '@angular/core';
380
+ import { RouterLink } from '@angular/router';
381
+
382
+ import { DotCMSBasicContentlet } from '@dotcms/types';
383
+ import { DotCMSEditableTextComponent } from '@dotcms/angular/next';
384
+
385
+ @Component({
386
+ selector: 'app-your-component',
387
+ imports: [RouterLink, NgOptimizedImage, DotCMSEditableTextComponent],
388
+ template: `
389
+ <div
390
+ class="flex overflow-hidden relative justify-center items-center w-full h-96 bg-gray-200">
391
+ <img
392
+ class="object-cover w-full"
393
+ [src]="'/dA/' + contentlet().inode"
394
+ [alt]="contentlet().title" />
395
+ <div
396
+ class="flex absolute inset-0 flex-col justify-center items-center p-4 text-center text-white">
397
+ <h2 class="mb-2 text-6xl font-bold text-shadow">
398
+ <dotcms-editable-text fieldName="title" [contentlet]="contentlet()" />
399
+ </h2>
400
+ <a
401
+ class="p-4 text-xl bg-red-400 rounded-sm transition duration-300 hover:bg-red-500"
402
+ [routerLink]="contentlet().link">
403
+ See more
404
+ </a>
405
+ </div>
406
+ </div>
407
+ `
408
+ })
409
+ export class MyBannerComponent {
410
+ @Input() contentlet: DotCMSBasicContentlet;
151
411
  }
152
412
  ```
153
413
 
154
- In your template file (e.g., `pages.component.html`):
414
+ #### Editor Integration
415
+
416
+ - Detects UVE edit mode and enables inline TinyMCE editing
417
+ - Triggers a `Save` [workflow action](https://dev.dotcms.com/docs/workflows) on blur without needing full content dialog.
418
+
419
+ ### DotCMSBlockEditorRenderer
420
+
421
+ `DotCMSBlockEditorRenderer` is a component for rendering [Block Editor](https://dev.dotcms.com/docs/block-editor) content from dotCMS with support for custom block renderers.
422
+
423
+ | Input | Type | Required | Description |
424
+ |-------------------|----------------------|----------|------------------------------------------------------------------------------------------------------------|
425
+ | `blocks` | `BlockEditorContent` | ✅ | The [Block Editor](https://dev.dotcms.com/docs/block-editor) content to render |
426
+ | `customRenderers` | `CustomRenderer` | ❌ | Custom rendering functions for specific [block types](https://dev.dotcms.com/docs/block-editor#BlockTypes) |
427
+ | `className` | `string` | ❌ | CSS class to apply to the container |
428
+ | `style` | `CSSProperties` | ❌ | Inline styles for the container |
155
429
 
156
- ```html
157
- <dotcms-layout
158
- [pageAsset]="pageAsset"
159
- [components]="components()"
160
- [editor]="editorConfig()"
161
- />
430
+ #### Usage
431
+
432
+ ```typescript
433
+ import { DotCMSBasicContentlet } from '@dotcms/types';
434
+ import { DotCMSBlockEditorRenderer } from '@dotcms/angular/next';
435
+
436
+ const CUSTOM_RENDERERS = {
437
+ customBlock: import('./custom-block.component').then((c) => c.CustomBlockComponent),
438
+ h1: import('./custom-h1.component').then((c) => c.CustomH1Component)
439
+ };
440
+
441
+ @Component({
442
+ selector: 'app-your-component',
443
+ imports: [DotCMSShowWhen],
444
+ template: `
445
+ <dotcms-block-editor-renderer
446
+ [blocks]="contentlet.myBlockEditorField"
447
+ [customRenderers]="customRenderers()" />
448
+ `
449
+ })
450
+ export class MyBannerComponent {
451
+ @Input() contentlet: DotCMSBasicContentlet;
452
+ readonly customRenderers = signal(CUSTOM_RENDERERS);
453
+ }
162
454
  ```
163
455
 
164
- This setup allows for dynamic rendering of different content types on your dotCMS pages.
456
+ #### Recommendations
457
+
458
+ - Should not be used with [`DotCMSEditableText`](#dotcmseditabletext)
459
+ - Take into account the CSS cascade can affect the look and feel of your blocks.
460
+ - `DotCMSBlockEditorRenderer` only works with [Block Editor fields](https://dev.dotcms.com/docs/block-editor). For other fields, use [`DotCMSEditableText`](#dotcmseditabletext).
461
+
462
+ 📘 For advanced examples, customization options, and best practices, refer to the [DotCMSBlockEditorRenderer README](https://github.com/dotCMS/core/tree/master/core-web/libs/sdk/angular/src/lib/components/DotCMSBlockEditorRenderer).
165
463
 
166
- ## Best Practices
167
464
 
168
- 1. **Lazy Loading**: Use dynamic imports for components to improve initial load times.
169
- 2. **Error Handling**: Implement robust error handling for API calls and component rendering.
170
- 3. **Type Safety**: Leverage TypeScript's type system to ensure proper usage of dotCMS structures.
171
- 4. **Performance Optimization**: Monitor and optimize the performance of rendered components.
465
+ ### DotCMSShowWhen
466
+
467
+ `DotCMSShowWhen` is a `directive` for conditionally showing content based on the current UVE mode. Useful for mode-based behaviors outside of render logic.
468
+
469
+ | Input | Type | Required | Description |
470
+ |--------|------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
471
+ | `when` | `UVE_MODE` | ✅ | The `UVE` mode when content should be displayed: <br/> `UVE_MODE.EDIT`: Only visible in edit mode <br/> `UVE_MODE.PREVIEW`: Only visible in preview mode <br/> `UVE_MODE.PUBLISHED`: Only visible in published mode |
472
+
473
+ #### Usage
474
+
475
+ ```typescript
476
+ import { UVE_MODE } from '@dotcms/types';
477
+ import { DotCMSShowWhen } from '@dotcms/angular/next';
478
+
479
+ @Component({
480
+ selector: 'app-your-component',
481
+ imports: [DotCMSShowWhen],
482
+ template: `
483
+ <div *dotCMSShowWhen="UVE_MODE.EDIT">Only visible in edit mode</div>
484
+ `
485
+ })
486
+ export class YourComponent {}
487
+ ```
488
+
489
+ 📚 Learn more about the `UVE_MODE` enum in the [dotCMS UVE Package Documentation](https://dev.dotcms.com/docs/uve).
490
+
491
+ ### DotCMSEditablePageService
492
+
493
+ The `DotCMSEditablePageService` enables real-time page updates when using the Universal Visual Editor. It provides a single method `listen` that returns an Observable of page changes.
494
+
495
+ | Param | Type | Required | Description |
496
+ |----------------|----------------------|----------|-----------------------------------------------|
497
+ | `pageResponse` | `DotCMSPageResponse` | ✅ | The page data object from `client.page.get()` |
498
+
499
+ #### Service Lifecycle & Operations
500
+
501
+ When you use the `listen` method, the service:
502
+
503
+ 1. Initializes the UVE with your page data
504
+ 2. Sets up communication channels with the editor
505
+ 3. Tracks content changes in real-time
506
+ 4. Updates your page automatically when:
507
+ - Content is edited inline
508
+ - Blocks are added or removed
509
+ - Layout changes are made
510
+ - Components are moved
511
+ 5. Cleans up all listeners and connections on destroy
512
+
513
+ #### Usage
514
+
515
+ ```typescript
516
+ import { Subscription } from 'rxjs';
517
+ import { Component, OnDestroy, OnInit, signal, inject } from '@angular/core';
518
+
519
+ import { getUVEState } from '@dotcms/uve';
520
+ import { DotCMSPageAsset } from '@dotcms/types';
521
+ import { DotCMSLayoutBody, DotCMSEditablePageService } from '@dotcms/angular/next';
522
+ import { DOTCMS_CLIENT_TOKEN } from './app.config';
523
+
524
+ @Component({
525
+ imports: [DotCMSLayoutBody],
526
+ providers: [DotCMSEditablePageService],
527
+ template: `
528
+ @if (pageAsset()) {
529
+ <dotcms-layout-body [page]="pageAsset()" [components]="components()" />
530
+ } @else {
531
+ <div>Loading...</div>
532
+ }
533
+ `
534
+ })
535
+ export class PageComponent implements OnInit, OnDestroy {
536
+ private subscription?: Subscription;
537
+ private readonly dotCMSClient = inject(DOTCMS_CLIENT_TOKEN);
538
+ private readonly editablePageService = inject(DotCMSEditablePageService);
539
+ readonly pageAsset = signal<DotCMSPageAsset | null>(null);
540
+
541
+ ngOnInit() {
542
+ this.dotCMSClient.page.get({ url: '/about-us' }).then((pageResponse) => {
543
+ // Only subscribe to changes when in the editor
544
+ if (getUVEState()) {
545
+ this.subscription = this.editablePageService
546
+ .listen(pageResponse)
547
+ .subscribe(({ pageAsset }) => {
548
+ this.pageAsset.set(pageAsset);
549
+ });
550
+ } else {
551
+ const { pageAsset } = pageResponse;
552
+ this.pageAsset.set(pageAsset);
553
+ }
554
+ });
555
+ }
556
+
557
+ ngOnDestroy() {
558
+ this.subscription?.unsubscribe();
559
+ }
560
+ }
561
+ ```
172
562
 
173
563
  ## Troubleshooting
174
564
 
175
- If you encounter issues while using `@dotcms/angular`, here are some common problems and their solutions:
176
-
177
- 1. **Dependency Issues**:
178
- - Ensure that all dependencies, such as `@dotcms/client`, `@angular/core`, and `rxjs`, are correctly installed and up-to-date. You can verify installed versions by running:
179
- ```bash
180
- npm list @dotcms/client @angular/core rxjs
181
- ```
182
- - If there are any missing or incompatible versions, reinstall dependencies by running:
183
- ```bash
184
- npm install
185
- ```
186
- or
187
- ```bash
188
- npm install --force
189
- ```
190
-
191
- 2. **Configuration Errors**:
192
- - **DotCMS Configuration**: Double-check that your `DOTCMS_CLIENT_CONFIG` settings (URL, auth token, site ID) are correct and aligned with the environment variables. For example:
193
- ```typescript
194
- const DOTCMS_CLIENT_CONFIG: ClientConfig = {
195
- dotcmsUrl: environment.dotcmsUrl, // Ensure this is a valid URL
196
- authToken: environment.authToken, // Ensure auth token has the correct permissions
197
- siteId: environment.siteId // Ensure site ID is valid and accessible
198
- };
199
- ```
200
- - **Injection Issues**: Ensure that `DOTCMS_CLIENT_TOKEN` is provided globally. Errors like `NullInjectorError` usually mean the token hasn’t been properly added to the `ApplicationConfig`. Verify by checking `src/app/app.config.ts`.
201
-
202
- 3. **Network and API Errors**:
203
- - **dotCMS API Connectivity**: If API calls are failing, check your browser’s Network tab to ensure requests to `dotcmsUrl` are successful. For CORS-related issues, ensure that your dotCMS server allows requests from your application’s domain.
204
- - **Auth Token Permissions**: If you’re seeing `401 Unauthorized` errors, make sure the auth token used in `DOTCMS_CLIENT_CONFIG` has appropriate permissions in dotCMS for accessing pages and content.
205
-
206
- 4. **Page and Component Rendering**:
207
- - **Dynamic Imports**: If you’re encountering issues with lazy-loaded components, make sure dynamic imports are correctly set up, as in:
208
- ```typescript
209
- const DYNAMIC_COMPONENTS: DotCMSPageComponent = {
210
- Activity: import('../pages/content-types/activity/activity.component').then(
211
- (c) => c.ActivityComponent
212
- )
213
- };
214
- ```
215
- - **Invalid Page Assets**: Ensure that `pageAsset` objects are correctly formatted. Missing fields in `pageAsset` can cause errors in `DotcmsLayoutComponent`. Validate the structure by logging `pageAsset` before passing it in.
216
-
217
- 5. **Common Angular Errors**:
218
- - **Change Detection**: Angular sometimes fails to detect changes with dynamic content. If `DotcmsLayoutComponent` isn’t updating as expected, you may need to call `ChangeDetectorRef.detectChanges()` manually.
219
- - **TypeScript Type Errors**: Ensure all types (e.g., `DotCMSPageAsset`, `DotCMSPageComponent`) are imported correctly from `@dotcms/angular`. Type mismatches can often be resolved by verifying imports.
220
-
221
- 6. **Consult Documentation**: Refer to the official [dotCMS documentation](https://dotcms.com/docs/) and the [@dotcms/angular GitHub repository](https://github.com/dotCMS/core). These sources often provide updates and additional usage examples.
222
-
223
- ## Contributing
224
-
225
- GitHub pull requests are the preferred method to contribute code to dotCMS. Before any pull requests can be accepted, an automated tool will ask you to agree to the [dotCMS Contributor's Agreement](https://www.gist.github.com/wezell/85ef45298c48494b90d92755b583acb3).
226
-
227
- ## Licensing
228
-
229
- 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 a number of 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).
565
+ ### Common Issues & Solutions
566
+
567
+ #### Universal Visual Editor (UVE)
568
+
569
+ 1. **UVE Not Loading**: Page loads but UVE controls are not visible
570
+ - **Possible Causes**:
571
+ - Incorrect UVE configuration
572
+ - Missing API token permissions
573
+ - Missing the `DotCMSEditablePageService` call to enable UVE.
574
+ - **Solutions**:
575
+ - Verify UVE app configuration in dotCMS admin
576
+ - Check API token has edit permissions
577
+ - Ensure `dotcmsUrl` matches your instance URL exactly
578
+
579
+ #### Missing Content
580
+
581
+ 1. **Components Not Rendering**: Empty spaces where content should appear
582
+
583
+ - **Possible Causes**:
584
+ - Missing component mappings
585
+ - Incorrect content type variable names
586
+ - **Solutions**:
587
+ - Check component registration in `components` prop
588
+ - Verify content type variable names match exactly
589
+ - Enable `development` mode for detailed logging
590
+
591
+ 2. **Asset Loading Issues**: Images or files not loading
592
+ - **Possible Causes**:
593
+ - Proxy configuration issues
594
+ - CORS restrictions
595
+ - **Solutions**:
596
+ - Verify proxy settings in `angular.json`
597
+ - Check network tab for CORS errors
598
+ - Ensure `/dA` path is properly configured
599
+
600
+ #### Development Setup
601
+
602
+ 1. **Build Errors**: `npm install` fails
603
+
604
+ - **Solutions**:
605
+ - Clear npm cache: `npm cache clean --force`
606
+ - Delete `node_modules` and reinstall
607
+ - Verify Node.js version compatibility
608
+
609
+ 2. **Runtime Errors**: Console errors about missing imports or components not rendering
610
+ - **Solutions**:
611
+ - Check all imports are from `@dotcms/angular/next`
612
+ - Verify all peer dependencies are installed
613
+ - Update to latest compatible versions
614
+
615
+ ### Debugging Tips
616
+
617
+ 1. **Enable Development Mode**
618
+
619
+ ```typescript
620
+ <dotcms-layout-body
621
+ [page]="pageAsset()"
622
+ [components]="components()"
623
+ mode="development"
624
+ />
625
+ ```
626
+
627
+ This will:
628
+
629
+ - Show detailed error messages
630
+ - Highlight unmapped components
631
+ - Log component lifecycle events
632
+
633
+ 2. **Check Browser Console**
634
+
635
+ - Check for errors in the browser console
636
+ - Check for errors in the browser network tab
637
+
638
+ 3. **Network Monitoring**
639
+ - Use browser dev tools to monitor API calls
640
+ - Check for 401/403 errors (auth issues)
641
+ - Verify asset loading paths
642
+
643
+ ### Still Having Issues?
644
+
645
+ If you're still experiencing problems after trying these solutions:
646
+
647
+ 1. Search existing [GitHub issues](https://github.com/dotCMS/core/issues)
648
+ 2. Ask questions on the [community forum](https://community.dotcms.com/) to engage with other users.
649
+ 3. Create a new issue with:
650
+ - Detailed reproduction steps
651
+ - Environment information
652
+ - Error messages
653
+ - Code samples
654
+
655
+ ## dotCMS Support
656
+
657
+ We offer multiple channels to get help with the dotCMS Angular SDK:
658
+
659
+ - **GitHub Issues**: For bug reports and feature requests, please [open an issue](https://github.com/dotCMS/core/issues/new/choose) in the GitHub repository.
660
+ - **Community Forum**: Join our [community discussions](https://community.dotcms.com/) to ask questions and share solutions.
661
+ - **Stack Overflow**: Use the tag `dotcms-angular` when posting questions.
662
+ - **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://helpdesk.dotcms.com/support/).
663
+
664
+ When reporting issues, please include:
665
+
666
+ - SDK version you're using
667
+ - Angular version
668
+ - Minimal reproduction steps
669
+ - Expected vs. actual behavior
670
+
671
+ ## How To Contribute
672
+
673
+ 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:
674
+
675
+ 1. Fork the repository [dotCMS/core](https://github.com/dotCMS/core)
676
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
677
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
678
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
679
+ 5. Open a Pull Request
680
+
681
+ Please ensure your code follows the existing style and includes appropriate tests.
682
+
683
+ ## Licensing Information
684
+
685
+ 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).
686
+
687
+ This SDK is part of dotCMS's dual-licensed platform (GPL 3.0 for Community, commercial license for Enterprise).
688
+
689
+ [Learn more ](https://www.dotcms.com)at [dotcms.com](https://www.dotcms.com).