Take advantage of this exclusive deal and launch your professional website today.
Karamjot Singh
September 13, 2024
Integrate Contentful with your website using JavaScript to dynamically fetch and render blog posts. Learn how to set up Contentful, create a client, handle rich text content, and display blog posts.
In the modern web development landscape, integrating a Content Management System (CMS) with your website can greatly enhance content management and scalability. Contentful, a popular headless CMS, provides a flexible API that allows developers to manage content effortlessly. In this blog post, we’ll explore how to integrate Contentful with your website using JavaScript, enabling you to fetch and render blog posts dynamically.
We’ll walk through:
Before you start, ensure that you have the following:
In your space, create a Content Type called Blog Post with the following fields:
Create an Author content type with a Name field.
master
), and Content Delivery API - access token.We’ll use the Contentful JavaScript SDK to interact with the Contentful API.
npm install contentful
// contentful.js
import { createClient } from 'contentful';
const client = createClient({
space: 'YOUR_SPACE_ID',
accessToken: 'YOUR_ACCESS_TOKEN',
environment: 'master', // or your specific environment ID
});
export default client;
Replace ‘YOUR_SPACE_ID’ and ‘YOUR_ACCESS_TOKEN’ with your actual credentials.
// contentful.js
// Fetch all blog posts
export async function getBlogPosts() {
try {
const entries = await client.getEntries({
content_type: 'blogPost', // Use the Content Type ID
order: '-fields.publishedDate', // Order posts by published date
include: 10, // Include linked entries/assets up to 10 levels deep
});
return entries.items.map((item) => item.fields);
} catch (error) {
console.error('Error fetching blog posts:', error);
return [];
}
}
import { getBlogPosts } from './contentful.js';
(async () => {
const blogPosts = await getBlogPosts();
console.log(blogPosts);
})();
// contentful.js
// Fetch a single blog post by slug
export async function getSinglePost(slug) {
try {
const entries = await client.getEntries({
content_type: 'blogPost',
'fields.slug': slug,
include: 10, // Include related entries/assets
});
if (entries.items.length > 0) {
const entry = entries.items[0];
return {
entry: entry.fields,
includes: entries.includes || {}, // Related assets/entries
};
}
return null;
} catch (error) {
console.error(`Error fetching blog post with slug "${slug}":`, error);
return null;
}
}
import { getSinglePost } from './contentful.js';
(async () => {
const slug = 'your-blog-post-slug';
const post = await getSinglePost(slug);
console.log(post);
})();
npm install @contentful/rich-text-html-renderer
import { BLOCKS, INLINES } from '@contentful/rich-text-types';
import { documentToHtmlString } from '@contentful/rich-text-html-renderer';
export default function richTextOptions(assets, entries) {
const assetMap = new Map();
assets?.forEach((asset) => {
assetMap.set(asset.sys.id, asset);
});
const entryMap = new Map();
entries?.forEach((entry) => {
entryMap.set(entry.sys.id, entry);
});
return {
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: (node) => {
const asset = assetMap.get(node.data.target.sys.id);
if (asset) {
const { url, fileName } = asset.fields.file;
const alt = asset.fields.description || asset.fields.title || fileName;
return `<img src="https:${url}" alt="${alt}" />`;
}
return '';
},
[INLINES.EMBEDDED_ENTRY]: (node) => {
const entry = entryMap.get(node.data.target.sys.id);
if (entry && entry.sys.contentType.sys.id === 'blogPost') {
return `<a href="/blog/${entry.fields.slug}">${entry.fields.title}</a>`;
}
return '';
},
},
};
}
import { getSinglePost } from './contentful.js';
import { renderRichTextContent } from './richTextOptions.js';
app.get('/blog/:slug', async (req, res) => {
const { slug } = req.params;
const data = await getSinglePost(slug);
if (!data) {
res.status(404).send('Blog post not found');
return;
}
const { entry, includes } = data;
const contentHtml = renderRichTextContent(entry.content, includes);
res.render('blogPost', {
title: entry.title,
contentHtml,
featuredImage: entry.featuredImage,
});
});
Integrating Contentful with JavaScript enables dynamic content management, helping you build scalable and maintainable websites. Key steps include setting up the CMS, fetching content, and rendering it dynamically on your site.