Connect Components
Learn how to integrate Craft CMS data with your Nuxt components
This guide explains the steps to connect your Vue components with data from Craft CMS. We’ll set up a catch-all route, create a mapping object for components, query data,
and use the <CraftPage/>
and <CraftArea/>
components to display content dynamically.
Catch all route
To support dynamic URLs in your Nuxt app, add a catch-all route by creating a file named ~/pages/[...slug].vue
.
This route will capture all URLs and allow you to dynamically render the corresponding content.
Mapping Object
Define a mapping object in the ~/pages/[...slug].vue
file. This object connects each Craft CMS section handle to a Vue page component and each field handle to a specific
Vue component. This setup allows the correct component to render based on the Craft CMS data.
For example:
<script setup lang="ts">
import type { Config } from 'vue-craftcms'
import Home from '~/templates/pages/home.vue'
import News from '~/templates/pages/news.vue'
import ImageText from '~/templates/components/imageText.vue'
import Headline from '~/templates/components/headline.vue'
const mapping: Config = {
pages: {
home: Home, // 'home' is the section handle of the Craft CMS section, 'Home' is the Vue component.
news: News,
},
components: {
imageText: ImageText,
headline: Headline,
},
}
</script>
Query Data
Use the useCraftQuery()
composable to fetch data from Craft CMS. Combine this with Nuxt’s useRoute()
composable to get the correct URI based on the route parameters.
Here’s what you can add the code to [...slug].vue
:
const route = useRoute()
const uri = route.params.slug.length > 0 ? route.params.slug : '__home__'
const { data, error } = await useCraftQuery('entries').uri(uri).one()
if (error.value) {
console.error(error.value)
}
console.log(data.value)
Display Page
To display the page data, use the <CraftPage/>
component in [...slug].vue
. This component automatically renders based on the
mapping configuration and data received from Craft CMS.
To find out more about the <CraftPage/>
check out the docs.
Here’s what a full example file might look like:
<script setup lang="ts">
import { CraftNotImplemented, type Config } from 'vue-craftcms'
import Home from '~/templates/pages/home.vue';
import News from '~/templates/pages/news.vue';
import Headline from '~/templates/components/headline.vue'
const mapping: Config = {
pages: {
'home': Home,
'news': News,
},
components: {
'block_imageText': CraftNotImplemented,
'block_headline': Headline,
}
};
const route = useRoute()
const uri = route.params.slug.length > 0 ? route.params.slug : '__home__';
const { data, error } = await useCraftQuery('entries').uri(uri).one()
if(error.value) {
console.error(error.value)
}
console.log(data.value)
</script>
<template>
<div>
<CraftPage v-if="data" :config="mapping" :content="data" />
</div>
</template>
This setup should render the correct Nuxt page based on the Craft CMS section handle.
To verify the data structure Craft CMS sends to your page, you can add the following code to inspect the data in home.vue
:
<template>
<h1>Home</h1>
<pre>
{{ $attrs }}
</pre>
</template>
Display Components
To connect Matrix blocks with Vue components, use the <CraftArea/>
component. This component will dynamically render
Vue components based on the content provided from Craft CMS.
Example:
<script setup lang="ts">
const props = defineProps({
metadata: {
type: Object,
required: true,
},
contentBuilder: {
type: Object,
required: true,
},
sectionHandle: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
});
</script>
<template>
<div>
<h1>{{ props.title }}</h1>
<CraftArea v-if="props.contentBuilder" :content="props.contentBuilder" />
</div>
</template>
To find out more about the <CraftArea/>
check out the docs.