@dotcms/react 1.5.5-next.2180 → 1.5.5-next.2253

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
@@ -6,8 +6,8 @@ The `@dotcms/react` SDK is the DotCMS official React library. It empowers React
6
6
 
7
7
  - [Prerequisites & Setup](#prerequisites--setup)
8
8
  - [Get a dotCMS Environment](#get-a-dotcms-environment)
9
- - [Create a dotCMS API Key](#create-a-dotcms-api-key)
10
9
  - [Configure The Universal Visual Editor App](#configure-the-universal-visual-editor-app)
10
+ - [Create a dotCMS API Key](#create-a-dotcms-api-key)
11
11
  - [Installation](#installation)
12
12
  - [dotCMS Client Configuration](#dotcms-client-configuration)
13
13
  - [Proxy Configuration for Static Assets](#proxy-configuration-for-static-assets)
@@ -15,16 +15,15 @@ The `@dotcms/react` SDK is the DotCMS official React library. It empowers React
15
15
  - [Example Project](#example-project-)
16
16
  - [SDK Reference](#sdk-reference)
17
17
  - [DotCMSLayoutBody](#dotcmslayoutbody)
18
- - [DotCMSShow](#dotcmsshow)
19
- - [DotCMSBlockEditorRenderer](#dotcmsblockeditorrenderer)
20
18
  - [DotCMSEditableText](#dotcmseditabletext)
19
+ - [DotCMSBlockEditorRenderer](#dotcmsblockeditorrenderer)
20
+ - [DotCMSShow](#dotcmsshow)
21
21
  - [useEditableDotCMSPage](#useeditabledotcmspage)
22
22
  - [useDotCMSShowWhen](#usedotcmsshowwhen)
23
23
  - [useAISearch](#useaisearch)
24
24
  - [Troubleshooting](#troubleshooting)
25
25
  - [Common Issues & Solutions](#common-issues--solutions)
26
26
  - [Debugging Tips](#debugging-tips)
27
- - [Version Compatibility](#version-compatibility)
28
27
  - [Still Having Issues?](#still-having-issues)
29
28
  - [Migration from Alpha to 1.0.X](./MIGRATION.md)
30
29
  - [Support](#support)
@@ -77,7 +76,7 @@ This integration requires an API Key with read-only permissions for security bes
77
76
 
78
77
  For detailed instructions, please refer to the [dotCMS API Documentation - Read-only token](https://dev.dotcms.com/docs/rest-api-authentication#ReadOnlyToken).
79
78
 
80
- ### Install Dependencies
79
+ ### Installation
81
80
 
82
81
  ```bash
83
82
  npm install @dotcms/react@latest
@@ -132,7 +131,7 @@ Learn more about Vite configuration [here](https://vitejs.dev/config/).
132
131
 
133
132
  Once configured, image URLs in your components will automatically be proxied to your dotCMS instance:
134
133
 
135
- >📚 Learn more about [Image Resizing and Processing in dotCMS with React](https://www.dotcms.com/blog/image-resizing-and-processing-in-dotcms-with-angular-and-nextjs).
134
+ >📚 Learn more about [Image Resizing and Processing in dotCMS with Angular and Next.js](https://www.dotcms.com/blog/image-resizing-and-processing-in-dotcms-with-angular-and-nextjs).
136
135
 
137
136
  ```typescript
138
137
  // /components/my-dotcms-image.tsx
@@ -210,7 +209,7 @@ All components and hooks should be imported from `@dotcms/react`:
210
209
  | ------------ | ------------------------ | -------- | -------------- | ---------------------------------------------- |
211
210
  | `page` | `DotCMSPageAsset` | ✅ | - | The page asset containing the layout to render |
212
211
  | `components` | `DotCMSPageComponent` | ✅ | `{}` | [Map of content type → React component](#component-mapping) |
213
- | `mode` | `DotCMSPageRendererMode` | ❌ | `’production’` | [Rendering mode (production or development)](#layout-body-modes) |
212
+ | `mode` | `DotCMSPageRendererMode` | ❌ | `'production'` | [Rendering mode ('production' or 'development')](#layout-body-modes) |
214
213
  | `slots` | `Record<string, ReactNode>` | ❌ | `{}` | Pre-rendered server component nodes keyed by contentlet identifier. See [`buildSlots`](#buildslots). |
215
214
 
216
215
  #### Next.js App Router
@@ -227,7 +226,7 @@ export default async function Page() {
227
226
 
228
227
  ```tsx
229
228
  // PageView.tsx — "use client", owns components and renders layout
230
- use client’;
229
+ 'use client';
231
230
 
232
231
  export function PageView({ pageContent }) {
233
232
  const { pageAsset } = useEditableDotCMSPage(pageContent);
@@ -238,11 +237,11 @@ export function PageView({ pageContent }) {
238
237
  #### Usage
239
238
 
240
239
  ```tsx
241
- import type { DotCMSPageAsset } from ‘@dotcms/types’;
242
- import { DotCMSLayoutBody } from ‘@dotcms/react’;
240
+ import type { DotCMSPageResponse } from '@dotcms/types';
241
+ import { DotCMSLayoutBody } from '@dotcms/react';
243
242
 
244
- import { MyBlogCard } from ‘./MyBlogCard’;
245
- import { DotCMSProductComponent } from ‘./DotCMSProductComponent’;
243
+ import { MyBlogCard } from './MyBlogCard';
244
+ import { DotCMSProductComponent } from './DotCMSProductComponent';
246
245
 
247
246
  const COMPONENTS_MAP = {
248
247
  Blog: MyBlogCard,
@@ -256,10 +255,10 @@ const MyPage = ({ pageAsset }: DotCMSPageResponse) => {
256
255
 
257
256
  #### buildSlots
258
257
 
259
- Use `buildSlots` when you have Next.js async server components that need to fetch their own data. Since async server components cant be called from inside a client component tree, pre-render them on the server and pass the result into the layout via `slots`:
258
+ Use `buildSlots` when you have Next.js async server components that need to fetch their own data. Since async server components can't be called from inside a client component tree, pre-render them on the server and pass the result into the layout via `slots`:
260
259
 
261
260
  ```tsx
262
- import { buildSlots, DotCMSLayoutBody } from ‘@dotcms/react’;
261
+ import { buildSlots, DotCMSLayoutBody } from '@dotcms/react';
263
262
 
264
263
  // BlogListContainer is an async server component that fetches its own data
265
264
  const slots = buildSlots(pageContent.pageAsset.containers, {
@@ -304,7 +303,7 @@ const DYNAMIC_COMPONENTS = {
304
303
  | ------------ | ------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
305
304
  | `contentlet` | `T extends DotCMSBasicContentlet` | ✅ | The contentlet containing the editable field |
306
305
  | `fieldName` | `keyof T` | ✅ | Name of the field to edit, which must be a valid key of the contentlet type `T` |
307
- | `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). |
306
+ | `mode` | `'plain' \| 'full'` | ❌ | `plain` (default): Supports 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). |
308
307
  | `format` | `'text' \| 'html'` | ❌ | `text` (default): Renders HTML tags as plain text <br/> `html`: Interprets and renders HTML markup |
309
308
 
310
309
  #### Usage
@@ -341,7 +340,7 @@ export default MyBannerComponent;
341
340
  - Detects UVE edit mode and enables inline TinyMCE editing
342
341
  - Triggers a `Save` [workflow action](https://dev.dotcms.com/docs/workflows) on blur without needing full content dialog.
343
342
 
344
- #### DotCMSBlockEditorRenderer
343
+ ### DotCMSBlockEditorRenderer
345
344
 
346
345
  `DotCMSBlockEditorRenderer` is a component for rendering [Block Editor](https://dev.dotcms.com/docs/block-editor) content from dotCMS with support for custom block renderers.
347
346
 
@@ -404,9 +403,9 @@ export default async function ArticlePage() {
404
403
  - Take into account the CSS cascade can affect the look and feel of your blocks.
405
404
  - `DotCMSBlockEditorRenderer` only works with [Block Editor fields](https://dev.dotcms.com/docs/block-editor). For other fields, use [`DotCMSEditableText`](#dotcmseditabletext).
406
405
 
407
- 📘 For advanced examples, customization options, and best practices, refer to the [DotCMSBlockEditorRenderer README](https://github.com/dotCMS/core/tree/master/core-web/libs/sdk/react/src/lib/components/DotCMSBlockEditorRenderer).
406
+ 📘 For advanced examples, customization options, and best practices, refer to the [DotCMSBlockEditorRenderer README](https://github.com/dotCMS/core/tree/main/core-web/libs/sdk/react/src/lib/next/components/DotCMSBlockEditorRenderer).
408
407
 
409
- #### DotCMSShow
408
+ ### DotCMSShow
410
409
 
411
410
  `DotCMSShow` is a component for conditionally rendering content based on the current UVE mode. Useful for mode-based behaviors outside of render logic.
412
411
 
@@ -430,7 +429,7 @@ const MyComponent = () => {
430
429
  };
431
430
  ```
432
431
 
433
- 📚 Learn more about the `UVE_MODE` enum in the [dotCMS UVE Package Documentation](https://dev.dotcms.com/docs/uve).
432
+ 📚 Learn more about the `UVE_MODE` enum in the [dotCMS UVE Package Documentation](https://dev.dotcms.com/docs/universal-visual-editor).
434
433
 
435
434
  ### useEditableDotCMSPage
436
435
 
@@ -469,11 +468,11 @@ const COMPONENTS_MAP = {
469
468
 
470
469
  export function DotCMSPage({ pageResponse }: { pageResponse: DotCMSPageResponse }) {
471
470
  const { pageAsset } = useEditableDotCMSPage(pageResponse);
472
- return <DotCMSLayoutBody pageAsset={pageAsset} components={COMPONENTS_MAP} />;
471
+ return <DotCMSLayoutBody page={pageAsset} components={COMPONENTS_MAP} />;
473
472
  }
474
473
  ```
475
474
 
476
- #### useDotCMSShowWhen
475
+ ### useDotCMSShowWhen
477
476
 
478
477
  `useDotCMSShowWhen` is a hook for conditionally showing content based on the current UVE mode. Useful for mode-based behaviors outside of render logic.
479
478
 
@@ -643,7 +642,7 @@ export default AISearchComponent;
643
642
  - **Possible Causes**:
644
643
  - Incorrect UVE configuration
645
644
  - Missing API token permissions
646
- - Missing the `DotCMSEditablePageService` call to enable UVE.
645
+ - Missing the `useEditableDotCMSPage` hook to enable UVE.
647
646
  - **Solutions**:
648
647
  - Verify UVE app configuration in dotCMS admin
649
648
  - Check API token has edit permissions
@@ -722,7 +721,7 @@ export default AISearchComponent;
722
721
 
723
722
  export function DotCMSPage({ pageResponse }: { pageResponse: DotCMSPageResponse }) {
724
723
  const { pageAsset } = useEditableDotCMSPage(pageResponse);
725
- return <DotCMSLayoutBody pageAsset={pageAsset} components={COMPONENTS_MAP} />;
724
+ return <DotCMSLayoutBody page={pageAsset} components={COMPONENTS_MAP} />;
726
725
  }
727
726
  ```
728
727
 
@@ -733,10 +732,10 @@ export default AISearchComponent;
733
732
 
734
733
  1. **Enable Development Mode**
735
734
 
736
- ```typescript
737
- <dotcms-layout-body
738
- [page]="pageAsset()"
739
- [components]="components()"
735
+ ```tsx
736
+ <DotCMSLayoutBody
737
+ page={pageAsset}
738
+ components={COMPONENTS_MAP}
740
739
  mode="development"
741
740
  />
742
741
  ```
@@ -776,7 +775,7 @@ We offer multiple channels to get help with the dotCMS React SDK:
776
775
  - **GitHub Issues**: For bug reports and feature requests, please [open an issue](https://github.com/dotCMS/core/issues/new/choose) in the GitHub repository.
777
776
  - **Community Forum**: Join our [community discussions](https://community.dotcms.com/) to ask questions and share solutions.
778
777
  - **Stack Overflow**: Use the tag `dotcms-react` when posting questions.
779
- - **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://helpdesk.dotcms.com/support/).
778
+ - **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://www.dotcms.com/support).
780
779
 
781
780
  When reporting issues, please include:
782
781
 
@@ -4,6 +4,7 @@ import { useContext, useMemo } from 'react';
4
4
  import { getContainersData, getContentletsInContainer, getDotContainerAttributes } from '@dotcms/uve/internal';
5
5
  import { ContainerNotFound, EmptyContainer } from './ContainerFallbacks.esm.js';
6
6
  import { DotCMSPageContext } from '../../contexts/DotCMSPageContext.esm.js';
7
+ import { useIsDevMode } from '../../hooks/useIsDevMode.esm.js';
7
8
  import { Contentlet } from '../Contentlet/Contentlet.esm.js';
8
9
 
9
10
  /**
@@ -31,6 +32,7 @@ function Container({
31
32
  const {
32
33
  pageAsset
33
34
  } = useContext(DotCMSPageContext);
35
+ const isDevMode = useIsDevMode();
34
36
  const containerData = useMemo(() => getContainersData(pageAsset, container), [pageAsset, container]);
35
37
  const contentlets = useMemo(() => getContentletsInContainer(pageAsset, container), [pageAsset, container]);
36
38
  if (!containerData) {
@@ -39,7 +41,8 @@ function Container({
39
41
  });
40
42
  }
41
43
  const isEmpty = contentlets.length === 0;
42
- const dotAttributes = getDotContainerAttributes(containerData);
44
+ // Container metadata is editor-only — strip it from live output.
45
+ const dotAttributes = isDevMode ? getDotContainerAttributes(containerData) : {};
43
46
  if (isEmpty) {
44
47
  return jsx(EmptyContainer, Object.assign({}, dotAttributes));
45
48
  }
@@ -39,7 +39,7 @@ const ContainerNotFound = ({
39
39
  *
40
40
  * Component to display when a container is empty.
41
41
  *
42
- * @param {DotContainerAttributes} dotAttributes
42
+ * @param {Partial<DotContainerAttributes>} dotAttributes
43
43
  * @return {*}
44
44
  */
45
45
  const EmptyContainer = dotAttributes => {
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { jsx, Fragment } from 'react/jsx-runtime';
3
3
  import { useRef, useMemo, useContext } from 'react';
4
- import { getDotContentletAttributes, CUSTOM_NO_COMPONENT } from '@dotcms/uve/internal';
4
+ import { getDotContentletAttributes, getAnalyticsContentletAttributes, CUSTOM_NO_COMPONENT } from '@dotcms/uve/internal';
5
5
  import { DotCMSPageContext } from '../../contexts/DotCMSPageContext.esm.js';
6
6
  import { useCheckVisibleContent } from '../../hooks/useCheckVisibleContent.esm.js';
7
+ import { useIsAnalyticsActive } from '../../hooks/useIsAnalyticsActive.esm.js';
7
8
  import { useIsDevMode } from '../../hooks/useIsDevMode.esm.js';
8
9
  import { FallbackComponent } from '../FallbackComponent/FallbackComponent.esm.js';
9
10
 
@@ -34,14 +35,26 @@ function Contentlet({
34
35
  }) {
35
36
  const ref = useRef(null);
36
37
  const isDevMode = useIsDevMode();
38
+ const isAnalyticsActive = useIsAnalyticsActive();
37
39
  const haveContent = useCheckVisibleContent(ref);
38
40
  const style = useMemo(() => isDevMode ? {
39
41
  minHeight: haveContent ? undefined : '4rem'
40
42
  } : {}, [isDevMode, haveContent]);
41
- // UVE attributes - always applied
42
- const dotAttributes = useMemo(() => getDotContentletAttributes(contentlet, container), [contentlet, container]);
43
+ // In edit mode we emit the full set of editor metadata. In live mode we
44
+ // strip it to avoid leaking internal identifiers, keeping only the minimal
45
+ // set Analytics needs (and only while Analytics is active).
46
+ const dotAttributes = useMemo(() => {
47
+ if (isDevMode) {
48
+ return Object.assign({}, getDotContentletAttributes(contentlet, container), {
49
+ 'data-dot-object': 'contentlet'
50
+ });
51
+ }
52
+ if (isAnalyticsActive) {
53
+ return getAnalyticsContentletAttributes(contentlet);
54
+ }
55
+ return {};
56
+ }, [isDevMode, isAnalyticsActive, contentlet, container]);
43
57
  return jsx("div", Object.assign({}, dotAttributes, {
44
- "data-dot-object": "contentlet",
45
58
  className: CONTENTLET_CLASS,
46
59
  ref: ref,
47
60
  style: style,
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { useState, useEffect } from 'react';
3
+ import { ANALYTICS_READY_EVENT, isDotAnalyticsActive } from '@dotcms/uve/internal';
4
+
5
+ /**
6
+ * @internal
7
+ * A React hook that determines whether DotCMS Analytics is active on the page.
8
+ *
9
+ * It reads the analytics active flag on mount and subscribes to the
10
+ * `dotcms:analytics:ready` event so contentlets re-render with the attributes
11
+ * Analytics needs, regardless of initialization order.
12
+ *
13
+ * @returns {boolean} - `true` when analytics is active; otherwise, `false`.
14
+ */
15
+ const useIsAnalyticsActive = () => {
16
+ const [isAnalyticsActive, setIsAnalyticsActive] = useState(false);
17
+ useEffect(() => {
18
+ const updateState = () => setIsAnalyticsActive(isDotAnalyticsActive());
19
+ updateState();
20
+ window.addEventListener(ANALYTICS_READY_EVENT, updateState);
21
+ return () => window.removeEventListener(ANALYTICS_READY_EVENT, updateState);
22
+ }, []);
23
+ return isAnalyticsActive;
24
+ };
25
+
26
+ export { useIsAnalyticsActive };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/react",
3
- "version": "1.5.5-next.2180",
3
+ "version": "1.5.5-next.2253",
4
4
  "peerDependencies": {
5
5
  "react": ">=18",
6
6
  "react-dom": ">=18"
@@ -18,7 +18,7 @@ export declare const ContainerNotFound: ({ identifier }: {
18
18
  *
19
19
  * Component to display when a container is empty.
20
20
  *
21
- * @param {DotContainerAttributes} dotAttributes
21
+ * @param {Partial<DotContainerAttributes>} dotAttributes
22
22
  * @return {*}
23
23
  */
24
- export declare const EmptyContainer: (dotAttributes: DotContainerAttributes) => import("react/jsx-runtime").JSX.Element | null;
24
+ export declare const EmptyContainer: (dotAttributes: Partial<DotContainerAttributes>) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @internal
3
+ * A React hook that determines whether DotCMS Analytics is active on the page.
4
+ *
5
+ * It reads the analytics active flag on mount and subscribes to the
6
+ * `dotcms:analytics:ready` event so contentlets re-render with the attributes
7
+ * Analytics needs, regardless of initialization order.
8
+ *
9
+ * @returns {boolean} - `true` when analytics is active; otherwise, `false`.
10
+ */
11
+ export declare const useIsAnalyticsActive: () => boolean;