Getting Started
Quick Start
Get started quickly with Nuxt Contentstack using these practical examples covering basic usage, live preview, and modular blocks.
Get up and running quickly with Nuxt Contentstack! This guide provides practical examples you can copy and adapt for your project.
Basic Example
The simplest way to fetch and display content from Contentstack:
pages/index.vue
<script lang="ts" setup>
import type { Page } from "../../types";
const { data: page } = await useGetEntryByUrl<Page>({
contentTypeUid: "page",
url: "/",
});
</script>
<template>
<main>
<h1>{{ page?.title }}</h1>
<p>{{ page?.description }}</p>
<NuxtImg
:src="page?.image?.url"
:alt="page?.image?.title"
provider="contentstack"
/>
</main>
</template>
With Live Preview
Enable real-time content editing by adding Live Preview attributes:
pages/index.vue
<script lang="ts" setup>
import type { Page } from "../../types";
type PageProps = Omit<Page, "$"> & {
cslp?: Page["$"];
};
const { data: page } = await useGetEntryByUrl<PageProps>({
contentTypeUid: "page",
url: "/",
});
</script>
<template>
<main>
<h1 v-bind="page?.cslp && page.cslp.title">{{ page?.title }}</h1>
<p v-bind="page?.cslp && page.cslp.description">{{ page?.description }}</p>
<NuxtImg
v-bind="page?.image?.cslp && page?.image?.cslp.url"
:src="page?.image?.url"
:alt="page?.image?.title"
provider="contentstack"
/>
</main>
</template>
Live Preview setup
This example:
- Includes CSLP (Contentstack Live Preview) attributes for editable fields
- Allows content editors to edit content directly on the page
- Requires Live Preview to be enabled in your configuration
Live Preview: Make sure you've configured Live Preview in your
nuxt.config.ts and are using the preview environment. See the Live Preview guide for full setup instructions.Modular Blocks with Composable
Build dynamic pages using modular blocks by fetching content first:
pages/index.vue
<script lang="ts" setup>
import type { Page } from "../../types";
import BlockItem from "./BlockItem.vue";
const componentMap = {
block: BlockItem,
};
const { data: page } = await useGetEntryByUrl<Page>({
contentTypeUid: "page",
url: "/",
});
</script>
<template>
<main>
<ContentstackModularBlocks
:component-map="componentMap"
:blocks="page?.blocks"
/>
</main>
</template>
Benefits of this approach
- Full control: Fetch and transform data before rendering
- Custom logic: Add computed properties or data transformations
- Conditional rendering: Easily add logic before rendering blocks
Modular Blocks with Auto-fetch
Let the component handle fetching automatically for simpler code:
pages/index.vue
<script lang="ts" setup>
import BlockItem from "./BlockItem.vue";
const componentMap = {
block: BlockItem,
};
</script>
<template>
<main>
<ContentstackModularBlocks
:component-map="componentMap"
blocks-field-path="blocks"
content-type-uid="page"
url="/"
/>
</main>
</template>
When to use auto-fetch
- Simpler pages: When you don't need custom data processing
- Rapid prototyping: Get up and running quickly
- Standard layouts: Common page structures that don't need extra logic
- SEO pages: The component automatically handles SEO metadata
Auto-fetch: The
ContentstackModularBlocks component can fetch entry data automatically when you provide content-type-uid and url props. See the Components guide for all available options.Creating Block Components
For the modular blocks examples above, create block components that match your Contentstack content types:
components/BlockItem.vue
<script lang="ts" setup>
interface Props {
title: string;
description?: string;
image?: {
url: string;
title: string;
};
}
defineProps<Props>();
</script>
<template>
<section class="block-item">
<h2>{{ title }}</h2>
<p v-if="description">{{ description }}</p>
<NuxtImg
v-if="image"
:src="image.url"
:alt="image.title"
provider="contentstack"
/>
</section>
</template>
Next Steps
Now that you have the basics down, explore more advanced features: