@dotcms/vue 1.5.5
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 +571 -0
- package/index.d.ts +12 -0
- package/index.js +842 -0
- package/lib/__test__/mocks.d.ts +6 -0
- package/lib/components/Column/Column.vue.d.ts +12 -0
- package/lib/components/Container/Container.vue.d.ts +11 -0
- package/lib/components/Container/ContainerNotFound.vue.d.ts +6 -0
- package/lib/components/Container/EmptyContainer.vue.d.ts +2 -0
- package/lib/components/Contentlet/Contentlet.vue.d.ts +14 -0
- package/lib/components/Contentlet/constants.d.ts +2 -0
- package/lib/components/DotCMSBlockEditorRenderer/DotCMSBlockEditorRenderer.vue.d.ts +5 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/BlockEditorBlock.vue.d.ts +13 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/BulletList.vue.d.ts +17 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/CodeBlock.vue.d.ts +22 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/DotContent.vue.d.ts +10 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/DotImage.vue.d.ts +7 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/DotVideo.vue.d.ts +7 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/GridBlock.vue.d.ts +10 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/Heading.vue.d.ts +22 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/ListItem.vue.d.ts +17 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/NoComponentProvided.vue.d.ts +6 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/OrderedList.vue.d.ts +17 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/Paragraph.vue.d.ts +22 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/Quote.vue.d.ts +17 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/TableRenderer.vue.d.ts +15 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/TextBlock.vue.d.ts +13 -0
- package/lib/components/DotCMSBlockEditorRenderer/components/blocks/UnknownBlock.vue.d.ts +10 -0
- package/lib/components/DotCMSBlockEditorRenderer/types.d.ts +44 -0
- package/lib/components/DotCMSEditableText/DotCMSEditableText.vue.d.ts +15 -0
- package/lib/components/DotCMSEditableText/utils.d.ts +22 -0
- package/lib/components/DotCMSLayoutBody/DotCMSLayoutBody.vue.d.ts +5 -0
- package/lib/components/DotCMSLayoutBody/components/ErrorMessage.vue.d.ts +2 -0
- package/lib/components/DotCMSLayoutBody/types.d.ts +17 -0
- package/lib/components/DotCMSShow/DotCMSShow.vue.d.ts +35 -0
- package/lib/components/FallbackComponent/FallbackComponent.vue.d.ts +13 -0
- package/lib/components/Row/Row.vue.d.ts +13 -0
- package/lib/composables/useCheckVisibleContent.d.ts +16 -0
- package/lib/composables/useDotCMSShowWhen.d.ts +18 -0
- package/lib/composables/useEditableDotCMSPage.d.ts +34 -0
- package/lib/composables/useIsAnalyticsActive.d.ts +14 -0
- package/lib/composables/useIsDevMode.d.ts +23 -0
- package/lib/contexts/dotcms-page.context.d.ts +61 -0
- package/lib/utils/toPlain.d.ts +12 -0
- package/package.json +47 -0
- package/test-setup.d.ts +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
# dotCMS Vue SDK
|
|
2
|
+
|
|
3
|
+
The `@dotcms/vue` SDK is the dotCMS official Vue 3 library. It empowers Vue developers to build powerful, editable websites and applications in no time, with full support for the Universal Visual Editor (UVE).
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Prerequisites & Setup](#prerequisites--setup)
|
|
8
|
+
- [Get a dotCMS Environment](#get-a-dotcms-environment)
|
|
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
|
+
- [Installation](#installation)
|
|
12
|
+
- [dotCMS Client Configuration](#dotcms-client-configuration)
|
|
13
|
+
- [Proxy Configuration for Static Assets](#proxy-configuration-for-static-assets)
|
|
14
|
+
- [Quickstart: Render a Page with dotCMS](#quickstart-render-a-page-with-dotcms)
|
|
15
|
+
- [Example Project](#example-project-)
|
|
16
|
+
- [SDK Reference](#sdk-reference)
|
|
17
|
+
- [DotCMSLayoutBody](#dotcmslayoutbody)
|
|
18
|
+
- [DotCMSEditableText](#dotcmseditabletext)
|
|
19
|
+
- [DotCMSBlockEditorRenderer](#dotcmsblockeditorrenderer)
|
|
20
|
+
- [DotCMSShow](#dotcmsshow)
|
|
21
|
+
- [useEditableDotCMSPage](#useeditabledotcmspage)
|
|
22
|
+
- [useDotCMSShowWhen](#usedotcmsshowwhen)
|
|
23
|
+
- [toPlain](#toplain)
|
|
24
|
+
- [Troubleshooting](#troubleshooting)
|
|
25
|
+
- [Common Issues & Solutions](#common-issues--solutions)
|
|
26
|
+
- [Debugging Tips](#debugging-tips)
|
|
27
|
+
- [Still Having Issues?](#still-having-issues)
|
|
28
|
+
- [Support](#support)
|
|
29
|
+
- [Contributing](#contributing)
|
|
30
|
+
- [Licensing](#licensing)
|
|
31
|
+
|
|
32
|
+
## Prerequisites & Setup
|
|
33
|
+
|
|
34
|
+
### Get a dotCMS Environment
|
|
35
|
+
|
|
36
|
+
#### Version Compatibility
|
|
37
|
+
|
|
38
|
+
- **Recommended**: dotCMS Evergreen
|
|
39
|
+
- **Minimum**: dotCMS v25.05
|
|
40
|
+
- **Best Experience**: Latest Evergreen release
|
|
41
|
+
|
|
42
|
+
#### Environment Setup
|
|
43
|
+
|
|
44
|
+
**For Production Use:**
|
|
45
|
+
|
|
46
|
+
- ☁️ [Cloud hosting options](https://www.dotcms.com/pricing) - managed solutions with SLA
|
|
47
|
+
- 🛠️ [Self-hosted options](https://dev.dotcms.com/docs/current-releases) - deploy on your infrastructure
|
|
48
|
+
|
|
49
|
+
**For Testing & Development:**
|
|
50
|
+
|
|
51
|
+
- 🧑🏻💻 [dotCMS demo site](https://demo.dotcms.com/dotAdmin/#/public/login) - perfect for trying out the SDK
|
|
52
|
+
- 📘 [Learn how to use the demo site](https://dev.dotcms.com/docs/demo-site)
|
|
53
|
+
- 📝 Read-only access, ideal for building proof-of-concepts
|
|
54
|
+
|
|
55
|
+
**For Local Development:**
|
|
56
|
+
|
|
57
|
+
- 🐳 [Docker setup guide](https://github.com/dotCMS/core/tree/main/docker/docker-compose-examples/single-node-demo-site)
|
|
58
|
+
- 💻 [Local installation guide](https://dev.dotcms.com/docs/quick-start-guide)
|
|
59
|
+
|
|
60
|
+
### Configure The Universal Visual Editor App
|
|
61
|
+
|
|
62
|
+
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!
|
|
63
|
+
|
|
64
|
+
When configuring the UVE app, point it at your Vue app's URL (e.g. `http://localhost:5173`):
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{ "config": [{ "pattern": "(.*)", "url": "http://localhost:5173" }] }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Create a dotCMS API Key
|
|
71
|
+
|
|
72
|
+
> [!TIP]
|
|
73
|
+
> 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.
|
|
74
|
+
|
|
75
|
+
This integration requires an API Key with read-only permissions for security best practices:
|
|
76
|
+
|
|
77
|
+
1. Go to the **dotCMS admin panel**.
|
|
78
|
+
2. Click on **System** > **Users**.
|
|
79
|
+
3. Select the user you want to create the API Key for.
|
|
80
|
+
4. Go to **API Access Key** and generate a new key.
|
|
81
|
+
|
|
82
|
+
For detailed instructions, please refer to the [dotCMS API Documentation - Read-only token](https://dev.dotcms.com/docs/rest-api-authentication#ReadOnlyToken).
|
|
83
|
+
|
|
84
|
+
### Installation
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install @dotcms/vue@latest
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Requires **Vue 3.4+** (declared as a peer dependency). The install also brings in:
|
|
91
|
+
|
|
92
|
+
- `@dotcms/uve`: Enables interaction with the [Universal Visual Editor](https://dev.dotcms.com/docs/uve-headless-config) for real-time content editing
|
|
93
|
+
- `@dotcms/client`: Provides the core client functionality for fetching and managing dotCMS data
|
|
94
|
+
- `@tinymce/tinymce-vue`: Powers inline text editing in [`DotCMSEditableText`](#dotcmseditabletext)
|
|
95
|
+
|
|
96
|
+
### dotCMS Client Configuration
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { createDotCMSClient } from '@dotcms/client';
|
|
100
|
+
|
|
101
|
+
export const dotCMSClient = createDotCMSClient({
|
|
102
|
+
dotcmsUrl: import.meta.env.VITE_DOTCMS_HOST,
|
|
103
|
+
authToken: import.meta.env.VITE_DOTCMS_AUTH_TOKEN, // Optional for public content
|
|
104
|
+
siteId: import.meta.env.VITE_DOTCMS_SITE_ID, // Optional site identifier/name
|
|
105
|
+
requestOptions: {
|
|
106
|
+
// The UVE needs fresh data so in-context edits are reflected immediately.
|
|
107
|
+
cache: 'no-cache'
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Proxy Configuration for Static Assets
|
|
113
|
+
|
|
114
|
+
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 the user experience.
|
|
115
|
+
|
|
116
|
+
#### 1. Configure Vite
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
// vite.config.ts
|
|
120
|
+
import { defineConfig } from 'vite';
|
|
121
|
+
|
|
122
|
+
export default defineConfig({
|
|
123
|
+
server: {
|
|
124
|
+
proxy: {
|
|
125
|
+
'/dA': {
|
|
126
|
+
target: 'https://your-dotcms-instance.com',
|
|
127
|
+
changeOrigin: true
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Learn more about Vite configuration [here](https://vitejs.dev/config/).
|
|
135
|
+
|
|
136
|
+
#### 2. Usage in Components
|
|
137
|
+
|
|
138
|
+
Once configured, image URLs in your components will automatically be proxied to your dotCMS instance:
|
|
139
|
+
|
|
140
|
+
> 📚 Learn more about [Image Resizing and Processing in dotCMS](https://www.dotcms.com/blog/image-resizing-and-processing-in-dotcms-with-angular-and-nextjs).
|
|
141
|
+
|
|
142
|
+
```vue
|
|
143
|
+
<script setup lang="ts">
|
|
144
|
+
import type { DotCMSBasicContentlet } from '@dotcms/types';
|
|
145
|
+
|
|
146
|
+
defineProps<{ contentlet: DotCMSBasicContentlet }>();
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<template>
|
|
150
|
+
<img :src="`/dA/${contentlet.inode}`" :alt="contentlet.title" />
|
|
151
|
+
</template>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Quickstart: Render a Page with dotCMS
|
|
155
|
+
|
|
156
|
+
The following example shows how to quickly set up a basic dotCMS page renderer in your Vue application. It demonstrates how to:
|
|
157
|
+
|
|
158
|
+
- Fetch a dotCMS page and render it with `DotCMSLayoutBody`
|
|
159
|
+
- Map content types to your own Vue components
|
|
160
|
+
- Keep the page editable and live-updating inside the Universal Visual Editor
|
|
161
|
+
|
|
162
|
+
Because a Vue composable must be called synchronously in `setup`, the recommended pattern splits fetching from rendering: a **fetcher** loads the page, then mounts a **renderer** child that receives the resolved page and calls `useEditableDotCMSPage`.
|
|
163
|
+
|
|
164
|
+
```vue
|
|
165
|
+
<!-- PageView.vue — fetches the page, then mounts the renderer -->
|
|
166
|
+
<script setup lang="ts">
|
|
167
|
+
import { shallowRef, onMounted } from 'vue';
|
|
168
|
+
|
|
169
|
+
import PageRenderer from './PageRenderer.vue';
|
|
170
|
+
import { dotCMSClient } from './dotCMSClient';
|
|
171
|
+
|
|
172
|
+
// shallowRef keeps the response a plain object (see toPlain / reactivity note below).
|
|
173
|
+
const pageResponse = shallowRef<Awaited<ReturnType<typeof dotCMSClient.page.get>> | null>(null);
|
|
174
|
+
|
|
175
|
+
onMounted(async () => {
|
|
176
|
+
pageResponse.value = await dotCMSClient.page.get('/');
|
|
177
|
+
});
|
|
178
|
+
</script>
|
|
179
|
+
|
|
180
|
+
<template>
|
|
181
|
+
<PageRenderer v-if="pageResponse" :page-response="pageResponse" />
|
|
182
|
+
</template>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```vue
|
|
186
|
+
<!-- PageRenderer.vue — renders the resolved page -->
|
|
187
|
+
<script setup lang="ts">
|
|
188
|
+
import { DotCMSLayoutBody, useEditableDotCMSPage } from '@dotcms/vue';
|
|
189
|
+
import { computed } from 'vue';
|
|
190
|
+
|
|
191
|
+
import Blog from './content-types/Blog.vue';
|
|
192
|
+
import Product from './content-types/Product.vue';
|
|
193
|
+
|
|
194
|
+
const props = defineProps<{ pageResponse: unknown }>();
|
|
195
|
+
|
|
196
|
+
const pageComponents = {
|
|
197
|
+
Blog,
|
|
198
|
+
Product
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Returns a reactive ref that live-updates while editing in the UVE.
|
|
202
|
+
const page = useEditableDotCMSPage(props.pageResponse as never);
|
|
203
|
+
const pageAsset = computed(() => page.value?.pageAsset);
|
|
204
|
+
</script>
|
|
205
|
+
|
|
206
|
+
<template>
|
|
207
|
+
<DotCMSLayoutBody v-if="pageAsset" :page="pageAsset" :components="pageComponents" />
|
|
208
|
+
</template>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Example Project 🚀
|
|
212
|
+
|
|
213
|
+
Looking to get started quickly? Our [Vue.js starter project](https://github.com/dotCMS/core/tree/main/examples/vuejs) is the perfect launchpad. This Vite + TypeScript + Tailwind template demonstrates everything you need:
|
|
214
|
+
|
|
215
|
+
📦 Fetch and render dotCMS pages with best practices
|
|
216
|
+
🧩 Map components to different content types
|
|
217
|
+
🔍 Listing pages with search functionality
|
|
218
|
+
📝 Detail pages with the block editor
|
|
219
|
+
📈 Image and asset optimization for better performance
|
|
220
|
+
✨ Seamless editing via the Universal Visual Editor (UVE)
|
|
221
|
+
⚡️ Vue Composition API + reactive live updates
|
|
222
|
+
|
|
223
|
+
## SDK Reference
|
|
224
|
+
|
|
225
|
+
All components, composables and utilities are imported from `@dotcms/vue`.
|
|
226
|
+
|
|
227
|
+
### DotCMSLayoutBody
|
|
228
|
+
|
|
229
|
+
`DotCMSLayoutBody` renders the layout for a dotCMS page (rows → columns → containers → contentlets), dispatching each contentlet to the mapped component. It supports both production and development modes.
|
|
230
|
+
|
|
231
|
+
| Prop | Type | Required | Default | Description |
|
|
232
|
+
| ------------ | -------------------------- | -------- | -------------- | -------------------------------------------------------------------- |
|
|
233
|
+
| `page` | `DotCMSPageAsset` | ✅ | - | The page asset containing the layout to render |
|
|
234
|
+
| `components` | `Record<string, Component>`| ✅ | `{}` | [Map of content type → Vue component](#component-mapping) |
|
|
235
|
+
| `mode` | `DotCMSPageRendererMode` | ❌ | `'production'` | [Rendering mode ('production' or 'development')](#layout-body-modes) |
|
|
236
|
+
|
|
237
|
+
#### Usage
|
|
238
|
+
|
|
239
|
+
```vue
|
|
240
|
+
<script setup lang="ts">
|
|
241
|
+
import { DotCMSLayoutBody } from '@dotcms/vue';
|
|
242
|
+
import type { DotCMSPageAsset } from '@dotcms/types';
|
|
243
|
+
|
|
244
|
+
import Blog from './content-types/Blog.vue';
|
|
245
|
+
import Product from './content-types/Product.vue';
|
|
246
|
+
|
|
247
|
+
defineProps<{ page: DotCMSPageAsset }>();
|
|
248
|
+
|
|
249
|
+
const components = {
|
|
250
|
+
Blog,
|
|
251
|
+
Product
|
|
252
|
+
};
|
|
253
|
+
</script>
|
|
254
|
+
|
|
255
|
+
<template>
|
|
256
|
+
<DotCMSLayoutBody :page="page" :components="components" />
|
|
257
|
+
</template>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Layout Body Modes
|
|
261
|
+
|
|
262
|
+
- `production`: Performance-optimized mode that only renders content with explicitly mapped components, leaving unmapped content empty.
|
|
263
|
+
- `development`: Debug-friendly mode that renders a fallback for unmapped content types and shows visual indicators for empty containers and missing mappings. **Inside the UVE, edit mode is detected automatically** — the editor `data-dot-*` metadata is always emitted regardless of the `mode` prop.
|
|
264
|
+
|
|
265
|
+
#### Component Mapping
|
|
266
|
+
|
|
267
|
+
The `components` prop maps content type variable names to Vue components. Each contentlet's fields are passed to the matched component as props.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const components = {
|
|
271
|
+
Blog: MyBlogCard,
|
|
272
|
+
Product: MyProductCard,
|
|
273
|
+
CustomNoComponent: MyFallback // optional: rendered for unmapped types in dev mode
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
- Keys (e.g. `Blog`, `Product`): must match your [content type variable names](https://dev.dotcms.com/docs/content-types#VariableNames) in dotCMS (they are case-sensitive — e.g. `webPageContent`, `calendarEvent`).
|
|
278
|
+
- Values: the Vue component that renders that content type. Declare a typed props interface for the fields you use — do **not** spread the full `DotCMSBasicContentlet` type onto a component, as Vue runtime-validates every declared prop and dotCMS ships some fields (e.g. `language`, `modDate`) with types that differ from the type defs.
|
|
279
|
+
- The special `CustomNoComponent` key is the fallback rendered when no mapping exists.
|
|
280
|
+
|
|
281
|
+
> [!TIP]
|
|
282
|
+
> Always use the exact content type variable name from dotCMS as the key. You can find it in the Content Types section of your dotCMS admin panel.
|
|
283
|
+
|
|
284
|
+
### DotCMSEditableText
|
|
285
|
+
|
|
286
|
+
`DotCMSEditableText` enables inline editing of a single text field in dotCMS. Inside the UVE in edit mode it mounts a TinyMCE editor; everywhere else it renders the field's current value.
|
|
287
|
+
|
|
288
|
+
| Prop | Type | Required | Default | Description |
|
|
289
|
+
| ------------ | ----------------------------- | -------- | --------- | ------------------------------------------------------------------ |
|
|
290
|
+
| `contentlet` | `T extends DotCMSBasicContentlet` | ✅ | - | The contentlet containing the editable field |
|
|
291
|
+
| `fieldName` | `keyof T` | ✅ | - | Name of the field to edit (must be a valid key of the contentlet) |
|
|
292
|
+
| `mode` | `'plain' \| 'minimal' \| 'full'` | ❌ | `'plain'` | TinyMCE toolbar preset. `full` enables the full style bubble menu. |
|
|
293
|
+
| `format` | `'text' \| 'html'` | ❌ | `'text'` | `text` renders HTML as plain text; `html` interprets HTML markup |
|
|
294
|
+
|
|
295
|
+
#### Usage
|
|
296
|
+
|
|
297
|
+
```vue
|
|
298
|
+
<script setup lang="ts">
|
|
299
|
+
import { DotCMSEditableText } from '@dotcms/vue';
|
|
300
|
+
import type { DotCMSBasicContentlet } from '@dotcms/types';
|
|
301
|
+
|
|
302
|
+
const props = defineProps<{ contentlet: DotCMSBasicContentlet }>();
|
|
303
|
+
</script>
|
|
304
|
+
|
|
305
|
+
<template>
|
|
306
|
+
<div class="banner">
|
|
307
|
+
<img :src="`/dA/${contentlet.inode}`" :alt="contentlet.title" />
|
|
308
|
+
<h2>
|
|
309
|
+
<DotCMSEditableText :contentlet="contentlet" field-name="title" />
|
|
310
|
+
</h2>
|
|
311
|
+
</div>
|
|
312
|
+
</template>
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Editor Integration
|
|
316
|
+
|
|
317
|
+
- Detects UVE edit mode and enables inline TinyMCE editing.
|
|
318
|
+
- Sends the edited content back to the editor on blur, without opening the full content dialog.
|
|
319
|
+
- The TinyMCE script is loaded from your dotCMS instance (`dotCMSHost`), so no extra TinyMCE install is required.
|
|
320
|
+
|
|
321
|
+
### DotCMSBlockEditorRenderer
|
|
322
|
+
|
|
323
|
+
`DotCMSBlockEditorRenderer` renders [Block Editor](https://dev.dotcms.com/docs/block-editor) content from dotCMS, with support for custom block renderers.
|
|
324
|
+
|
|
325
|
+
| Prop | Type | Required | Default | Description |
|
|
326
|
+
| ----------------- | --------------------------- | -------- | ------- | --------------------------------------------------------------- |
|
|
327
|
+
| `blocks` | `BlockEditorNode` | ✅ | - | The Block Editor field value to render |
|
|
328
|
+
| `customRenderers` | `CustomRenderer` | ❌ | - | Custom Vue components for specific block types / content types |
|
|
329
|
+
| `className` | `string` | ❌ | - | CSS class applied to the container |
|
|
330
|
+
| `style` | `CSSProperties` | ❌ | - | Inline styles for the container |
|
|
331
|
+
| `isDevMode` | `boolean` | ❌ | `false` | When `true`, shows a visible message for invalid/unknown blocks |
|
|
332
|
+
|
|
333
|
+
#### Usage
|
|
334
|
+
|
|
335
|
+
A custom renderer is a Vue component that receives the block as a `node` prop and the rendered children in its default `<slot />`.
|
|
336
|
+
|
|
337
|
+
```vue
|
|
338
|
+
<!-- CustomHeading.vue -->
|
|
339
|
+
<script setup lang="ts">
|
|
340
|
+
import type { CustomRendererProps } from '@dotcms/vue';
|
|
341
|
+
|
|
342
|
+
defineProps<CustomRendererProps>();
|
|
343
|
+
</script>
|
|
344
|
+
|
|
345
|
+
<template>
|
|
346
|
+
<h1 class="my-heading"><slot /></h1>
|
|
347
|
+
</template>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
```vue
|
|
351
|
+
<!-- DetailPage.vue -->
|
|
352
|
+
<script setup lang="ts">
|
|
353
|
+
import { DotCMSBlockEditorRenderer, type CustomRenderer } from '@dotcms/vue';
|
|
354
|
+
import type { DotCMSBasicContentlet } from '@dotcms/types';
|
|
355
|
+
|
|
356
|
+
import CustomHeading from './CustomHeading.vue';
|
|
357
|
+
|
|
358
|
+
const props = defineProps<{ contentlet: DotCMSBasicContentlet }>();
|
|
359
|
+
|
|
360
|
+
const customRenderers: CustomRenderer = {
|
|
361
|
+
heading: CustomHeading
|
|
362
|
+
};
|
|
363
|
+
</script>
|
|
364
|
+
|
|
365
|
+
<template>
|
|
366
|
+
<DotCMSBlockEditorRenderer
|
|
367
|
+
:blocks="contentlet.myBlockEditorField"
|
|
368
|
+
:custom-renderers="customRenderers" />
|
|
369
|
+
</template>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### Recommendations
|
|
373
|
+
|
|
374
|
+
- Should not be used together with [`DotCMSEditableText`](#dotcmseditabletext) on the same field.
|
|
375
|
+
- Be mindful that the CSS cascade can affect the look and feel of your blocks.
|
|
376
|
+
- Only works with [Block Editor fields](https://dev.dotcms.com/docs/block-editor). For other text fields, use [`DotCMSEditableText`](#dotcmseditabletext).
|
|
377
|
+
|
|
378
|
+
### DotCMSShow
|
|
379
|
+
|
|
380
|
+
`DotCMSShow` conditionally renders its slot content based on the current UVE mode — useful for editor-only affordances like Edit or Reorder buttons.
|
|
381
|
+
|
|
382
|
+
| Prop | Type | Required | Default | Description |
|
|
383
|
+
| ------ | ---------- | -------- | ---------------- | -------------------------------------------------------- |
|
|
384
|
+
| `when` | `UVE_MODE` | ❌ | `UVE_MODE.EDIT` | The UVE mode in which the slot content should be shown |
|
|
385
|
+
|
|
386
|
+
#### Usage
|
|
387
|
+
|
|
388
|
+
```vue
|
|
389
|
+
<script setup lang="ts">
|
|
390
|
+
import { DotCMSShow } from '@dotcms/vue';
|
|
391
|
+
import { UVE_MODE } from '@dotcms/types';
|
|
392
|
+
</script>
|
|
393
|
+
|
|
394
|
+
<template>
|
|
395
|
+
<DotCMSShow :when="UVE_MODE.EDIT">
|
|
396
|
+
<button>Edit</button>
|
|
397
|
+
</DotCMSShow>
|
|
398
|
+
</template>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
📚 Learn more about the `UVE_MODE` enum in the [dotCMS UVE documentation](https://dev.dotcms.com/docs/universal-visual-editor).
|
|
402
|
+
|
|
403
|
+
### useEditableDotCMSPage
|
|
404
|
+
|
|
405
|
+
`useEditableDotCMSPage` wires a page into the Universal Visual Editor and returns a reactive ref that live-updates as an editor makes changes. Outside the UVE it is a pass-through — the returned ref simply holds the initial response.
|
|
406
|
+
|
|
407
|
+
| Param | Type | Required | Description |
|
|
408
|
+
| -------------- | ----------------------------- | -------- | --------------------------------------------- |
|
|
409
|
+
| `pageResponse` | `DotCMSComposedPageResponse` | ✅ | The page response from `client.page.get()` |
|
|
410
|
+
|
|
411
|
+
**Returns** a `Ref<DotCMSComposedPageResponse>` — access `.value.pageAsset` and `.value.content`.
|
|
412
|
+
|
|
413
|
+
When you use the composable, it:
|
|
414
|
+
|
|
415
|
+
1. Initializes the UVE with your page data
|
|
416
|
+
2. Keeps the editor navigation in sync
|
|
417
|
+
3. Subscribes to content changes and swaps in the new page automatically when content is edited, blocks are added/removed, layout changes, or components are moved
|
|
418
|
+
4. Cleans up all listeners on unmount
|
|
419
|
+
|
|
420
|
+
#### Usage
|
|
421
|
+
|
|
422
|
+
```vue
|
|
423
|
+
<script setup lang="ts">
|
|
424
|
+
import { DotCMSLayoutBody, useEditableDotCMSPage } from '@dotcms/vue';
|
|
425
|
+
import { computed } from 'vue';
|
|
426
|
+
|
|
427
|
+
const props = defineProps<{ pageResponse: unknown }>();
|
|
428
|
+
|
|
429
|
+
const page = useEditableDotCMSPage(props.pageResponse as never);
|
|
430
|
+
const pageAsset = computed(() => page.value?.pageAsset);
|
|
431
|
+
|
|
432
|
+
const components = {
|
|
433
|
+
/* content-type → component map */
|
|
434
|
+
};
|
|
435
|
+
</script>
|
|
436
|
+
|
|
437
|
+
<template>
|
|
438
|
+
<DotCMSLayoutBody v-if="pageAsset" :page="pageAsset" :components="components" />
|
|
439
|
+
</template>
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
> [!IMPORTANT]
|
|
443
|
+
> Store the page response in a `shallowRef` (not a deep `ref`). A deep `ref` wraps the whole page in reactive Proxies, which the UVE cannot `postMessage` to the editor (`DataCloneError`). See [`toPlain`](#toplain).
|
|
444
|
+
|
|
445
|
+
### useDotCMSShowWhen
|
|
446
|
+
|
|
447
|
+
`useDotCMSShowWhen` returns a reactive boolean for whether the current UVE mode matches — useful for mode-based logic outside of the template.
|
|
448
|
+
|
|
449
|
+
| Param | Type | Required | Description |
|
|
450
|
+
| ------ | ---------- | -------- | ---------------------------------- |
|
|
451
|
+
| `when` | `UVE_MODE` | ✅ | The UVE mode to check against |
|
|
452
|
+
|
|
453
|
+
#### Usage
|
|
454
|
+
|
|
455
|
+
```vue
|
|
456
|
+
<script setup lang="ts">
|
|
457
|
+
import { useDotCMSShowWhen } from '@dotcms/vue';
|
|
458
|
+
import { UVE_MODE } from '@dotcms/types';
|
|
459
|
+
|
|
460
|
+
const isEditMode = useDotCMSShowWhen(UVE_MODE.EDIT); // Readonly<Ref<boolean>>
|
|
461
|
+
</script>
|
|
462
|
+
|
|
463
|
+
<template>
|
|
464
|
+
<button v-if="isEditMode">Edit</button>
|
|
465
|
+
</template>
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### toPlain
|
|
469
|
+
|
|
470
|
+
`toPlain` deep-unwraps a Vue reactive value (refs / reactive proxies) into a plain, structured-clone-safe object. Use it before passing reactive data to UVE editor actions (`editContentlet`, `enableBlockEditorInline`, …) from `@dotcms/uve`, which send their argument to the editor via `postMessage`.
|
|
471
|
+
|
|
472
|
+
```vue
|
|
473
|
+
<script setup lang="ts">
|
|
474
|
+
import { toPlain } from '@dotcms/vue';
|
|
475
|
+
import { editContentlet } from '@dotcms/uve';
|
|
476
|
+
import type { DotCMSBasicContentlet } from '@dotcms/types';
|
|
477
|
+
|
|
478
|
+
const props = defineProps<{ contentlet: DotCMSBasicContentlet }>();
|
|
479
|
+
|
|
480
|
+
const onEdit = () => editContentlet(toPlain(props.contentlet));
|
|
481
|
+
</script>
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Troubleshooting
|
|
485
|
+
|
|
486
|
+
### Common Issues & Solutions
|
|
487
|
+
|
|
488
|
+
#### Universal Visual Editor (UVE)
|
|
489
|
+
|
|
490
|
+
1. **UVE not loading**: the page renders but the editor tools/overlays don't appear.
|
|
491
|
+
- **Possible causes**: incorrect UVE app configuration; missing `useEditableDotCMSPage`; the app is not running inside the UVE iframe.
|
|
492
|
+
- **Solutions**: verify the UVE app URL matches your Vue dev server; ensure the page tree is wrapped with `useEditableDotCMSPage`; confirm `data-dot-object="contentlet"` attributes are present on rendered contentlets (they only appear in edit mode).
|
|
493
|
+
|
|
494
|
+
2. **`DataCloneError: could not be cloned`** when loading in the editor.
|
|
495
|
+
- **Cause**: a Vue reactive Proxy was sent to the editor via `postMessage`.
|
|
496
|
+
- **Solutions**: store the page response in a `shallowRef`, not a deep `ref`; use [`toPlain`](#toplain) before calling UVE editor actions with reactive data.
|
|
497
|
+
|
|
498
|
+
3. **Content edits don't update the page live.**
|
|
499
|
+
- **Cause**: usually a duplicate Vue instance — if `vue` is bundled into a consumer copy, the SDK's reactivity is a different instance from your app's. Ensure a single `vue` is installed.
|
|
500
|
+
|
|
501
|
+
#### Missing Content
|
|
502
|
+
|
|
503
|
+
1. **Components not rendering**: empty spaces where content should appear.
|
|
504
|
+
- **Solutions**: check the `components` map registration; verify content type variable names match exactly (case-sensitive); use `mode="development"` for detailed logging.
|
|
505
|
+
|
|
506
|
+
2. **Prop validation warnings** (e.g. *Invalid prop: type check failed for prop "modDate"*).
|
|
507
|
+
- **Cause**: a content-type component declares props by extending the full contentlet type; dotCMS ships some system fields with types that differ from the defs.
|
|
508
|
+
- **Solution**: declare only the specific fields your component reads.
|
|
509
|
+
|
|
510
|
+
#### Development Setup
|
|
511
|
+
|
|
512
|
+
1. **`npm install` fails**: clear the npm cache (`npm cache clean --force`), delete `node_modules`, and reinstall; verify your Node.js version.
|
|
513
|
+
|
|
514
|
+
2. **Runtime errors about missing imports**: check that all SDK imports come from `@dotcms/vue`, and that peer dependencies (`vue`, `@dotcms/client`, `@dotcms/uve`, `@dotcms/types`) are installed.
|
|
515
|
+
|
|
516
|
+
### Debugging Tips
|
|
517
|
+
|
|
518
|
+
1. **Enable development mode**
|
|
519
|
+
|
|
520
|
+
```vue
|
|
521
|
+
<DotCMSLayoutBody :page="pageAsset" :components="components" mode="development" />
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
This shows detailed messages, renders fallbacks for unmapped components, and highlights empty containers.
|
|
525
|
+
|
|
526
|
+
2. **Check the browser console and network tab** for errors, and watch for 401/403 (auth) responses.
|
|
527
|
+
|
|
528
|
+
3. **Inspect the DOM** inside the UVE iframe — contentlets should carry `data-dot-object="contentlet"` and containers `data-dot-object="container"` in edit mode.
|
|
529
|
+
|
|
530
|
+
### Still Having Issues?
|
|
531
|
+
|
|
532
|
+
If you're still experiencing problems after trying these solutions:
|
|
533
|
+
|
|
534
|
+
1. Search existing [GitHub issues](https://github.com/dotCMS/core/issues)
|
|
535
|
+
2. Ask questions on the [community forum](https://community.dotcms.com/)
|
|
536
|
+
3. Create a new issue with detailed reproduction steps, environment information, error messages, and code samples
|
|
537
|
+
|
|
538
|
+
## Support
|
|
539
|
+
|
|
540
|
+
We offer multiple channels to get help with the dotCMS Vue SDK:
|
|
541
|
+
|
|
542
|
+
- **GitHub Issues**: For bug reports and feature requests, please [open an issue](https://github.com/dotCMS/core/issues/new/choose).
|
|
543
|
+
- **Community Forum**: Join our [community discussions](https://community.dotcms.com/).
|
|
544
|
+
- **Enterprise Support**: Enterprise customers can access premium support through the [dotCMS Support Portal](https://www.dotcms.com/support).
|
|
545
|
+
|
|
546
|
+
When reporting issues, please include:
|
|
547
|
+
|
|
548
|
+
- SDK version you're using
|
|
549
|
+
- Vue version
|
|
550
|
+
- Minimal reproduction steps
|
|
551
|
+
- Expected vs. actual behavior
|
|
552
|
+
|
|
553
|
+
## Contributing
|
|
554
|
+
|
|
555
|
+
GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the dotCMS Vue SDK! If you'd like to contribute, please:
|
|
556
|
+
|
|
557
|
+
1. Fork the repository [dotCMS/core](https://github.com/dotCMS/core)
|
|
558
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
559
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
560
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
561
|
+
5. Open a Pull Request
|
|
562
|
+
|
|
563
|
+
Please ensure your code follows the existing style and includes appropriate tests.
|
|
564
|
+
|
|
565
|
+
## Licensing
|
|
566
|
+
|
|
567
|
+
dotCMS is available under either the [Business Source License 1.1 (BSL)](https://www.dotcms.com/bsl) or a commercial license.
|
|
568
|
+
|
|
569
|
+
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).
|
|
570
|
+
|
|
571
|
+
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).
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { useEditableDotCMSPage } from './lib/composables/useEditableDotCMSPage';
|
|
2
|
+
export { useDotCMSShowWhen } from './lib/composables/useDotCMSShowWhen';
|
|
3
|
+
export { toPlain } from './lib/utils/toPlain';
|
|
4
|
+
export { default as DotCMSShow } from './lib/components/DotCMSShow/DotCMSShow.vue';
|
|
5
|
+
export { default as DotCMSLayoutBody } from './lib/components/DotCMSLayoutBody/DotCMSLayoutBody.vue';
|
|
6
|
+
export { default as DotCMSEditableText } from './lib/components/DotCMSEditableText/DotCMSEditableText.vue';
|
|
7
|
+
export { default as DotCMSBlockEditorRenderer } from './lib/components/DotCMSBlockEditorRenderer/DotCMSBlockEditorRenderer.vue';
|
|
8
|
+
export type { DotCMSLayoutBodyProps } from './lib/components/DotCMSLayoutBody/types';
|
|
9
|
+
export type { BlockEditorRendererProps, CustomRenderer, CustomRendererComponent, CustomRendererProps } from './lib/components/DotCMSBlockEditorRenderer/types';
|
|
10
|
+
export type { DotCMSEditableTextProps, DOT_EDITABLE_TEXT_MODE, DOT_EDITABLE_TEXT_FORMAT } from './lib/components/DotCMSEditableText/utils';
|
|
11
|
+
export { provideDotCMSPageContext, useDotCMSPageContext, DOTCMS_PAGE_CONTEXT } from './lib/contexts/dotcms-page.context';
|
|
12
|
+
export type { DotCMSPageContextValue } from './lib/contexts/dotcms-page.context';
|