- Published on
Integrating Contentful with Vite and Vue 3
- Authors
- Name
- Federico Orlandau
- @fedeorlandau

Motivation
The last Jamstack Community Survey positioned Contentful as one of the favorite CMS for developers. Unlike other CMS, Contentful provides a Community License to work on personal sites, hackathons, or philanthropic projects.
Table of Contents
Getting started
Today, we're going to build a small website with Vue 3 and integrating it with Contentful. The idea is to model a component in Contentful and render it with Vue 3.
Setting up your Vite project
npm init vite@latest
Follow the instructions. Please name your project and select vue
as a framework.
Finally, go into the new folder, install the dependencies and run the solution.
npm install
npm run dev
This will serve a new website on localhost:3000
with the following default view.

Modeling a component in Contentful
For this example, we're going to create a Hero content-type in Contentful.
Hero
content-type ID: hero
- Title, short text. This will be entry title.
- Field ID:
title
- Field ID:
- Description, short text.
- Field ID:
description
- Field ID:
- CTA Text, short text.
- Field ID:
ctaText
- Field ID:
- CTA Link, short text.
- Field ID:
ctaLink
- Field ID:
Your Contentful model should look like this:

Creating an entry
Now that we have our Hero content-type created we need to create at least one entry for that model. Just fill in the inputs and publish the entry on the CMS.

Installing the Contentful SDK into the project
Contentful provides a JS SDK to fetch information from the CMS. You can find it in their GitHub
Let's install the dependency.
npm install contentful
Now, create a new file called contentful.js
in src/
import * as contentful from 'contentful'
const client = contentful.createClient({
space: "YOUR_SPACE",
accessToken: "YOUR_ACCESS_TOKEN"
});
export default client
Remember to replace YOUR_SPACE
AND YOUR_ACCESS_TOKEN
with your Contentful keys.
Building our first component
On the src/components
folder create a new file called Hero.vue
<script setup>
import client from "../contentful";
const res = await client.getEntries({ content_type: "hero" });
const item = res.items[0];
const hero = {
title: item.fields.title,
description: item.fields.description,
ctaLink: item.fields.ctaLink,
ctaText: item.fields.ctaText,
};
</script>
<template>
<div>
<h1>{{ hero.title }}</h1>
<h2>{{ hero.description }}</h2>
<a :href="hero.ctaLink">{{ hero.ctaText }}</a>
</div>
</template>
This component will use Contentful's client to fetch the entries with the hero
content-type.
Now it's time to place this component into the App.vue
<script setup>
import Hero from "./components/Hero.vue";
</script>
<template>
<Suspense>
<Hero />
</Suspense>
</template>
An this is how it looks on the browser:

Congratulations! Now you're serving your Contentful entries with Vue 3. You can find the working example with Tailwind CSS here
