Reputation: 1866
I am trying to incorporate live preview with my Payload CMS, using Vue 3 as front end. I have followed this "tutorial" starting at around 11:00 but this CMS is usually more geared towards React.
I have set up this super simple Pages.js collections:
const Pages = {
admin: {
useAsTitle: 'title',
livePreview:{
url: 'http://localhost:1234',
}
},
}
export default Pages
And I now want to connect it to Vue somehow I guess. I have my router index.js file which loads the Page component:
import { createRouter, createWebHistory } from 'vue-router'
import Page from '../views/Page.vue'
const routes = [
{
path: '/:slug',
name: 'Page',
component: Page,
props: true
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
And the page component itself is pretty simple at the moment since I only offer one block type "Hero" block:
<template>
<div v-if="pageData">
<div v-for="block in pageData.layout" :key="block.id">
<hero-block v-if="block.blockType === 'hero'" :title="block.title" :subtitle="block.content[0]?.children[0]?.text" :imageURL="block.media?.url" :imageAlt="block.media?.['alt text']"></hero-block>
</div>
</div>
<div v-else>
<p>Loading...</p>
</div>
</template>
<script>
import HeroBlock from '../blocks/HeroBlock.vue'
export default {
name: 'Page',
components:{
HeroBlock
},
props: {
slug: {
type: String,
required: true
}
},
data() {
return {
pageData: null
}
},
async mounted() {
await this.fetchPageData();
},
methods: {
async fetchPageData() {
try {
const apiUrl = import.meta.env.VITE_API_URL;
const response = await fetch(`${apiUrl}/pages?where[slug][equals]=${this.slug}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
this.pageData = data.docs[0];
if (!this.pageData) {
console.error('pageData is missing, load 404 here instead');
}
} catch (error) {
console.error('Error fetching page data:', error);
}
},
}
}
</script>
So I have two questions:
1. How can I incorporate the live preview functionality with Vue 3 as front end framework?
2. Since Payload seems pretty into React, should I consider another CMS? People in their discord thought I could still use it, but are there other good open source headless CMS:s that are more "Vue friendly"?
Upvotes: 0
Views: 531
Reputation: 11
If your front-end application is built with Vue 3 or Nuxt 3, you can use the useLivePreview composable that Payload provides.
First, install the @payloadcms/live-preview-vue package:
npm install @payloadcms/live-preview-vue
Then, use the useLivePreview hook in your Vue component:
<script setup lang="ts">
import type { PageData } from '~/types';
import { defineProps } from 'vue';
import { useLivePreview } from '@payloadcms/live-preview-vue';
// Fetch the initial data on the parent component or using async state
const props = defineProps<{ initialData: PageData }>();
// The hook will take over from here and keep the preview in sync with the changes you make.
// The `data` property will contain the live data of the document only when viewed from the Preview view of the Admin UI.
const { data } = useLivePreview<PageData>({
initialData: props.initialData,
serverURL: "<PAYLOAD_SERVER_URL>",
depth: 2,
});
</script>
<template>
<h1>{{ data.title }}</h1>
</template>
Docs here. If you want to roll your own solution there's a guide for that in the docs just below the Vue entry.
As for your second question. Another fantastic headless CMS to consider is Directus. It also has live preview, and is very customizable. Bonus for you is that the admin panel is based on Vue, and not React.
Upvotes: 1