Contentful
Contentful is a cloud-hosted headless CMS trusted by enterprise teams. Define content models in the web app, let editors manage content, and fetch everything via API in your Astro site.
Last updated: 2026-03-29
Setup
Create a Contentful space and define your content model. Contentful provides a generous free tier with 25K records and 2 locales.
# .env
CONTENTFUL_SPACE_ID=your-space-id
CONTENTFUL_ACCESS_TOKEN=your-delivery-api-token
CONTENTFUL_PREVIEW_TOKEN=your-preview-api-tokenInstall & Configure
Use the official Contentful JavaScript SDK to fetch entries. It handles pagination, link resolution, and asset URLs automatically.
# Install the SDK
npm install contentful
# src/lib/contentful.js
import { createClient } from 'contentful';
const client = createClient({
space: import.meta.env.CONTENTFUL_SPACE_ID,
accessToken: import.meta.env.CONTENTFUL_ACCESS_TOKEN,
});
export async function getPosts() {
const entries = await client.getEntries({
content_type: 'blogPost',
order: ['-fields.publishedDate'],
});
return entries.items;
}
export async function getPostBySlug(slug) {
const entries = await client.getEntries({
content_type: 'blogPost',
'fields.slug': slug,
limit: 1,
});
return entries.items[0];
}Render in Astro
Fetch Contentful entries in Astro frontmatter. Use the rich text renderer to convert Contentful's structured content to HTML.
---
// src/pages/blog/index.astro
import { getPosts } from '../../lib/contentful';
const posts = await getPosts();
---
{posts.map((post) => (
<article>
<img src={post.fields.heroImage?.fields.file.url} alt={post.fields.title} />
<h2>{post.fields.title}</h2>
<p>{post.fields.excerpt}</p>
</article>
))}
<!-- For rich text rendering -->
<!-- npm install @contentful/rich-text-html-renderer -->
<!-- import { documentToHtmlString } from '@contentful/rich-text-html-renderer'; -->Best Practices
Contentful excels at structured content. Use content models to enforce consistency across your team.