{post.fields.title}
By {post.fields.author.fields.name}
{documentToReactComponents(post.fields.body)}---
name: contentful
description: Manages content with Contentful headless CMS and Content Delivery API. Use when building content-driven applications with structured content models, CDN delivery, and enterprise content management.
---
# Contentful CMS
Enterprise headless CMS with Content Delivery API, global CDN, and powerful content modeling. Separate content from presentation for any frontend.
## Quick Start
```bash
npm install contentful
```
```typescript
import { createClient } from 'contentful';
const client = createClient({
space: 'your_space_id',
accessToken: 'your_access_token', // Delivery API token
});
// Fetch entries
const entries = await client.getEntries();
console.log(entries.items);
```
## API Types
| API | Purpose | Token Type |
|-----|---------|------------|
| Content Delivery | Published content | Delivery token |
| Content Preview | Draft content | Preview token |
| Content Management | Create/update content | Management token |
```typescript
// Preview API client
const previewClient = createClient({
space: 'your_space_id',
accessToken: 'preview_access_token',
host: 'preview.contentful.com'
});
```
## Fetching Entries
### Get All Entries
```typescript
const entries = await client.getEntries();
entries.items.forEach((entry) => {
console.log(entry.fields);
});
```
### Filter by Content Type
```typescript
const posts = await client.getEntries({
content_type: 'blogPost'
});
```
### Get Single Entry
```typescript
const entry = await client.getEntry('entry_id');
console.log(entry.fields.title);
```
### Query Parameters
```typescript
const posts = await client.getEntries({
content_type: 'blogPost',
// Field equality
'fields.slug': 'hello-world',
// Comparison operators
'fields.publishDate[lte]': new Date().toISOString(),
'fields.rating[gt]': 4,
// Text search
'fields.title[match]': 'javascript',
// Existence
'fields.featuredImage[exists]': true,
// Array contains
'fields.tags[in]': 'react,typescript',
// Ordering
order: '-fields.publishDate', // desc
order: 'fields.title', // asc
// Pagination
skip: 0,
limit: 10,
// Locale
locale: 'en-US',
// Include linked entries (depth 1-10)
include: 2,
// Select specific fields
select: 'fields.title,fields.slug,fields.author'
});
```
### Search Operators
```typescript
// [ne] - Not equal
'fields.status[ne]': 'draft'
// [in] - In array
'fields.category[in]': 'tech,design,business'
// [nin] - Not in array
'fields.category[nin]': 'archive'
// [exists] - Field exists
'fields.image[exists]': true
// [lt], [lte], [gt], [gte] - Comparisons
'fields.price[gte]': 100,
'fields.price[lte]': 500
// [match] - Full-text search
'fields.body[match]': 'react hooks'
// [near] - Location proximity
'fields.location[near]': '40.7128,-74.0060'
// [within] - Location within bounding box
'fields.location[within]': '40.7,-74.1,40.8,-74.0'
```
## Linked Entries (References)
```typescript
// Include linked entries (default: 1)
const posts = await client.getEntries({
content_type: 'blogPost',
include: 3 // Follow 3 levels of references
});
// Access linked author
posts.items.forEach((post) => {
// Linked entries are resolved automatically
const author = post.fields.author;
console.log(author.fields.name);
});
```
## Assets (Images & Files)
```typescript
// Get all assets
const assets = await client.getAssets();
// Get single asset
const asset = await client.getAsset('asset_id');
console.log(asset.fields.title);
console.log(asset.fields.file.url); // URL (add https:)
// Image transformations via URL
const imageUrl = `https:${asset.fields.file.url}?w=800&h=600&fit=fill`;
```
### Image API Parameters
```typescript
const url = `https:${image.fields.file.url}`;
// Resize
`${url}?w=800&h=600`
// Fit modes
`${url}?fit=pad` // Add padding
`${url}?fit=fill` // Resize to fit
`${url}?fit=scale` // Scale proportionally
`${url}?fit=crop` // Crop to size
`${url}?fit=thumb` // Thumbnail
// Focus area (for crop)
`${url}?f=face` // Focus on face
`${url}?f=faces` // Focus on faces
`${url}?f=center` // Center focus
// Format
`${url}?fm=webp` // WebP
`${url}?fm=jpg` // JPEG
`${url}?fm=png` // PNG
// Quality (1-100)
`${url}?q=80`
// Combined
`${url}?w=400&h=300&fit=fill&fm=webp&q=80`
```
## Sync API
Keep local content in sync with delta updates.
```typescript
// Initial sync
const response = await client.sync({
initial: true
});
// Store these
const { entries, assets, nextSyncToken } = response;
// Later: Get only changes
const deltaResponse = await client.sync({
nextSyncToken: storedNextSyncToken
});
// Contains only changed/deleted items
const { entries, deletedEntries, assets, deletedAssets } = deltaResponse;
```
## Rich Text Rendering
```bash
npm install @contentful/rich-text-react-renderer @contentful/rich-text-types
```
```tsx
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
import { BLOCKS, INLINES } from '@contentful/rich-text-types';
const options = {
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: (node) => {
const { file, title } = node.data.target.fields;
return ;
},
[BLOCKS.EMBEDDED_ENTRY]: (node) => {
const entry = node.data.target;
// Render embedded entry
return
By {post.fields.author.fields.name}
{documentToReactComponents(post.fields.body)}