Content Client SDK

Deprecated

ContentClient is deprecated. It is replaced by EntryDeliveryClient, EntryManagementClient, and ContentTypeClient. See content API clients for the current clients and a migration guide.

The Content Client (ContentClient from @uniformdev/canvas) provides programmatic access to headless content entries stored in Uniform. Use it for server-side data fetching, search indexing, custom API routes, or any scenario where you need to query content outside of the standard composition rendering pipeline.

note

Within the App Router SDK's composition rendering flow, content is resolved automatically. The Content Client is for use cases where you need to access content directly -- such as building sitemaps, search indexes, custom API endpoints, or fetching content that isn't part of a composition.


The Content Client is part of the @uniformdev/canvas package:

npm install @uniformdev/canvas
import { ContentClient } from "@uniformdev/canvas"; const contentClient = new ContentClient({ apiKey: process.env.UNIFORM_API_KEY, apiHost: process.env.UNIFORM_CLI_BASE_URL || "https://uniform.global", projectId: process.env.UNIFORM_PROJECT_ID, });

The App Router SDK does not provide a pre-configured Content Client factory; initialize the client directly as shown above. For composition access, the App Router SDK provides a pre-configured Canvas Client.


const response = await contentClient.getEntries({ type: "blogPost", }); // response.entries is an array of content entries for (const entry of response.entries) { console.log(entry.entry.name, entry.entry.fields); }
const response = await contentClient.getEntries({ type: "blogPost", limit: 20, offset: 0, }); console.log(`Total entries: ${response.totalCount}`);

getEntries accepts filters, search, orderBy, and select with the same syntax as the current entry clients:

const response = await contentClient.getEntries({ filters: { "type[eq]": "brand", "fields.brandName[match]": "adidas", }, });

For the filter syntax, operators, supported field types, and sorting, see search and filter. For the select option, see data projection.


A common use case for the Content Client is building a search index. Here is a pattern that retrieves all compositions via the project map and the Route Client, then extracts text content for indexing:

import { RouteClient } from "@uniformdev/canvas"; import { ProjectMapClient } from "@uniformdev/project-map"; const projectMapClient = new ProjectMapClient({ apiKey: process.env.UNIFORM_API_KEY, projectId: process.env.UNIFORM_PROJECT_ID, }); const routeClient = new RouteClient({ apiKey: process.env.UNIFORM_API_KEY, projectId: process.env.UNIFORM_PROJECT_ID, edgeApiHost: "https://uniform.global", }); async function buildSearchIndex() { // 1. Get all project map nodes with compositions const { nodes } = await projectMapClient.getNodes({ projectMapId: "your-project-map-id", }); const compositionNodes = (nodes ?? []).filter((node) => node.compositionId); // 2. Fetch each composition and extract text const indexData = await Promise.all( compositionNodes.map(async (node) => { const route = await routeClient.get({ path: node.path, projectMapId: "your-project-map-id", state: 0, // published state }); if (route.type !== "composition") return null; const { composition } = route.compositionApiResponse; const title = composition.parameters?.pageTitle?.value as string; return { path: node.path, title, compositionId: node.compositionId, }; }) ); return indexData.filter(Boolean); }

note

For large sites, consider running index rebuilds outside the Next.js build process to avoid build timeout limits. You can trigger rebuilds via a webhook when content is published.


ExportPackageDescription
ContentClient@uniformdev/canvasClient for fetching content entries
CanvasClient@uniformdev/canvasClient for fetching compositions
RouteClient@uniformdev/canvasClient for route resolution
ProjectionSpec@uniformdev/canvasType for the select data projection option