Connect a Website to the CMS API
The CMS API lets your website fetch and render published content from Profound CMS. You can use it to power documentation pages, marketing pages, blogs, help centers, or any other content-driven experience.
The typical integration has three parts:
To connect your application to the CMS, provide your CMS API URL, website ID, and API key.
const cmsConfig = {
cmsUrl: 'https://cms.dev.tryprofoun.com',
websiteId: 'your-website-id',
apiKey: process.env.PROFOUND_API_KEY,
};
Use environment variables for values that change between environments:
NEXT_PUBLIC_CMS_API_URL=https://cms.dev.tryprofound.com
NEXT_PUBLIC_WEBSITE_ID=your-website-id
PROFOUND_API_KEY=your-api-key
Do not expose private API keys in client-side code. API keys should be used on your server, in your build process, or in your backend routes.
Content in the CMS is organized by schema. For example, your project may have schemas such as post, category, page, or section.
Use the schema name to fetch content:
const posts = await cms.schema('post').fetchAll();
To fetch a single document by ID:
const post = await cms.schema('post').fetchSingleById('document-id');
To fetch localized content, request the translated version of the schema:
const frenchPost = await cms
.schema('post')
.translation('fr')
.fetchSingleById('document-id');
For websites that use CMS-managed pages, you can fetch content based on the current URL path.
const route = await cms.route.getByPath({
websiteId: 'your-website-id',
path: '/docs/getting-started',
});
The route response identifies the page and the blocks to render. Your application can then fetch the blocks and render them with your own components.
const blocks = await cms.block.getByIds({
websiteId: 'your-website-id',
ids: route.blockIds,
});
async function getDocsPage(path: string) {
const route = await cms.route.getByPath({
websiteId: process.env.WEBSITE_ID,
path,
});
const blocks = await cms.block.getByIds({
websiteId: process.env.WEBSITE_ID,
ids: route.blockIds,
});
return {
title: route.label,
path: route.path,
blocks,
};
}
You can use the returned blocks to render the page using your application’s component system.
Published CMS content is safe to cache. For most websites, cache API responses for a short period and revalidate them when content changes.
A common setup is:
const content = await cache(
() => cms.schema('post').fetchAll(),
{
revalidate: 60,
tags: ['cms-posts'],
}
);
Recommended cache behavior:
Preview mode lets editors see unpublished changes before they are published.
A common pattern is to use a separate preview route, for example:
/docs/getting-started
/cms-preview/docs/getting-started
Production pages should fetch only published content. Preview pages can accept preview parameters, such as:
?edit_mode=true
Preview routes should usually be dynamic and should not be statically cached.
CMS content may be unavailable during a build or request. Your application should handle this gracefully.
Recommended behavior:
404 when a route does not exist.async function getPost(id: string) {
try {
return await cms.schema('post').fetchSingleById(id);
} catch (error) {
console.error('Failed to fetch CMS post', error);
return null;
}
}
Keep API keys private and use them only on the server. Do not include private credentials in browser bundles or public JavaScript.
Use public environment variables only for non-sensitive values such as:
Use private environment variables for:
Use the CMS API when your website needs to fetch structured content, render CMS-managed routes, or support editor preview workflows.
A standard integration should: