@dotcms/react
Version:
Official React Components library to render a dotCMS page.
807 lines (601 loc) • 34.5 kB
Markdown
# dotCMS React SDK
The `@dotcms/react` SDK is the DotCMS official React library. It empowers React developers to build powerful, editable websites and applications in no time.
## Table of Contents
- [Prerequisites & Setup](#prerequisites--setup)
- [Get a dotCMS Environment](#get-a-dotcms-environment)
- [Create a dotCMS API Key](#create-a-dotcms-api-key)
- [Configure The Universal Visual Editor App](#configure-the-universal-visual-editor-app)
- [Installation](#installation)
- [dotCMS Client Configuration](#dotcms-client-configuration)
- [Proxy Configuration for Static Assets](#proxy-configuration-for-static-assets)
- [Quickstart: Render a Page with dotCMS](#quickstart-render-a-page-with-dotcms)
- [Example Project](#example-project-)
- [SDK Reference](#sdk-reference)
- [DotCMSLayoutBody](#dotcmslayoutbody)
- [DotCMSShow](#dotcmsshow)
- [DotCMSBlockEditorRenderer](#dotcmsblockeditorrenderer)
- [DotCMSEditableText](#dotcmseditabletext)
- [useEditableDotCMSPage](#useeditabledotcmspage)
- [useDotCMSShowWhen](#usedotcmsshowwhen)
- [useAISearch](#useaisearch)
- [Troubleshooting](#troubleshooting)
- [Common Issues & Solutions](#common-issues--solutions)
- [Debugging Tips](#debugging-tips)
- [Version Compatibility](#version-compatibility)
- [Still Having Issues?](#still-having-issues)
- [Migration from Alpha to 1.0.X](./MIGRATION.md)
- [Support](#support)
- [Contributing](#contributing)
- [Licensing](#licensing)
## Prerequisites & Setup
### Get a dotCMS Environment
#### Version Compatibility
- **Recommended**: dotCMS Evergreen
- **Minimum**: dotCMS v25.05
- **Best Experience**: Latest Evergreen release
#### Environment Setup
**For Production Use:**
- ☁️ [Cloud hosting options](https://www.dotcms.com/pricing) - managed solutions with SLA
- 🛠️ [Self-hosted options](https://dev.dotcms.com/docs/current-releases) - deploy on your infrastructure
**For Testing & Development:**
- 🧑🏻💻 [dotCMS demo site](https://demo.dotcms.com/dotAdmin/#/public/login) - perfect for trying out the SDK
- 📘 [Learn how to use the demo site](https://dev.dotcms.com/docs/demo-site)
- 📝 Read-only access, ideal for building proof-of-concepts
**For Local Development:**
- 🐳 [Docker setup guide](https://github.com/dotCMS/core/tree/main/docker/docker-compose-examples/single-node-demo-site)
- 💻 [Local installation guide](https://dev.dotcms.com/docs/quick-start-guide)
### Configure The Universal Visual Editor App
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!
### Create a dotCMS API Key
> [!TIP]
> 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.
This integration requires an API Key with read-only permissions for security best practices:
1. Go to the **dotCMS admin panel**.
2. Click on **System** > **Users**.
3. Select the user you want to create the API Key for.
4. Go to **API Access Key** and generate a new key.
For detailed instructions, please refer to the [dotCMS API Documentation - Read-only token](https://dev.dotcms.com/docs/rest-api-authentication#ReadOnlyToken).
### Install Dependencies
```bash
npm install @dotcms/react@latest
```
This will automatically install the required dependencies:
- `@dotcms/uve`: Enables interaction with the [Universal Visual Editor](https://dev.dotcms.com/docs/uve-headless-config) for real-time content editing
- `@dotcms/client`: Provides the core client functionality for fetching and managing dotCMS data
### dotCMS Client Configuration
```typescript
import { createDotCMSClient } from '@dotcms/client';
type DotCMSClient = ReturnType<typeof createDotCMSClient>;
export const dotCMSClient: DotCMSClient = createDotCMSClient({
dotcmsUrl: 'https://your-dotcms-instance.com',
authToken: 'your-auth-token', // Optional for public content
siteId: 'your-site-id' // Optional site identifier/name
});
```
### Proxy Configuration for Static Assets
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.
#### 1. Configure Vite
```ts
// vite.config.ts
import { defineConfig } from 'vite';
import dns from 'node:dns';
dns.setDefaultResultOrder('verbatim');
export default defineConfig({
server: {
proxy: {
'/dA': {
target: 'your-dotcms-instance.com',
changeOrigin: true
}
}
}
});
```
Learn more about Vite configuration [here](https://vitejs.dev/config/).
#### 2. Usage in Components
Once configured, image URLs in your components will automatically be proxied to your dotCMS instance:
>📚 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).
```typescript
// /components/my-dotcms-image.tsx
import type { DotCMSBasicContentlet } from '@dotcms/types';
export const MyDotCMSImageComponent = ({ inode, title }: DotCMSBasicContentlet) => {
return <img src={`/dA/${inode}`} alt={title} />;
}
```
## Quickstart: Render a Page with dotCMS
The following example demonstrates how to quickly set up a basic dotCMS page renderer in your React application. This example shows how to:
- Create a standalone component that renders a dotCMS page
- Set up dynamic component loading for different content types
- Handle both regular page viewing and editor mode
- Subscribe to real-time page updates when in the Universal Visual Editor
```tsx
// /src/app/pages/dotcms-page.tsx
import { useState, useEffect } from 'react';
import { DotCMSLayoutBody, useEditableDotCMSPage } from '@dotcms/react';
import { DotCMSPageResponse } from '@dotcms/types';
import { dotCMSClient } from './dotCMSClient';
import { BlogComponent } from './BlogComponent';
import { ProductComponent } from './ProductComponent';
const COMPONENTS_MAP = {
Blog: BlogComponent,
Product: ProductComponent
};
const MyPage = () => {
const [response, setResponse] = useState<DotCMSPageResponse | null>(null);
const { pageAsset } = useEditableDotCMSPage(response);
useEffect(() => {
dotCMSClient.page.get('/').then((response) => {
setResponse(response);
});
}, []);
return <DotCMSLayoutBody page={pageAsset} components={COMPONENTS_MAP} mode="development" />;
};
export default MyPage;
```
### Example Project 🚀
Looking to get started quickly? We've got you covered! Our [Next.js starter project](https://github.com/dotCMS/core/tree/main/examples/nextjs) is the perfect launchpad for your dotCMS + Next.js journey. This production-ready template demonstrates everything you need:
📦 Fetch and render dotCMS pages with best practices
🧩 Register and manage components for different content types
🔍 Listing pages with search functionality
📝 Detail pages for blogs
📈 Image and assets optimization for better performance
✨ Enable seamless editing via the Universal Visual Editor (UVE)
⚡️ Leverage React's hooks and state management for optimal performance
> [!TIP]
> 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 + Next.js project!
## SDK Reference
All components and hooks should be imported from `@dotcms/react`:
### DotCMSLayoutBody
`DotCMSLayoutBody` is a component used to render the layout for a DotCMS page, supporting both production and development modes.
| Input | Type | Required | Default | Description |
| ------------ | ------------------------ | -------- | -------------- | ---------------------------------------------- |
| `page` | `DotCMSPageAsset` | ✅ | - | The page asset containing the layout to render |
| `components` | `DotCMSPageComponent` | ✅ | `{}` | [Map of content type → React component](#component-mapping) |
| `mode` | `DotCMSPageRendererMode` | ❌ | `’production’` | [Rendering mode (‘production’ or ‘development’)](#layout-body-modes) |
| `slots` | `Record<string, ReactNode>` | ❌ | `{}` | Pre-rendered server component nodes keyed by contentlet identifier. See [`buildSlots`](#buildslots). |
#### Next.js App Router
`DotCMSLayoutBody` requires a `"use client"` parent because `components` is a map of React component functions, which React cannot serialize across the server→client boundary. The recommended pattern is to fetch data in the server page and pass the plain result to a client wrapper:
```tsx
// page.tsx — server component, fetches data only
export default async function Page() {
const pageContent = await getDotCMSPage(path);
return <PageView pageContent={pageContent} />;
}
```
```tsx
// PageView.tsx — "use client", owns components and renders layout
‘use client’;
export function PageView({ pageContent }) {
const { pageAsset } = useEditableDotCMSPage(pageContent);
return <DotCMSLayoutBody page={pageAsset} components={pageComponents} />;
}
```
#### Usage
```tsx
import type { DotCMSPageAsset } from ‘@dotcms/types’;
import { DotCMSLayoutBody } from ‘@dotcms/react’;
import { MyBlogCard } from ‘./MyBlogCard’;
import { DotCMSProductComponent } from ‘./DotCMSProductComponent’;
const COMPONENTS_MAP = {
Blog: MyBlogCard,
Product: DotCMSProductComponent
};
const MyPage = ({ pageAsset }: DotCMSPageResponse) => {
return <DotCMSLayoutBody page={pageAsset} components={COMPONENTS_MAP} />;
};
```
#### buildSlots
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`:
```tsx
import { buildSlots, DotCMSLayoutBody } from ‘@dotcms/react’;
// BlogListContainer is an async server component that fetches its own data
const slots = buildSlots(pageContent.pageAsset.containers, {
BlogList: BlogListContainer,
});
<DotCMSLayoutBody page={pageAsset} components={pageComponents} slots={slots} />
```
The layout renders the pre-rendered slot node for a contentlet if one exists, otherwise falls back to the matching entry in `components`.
#### Layout Body Modes
- `production`: Performance-optimized mode that only renders content with explicitly mapped components, leaving unmapped content empty.
- `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.
#### Component Mapping
The `DotCMSLayoutBody` component uses a `components` prop to map content type variable names to React components. This allows you to render different components for different content types. Example:
```typescript
const DYNAMIC_COMPONENTS = {
Blog: MyBlogCard,
Product: DotCMSProductComponent
};
```
- Keys (e.g., `Blog`, `Product`): Match your [content type variable names](https://dev.dotcms.com/docs/content-types#VariableNames) in dotCMS
- Values: Dynamic imports of your React components that render each content type
- Supports lazy loading through dynamic imports
- Components must be standalone or declared in a module
> [!TIP]
> 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.
### DotCMSEditableText
`DotCMSEditableText` is a component for inline editing of text fields in dotCMS, supporting plain text, text area, and WYSIWYG fields.
| Input | Type | Required | Description |
| ------------ | ------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `contentlet` | `T extends DotCMSBasicContentlet` | ✅ | The contentlet containing the editable field |
| `fieldName` | `keyof T` | ✅ | Name of the field to edit, which must be a valid key of the contentlet type `T` |
| `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). |
| `format` | `'text' \| 'html'` | ❌ | `text` (default): Renders HTML tags as plain text <br/> `html`: Interprets and renders HTML markup |
#### Usage
```tsx
import type { DotCMSBasicContentlet } from '@dotcms/types';
import { DotCMSEditableText } from '@dotcms/react';
const MyBannerComponent = ({ contentlet }: { contentlet: DotCMSBasicContentlet }) => {
const { inode, title, link } = contentlet;
return (
<div className="flex overflow-hidden relative justify-center items-center w-full h-96 bg-gray-200">
<img className="object-cover w-full" src={`/dA/${inode}`} alt={title} />
<div className="flex absolute inset-0 flex-col justify-center items-center p-4 text-center text-white">
<h2 className="mb-2 text-6xl font-bold text-shadow">
<DotCMSEditableText fieldName="title" contentlet={contentlet} />
</h2>
<a
href={link}
className="p-4 text-xl bg-red-400 rounded-sm transition duration-300 hover:bg-red-500">
See more
</a>
</div>
</div>
);
};
export default MyBannerComponent;
```
#### Editor Integration
- Detects UVE edit mode and enables inline TinyMCE editing
- Triggers a `Save` [workflow action](https://dev.dotcms.com/docs/workflows) on blur without needing full content dialog.
#### DotCMSBlockEditorRenderer
`DotCMSBlockEditorRenderer` is a component for rendering [Block Editor](https://dev.dotcms.com/docs/block-editor) content from dotCMS with support for custom block renderers.
| Input | Type | Required | Default | Description |
| ----------------- | -------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `blocks` | `BlockEditorContent` | ✅ | - | The [Block Editor](https://dev.dotcms.com/docs/block-editor) content to render |
| `customRenderers` | `CustomRenderers` | ❌ | - | Custom rendering functions for specific [block types](https://dev.dotcms.com/docs/block-editor#BlockTypes) |
| `className` | `string` | ❌ | - | CSS class to apply to the container |
| `style` | `CSSProperties` | ❌ | - | Inline styles for the container |
| `isDevMode` | `boolean` | ❌ | `false` | When `true`, shows a visible error message if the `blocks` data is invalid. When `false` (default), invalid blocks render nothing silently. |
#### Usage
```tsx
import type { DotCMSBasicContentlet } from '@dotcms/types';
import { DotCMSBlockEditorRenderer } from '@dotcms/react';
import { MyCustomBannerBlock } from './MyCustomBannerBlock';
import { MyCustomH1 } from './MyCustomH1';
const CUSTOM_RENDERERS = {
customBannerBlock: MyCustomBannerBlock,
h1: MyCustomH1
};
const DetailPage = ({ contentlet }: { contentlet: DotCMSBasicContentlet }) => {
return (
<DotCMSBlockEditorRenderer
blocks={contentlet['YOUR_BLOCK_EDITOR_FIELD']}
customRenderers={CUSTOM_RENDERERS}
/>
);
};
```
#### Next.js Server Components
`DotCMSBlockEditorRenderer` can be used directly in a Next.js server component — it has no hooks or browser dependencies:
```tsx
// app/article/page.tsx — server component
import { DotCMSBlockEditorRenderer } from '@dotcms/react';
export default async function ArticlePage() {
const { pageAsset } = await getDotCMSPage('/article');
const blocks = pageAsset.containers['...'].contentlets[0].blockEditorContent;
return (
<DotCMSBlockEditorRenderer
blocks={blocks}
isDevMode={process.env.NODE_ENV === 'development'}
/>
);
}
```
#### Recommendations
- Should not be used with [`DotCMSEditableText`](#dotcmseditabletext)
- Take into account the CSS cascade can affect the look and feel of your blocks.
- `DotCMSBlockEditorRenderer` only works with [Block Editor fields](https://dev.dotcms.com/docs/block-editor). For other fields, use [`DotCMSEditableText`](#dotcmseditabletext).
📘 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).
#### DotCMSShow
`DotCMSShow` is a component for conditionally rendering content based on the current UVE mode. Useful for mode-based behaviors outside of render logic.
| Input | Type | Required | Description |
| ---------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | ✅ | Content to be conditionally rendered |
| `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 |
#### Usage
```tsx
import { UVE_MODE } from '@dotcms/types';
import { DotCMSShow } from '@dotcms/react';
const MyComponent = () => {
return (
<DotCMSShow when={UVE_MODE.EDIT}>
<div>This will only render in UVE EDIT mode</div>
</DotCMSShow>
);
};
```
📚 Learn more about the `UVE_MODE` enum in the [dotCMS UVE Package Documentation](https://dev.dotcms.com/docs/uve).
### useEditableDotCMSPage
`useEditableDotCMSPage` is a hook that enables real-time page updates when using the Universal Visual Editor.
| Param | Type | Required | Description |
| -------------- | -------------------- | -------- | --------------------------------------------- |
| `pageResponse` | `DotCMSPageResponse` | ✅ | The page data object from `client.page.get()` |
#### Service Lifecycle & Operations
When you use the hook, it:
1. Initializes the UVE with your page data
2. Sets up communication channels with the editor
3. Tracks content changes in real-time
4. Updates your page automatically when:
- Content is edited inline
- Blocks are added or removed
- Layout changes are made
- Components are moved
5. Cleans up all listeners and connections on destroy
#### Usage
```tsx
'use client';
import { useEditableDotCMSPage, DotCMSLayoutBody } from '@dotcms/react';
import type { DotCMSPageResponse } from '@dotcms/types';
const COMPONENTS_MAP = {
Blog: BlogComponent,
Product: ProductComponent
};
export function DotCMSPage({ pageResponse }: { pageResponse: DotCMSPageResponse }) {
const { pageAsset } = useEditableDotCMSPage(pageResponse);
return <DotCMSLayoutBody pageAsset={pageAsset} components={COMPONENTS_MAP} />;
}
```
#### useDotCMSShowWhen
`useDotCMSShowWhen` is a hook for conditionally showing content based on the current UVE mode. Useful for mode-based behaviors outside of render logic.
| Param | Type | Required | Description |
| ------ | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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 |
#### Usage
```tsx
import { UVE_MODE } from '@dotcms/types';
import { useDotCMSShowWhen } from '@dotcms/react';
const MyEditButton = () => {
const isEditMode = useDotCMSShowWhen(UVE_MODE.EDIT); // returns a boolean
if (isEditMode) {
return <button>Edit</button>;
}
return null;
};
```
### useAISearch
`useAISearch` is a hook that enables AI-powered semantic search capabilities for your dotCMS content. It manages search state, handles API calls, and provides real-time status updates.
| Param | Type | Required | Description |
| ----------- | ----------------------- | -------- | ------------------------------------------------------------------------------ |
| `client` | `DotCMSClient` | ✅ | The dotCMS client instance created with `createDotCMSClient()` |
| `indexName` | `string` | ✅ | Name of the AI search index to query |
| `params` | `DotCMSAISearchParams` | ✅ | Search configuration including query params (limit, offset) and AI config |
#### Return Value
The hook returns an object with the following properties:
| Property | Type | Description |
| ---------- | ---------------------------------------- | -------------------------------------------------------------- |
| `response` | `DotCMSAISearchResponse<T> \| null` | Full search response including metadata and results |
| `results` | `DotCMSAISearchContentletData<T>[] \| undefined` | Array of search results with match scores |
| `status` | `DotCMSEntityStatus` | Current state: `IDLE`, `LOADING`, `SUCCESS`, or `ERROR` |
| `search` | `(prompt: string) => Promise<void>` | Function to execute a search with a text prompt |
| `reset` | `() => void` | Function to reset search state to idle |
#### Usage
```tsx
'use client';
import { useState } from 'react';
import { useAISearch } from '@dotcms/react';
import type { DotCMSBasicContentlet } from '@dotcms/types';
import { dotCMSClient } from '@/lib/dotCMSClient';
interface BlogPost extends DotCMSBasicContentlet {
body: string;
author: string;
}
const AISearchComponent = () => {
const [searchQuery, setSearchQuery] = useState('');
const { results, status, search, reset } = useAISearch<BlogPost>({
client: dotCMSClient,
indexName: 'blog-search-index',
params: {
query: {
limit: 10,
offset: 0,
contentType: 'Blog'
},
config: {
threshold: 0.5,
responseLength: 1024
}
}
});
const handleSearch = async () => {
if (searchQuery.trim()) {
await search(searchQuery);
}
};
const handleReset = () => {
setSearchQuery('');
reset();
};
return (
<div className="search-container">
<div className="search-bar">
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search with AI..."
/>
<button onClick={handleSearch} disabled={status.state === 'LOADING'}>
{status.state === 'LOADING' ? 'Searching...' : 'Search'}
</button>
<button onClick={handleReset}>Reset</button>
</div>
{status.state === 'ERROR' && (
<div className="error">
Error: {status.error.message}
</div>
)}
{status.state === 'SUCCESS' && results && (
<div className="results">
<h2>Found {results.length} results</h2>
{results.map((result) => (
<article key={result.identifier}>
<h3>{result.title}</h3>
<p>Author: {result.author}</p>
{result.matches?.map((match, idx) => (
<div key={idx} className="match">
<span>Relevance: {match.distance.toFixed(2)}</span>
<p>{match.extractedText}</p>
</div>
))}
</article>
))}
</div>
)}
</div>
);
};
export default AISearchComponent;
```
#### Features
- **Automatic State Management**: Handles loading, success, error, and idle states
- **Type-Safe Results**: Generic typing ensures type safety for your content types
- **Search Validation**: Automatically validates and trims search prompts
- **Configurable Parameters**: Support for pagination, thresholds, and AI configuration
- **Error Handling**: Provides detailed error information through status state
- **Reset Capability**: Easy state reset for clearing search results
#### Configuration Options
**Query Parameters (`params.query`):**
- `limit`: Maximum number of results (default: 1000)
- `offset`: Number of results to skip (default: 0)
- `siteId`: Filter by specific site
- `contentType`: Filter by content type
- `languageId`: Filter by language
**AI Configuration (`params.config`):**
- `threshold`: Minimum similarity score (default: 0.5)
- `distanceFunction`: Vector distance algorithm (default: cosine)
- `responseLength`: Maximum response text length (default: 1024)
## Troubleshooting
### Common Issues & Solutions
#### Universal Visual Editor (UVE)
1. **UVE Not Loading**: Page loads but UVE controls are not visible
- **Possible Causes**:
- Incorrect UVE configuration
- Missing API token permissions
- Missing the `DotCMSEditablePageService` call to enable UVE.
- **Solutions**:
- Verify UVE app configuration in dotCMS admin
- Check API token has edit permissions
- Ensure `dotcmsUrl` matches your instance URL exactly
#### Missing Content
1. **Components Not Rendering**: Empty spaces where content should appear
- **Possible Causes**:
- Missing component mappings
- Incorrect content type variable names
- **Solutions**:
- Check component registration in `components` prop
- Verify content type variable names match exactly
- Enable `development` mode for detailed logging
2. **Asset Loading Issues**: Images or files not loading
- **Possible Causes**:
- Proxy configuration issues
- CORS restrictions
- **Solutions**:
- Verify proxy settings in `vite.config.ts`
- Check network tab for CORS errors
- Ensure `/dA` path is properly configured
#### Development Setup
1. **Build Errors**: `npm install` fails
- **Solutions**:
- Clear npm cache: `npm cache clean --force`
- Delete `node_modules` and reinstall
- Verify Node.js version compatibility
2. **Runtime Errors**: Console errors about missing imports or components not rendering
- **Solutions**:
- Check all imports are from `@dotcms/react`
- Verify all peer dependencies are installed
- Update to latest compatible versions
#### Next.js App Router Integration
1. **Server Component Errors**: Errors about React class components in Server Components
- **Possible Causes**:
- Using dotCMS components directly in Server Components
- Missing 'use client' directive
- Incorrect data fetching pattern
- **Solutions**:
1. Split your code into Server and Client Components:
```tsx
// app/page.tsx (Server Component)
import { DotCMSPage } from '@/components/DotCMSPage';
import { dotCMSClient } from '@/lib/dotCMSClient';
export default async function Page() {
const pageResponse = await dotCMSClient.page.get('/index');
return <DotCMSPage pageResponse={pageResponse} />;
}
```
```tsx
// components/DotCMSPage.tsx (Client Component)
'use client';
import { useEditableDotCMSPage, DotCMSLayoutBody } from '@dotcms/react';
import type { DotCMSPageResponse } from '@dotcms/types';
const COMPONENTS_MAP = {
Blog: BlogComponent,
Product: ProductComponent
};
export function DotCMSPage({ pageResponse }: { pageResponse: DotCMSPageResponse }) {
const { pageAsset } = useEditableDotCMSPage(pageResponse);
return <DotCMSLayoutBody pageAsset={pageAsset} components={COMPONENTS_MAP} />;
}
```
2. Always fetch data in Server Components for better performance
3. Use Client Components only for rendering dotCMS interactive components
### Debugging Tips
1. **Enable Development Mode**
```typescript
<dotcms-layout-body
[page]="pageAsset()"
[components]="components()"
mode="development"
/>
```
This will:
- Show detailed error messages
- Highlight unmapped components
- Log component lifecycle events
2. **Check Browser Console**
- Check for errors in the browser console
- Check for errors in the browser network tab
3. **Network Monitoring**
- Use browser dev tools to monitor API calls
- Check for 401/403 errors (auth issues)
- Verify asset loading paths
### Still Having Issues?
If you're still experiencing problems after trying these solutions:
1. Search existing [GitHub issues](https://github.com/dotCMS/core/issues)
2. Ask questions on the [community forum](https://community.dotcms.com/) to engage with other users.
3. Create a new issue with:
- Detailed reproduction steps
- Environment information
- Error messages
- Code samples
## Support
We offer multiple channels to get help with the dotCMS React SDK:
- **GitHub Issues**: For bug reports and feature requests, please [open an issue](https://github.com/dotCMS/core/issues/new/choose) in the GitHub repository.
- **Community Forum**: Join our [community discussions](https://community.dotcms.com/) to ask questions and share solutions.
- **Stack Overflow**: Use the tag `dotcms-react` when posting questions.
- **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://helpdesk.dotcms.com/support/).
When reporting issues, please include:
- SDK version you're using
- React version
- Minimal reproduction steps
- Expected vs. actual behavior
## Contributing
GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the dotCMS React SDK! If you'd like to contribute, please follow these steps:
1. Fork the repository [dotCMS/core](https://github.com/dotCMS/core)
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
Please ensure your code follows the existing style and includes appropriate tests.
## Licensing
dotCMS is available under either the [Business Source License 1.1 (BSL)](https://www.dotcms.com/bsl) or a commercial license.
Under the BSL, dotCMS can be used at no cost by individual developers, small businesses or agencies under $5M in total finances, and by larger organizations in non-production environments. Every BSL release automatically converts to GPL v3 four years after its release date. For full terms and FAQs, visit [dotcms.com/bsl](https://www.dotcms.com/bsl) and [dotcms.com/bsl-faq](https://www.dotcms.com/bsl-faq).
Production use in larger organizations, along with access to managed cloud, SLAs, support, and enterprise capabilities, is available under a commercial license from dotCMS. For details on commercial plans, features, and support options, see [dotcms.com/pricing](https://www.dotcms.com/pricing).