🚀 Socket Launch Week Day 4:Socket MCP Adds Org Alerts, Threat Feed Review, and Package Inspection.Learn more
Sign In

@universal-data-layer/plugin-source-contentful

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@universal-data-layer/plugin-source-contentful

Contentful source plugin for Universal Data Layer

latest
npmnpm
Version
2.0.0
Version published
Weekly downloads
28
40%
Maintainers
1
Weekly downloads
 
Created
Source

@universal-data-layer/plugin-source-contentful

Contentful source plugin for Universal Data Layer. Automatically sources all content types, entries, and assets from a Contentful space.

Installation

npm install @universal-data-layer/plugin-source-contentful

Configuration

Add the plugin to your UDL configuration:

// udl.config.ts
import { defineConfig } from 'universal-data-layer';

export const config = defineConfig({
  plugins: [
    {
      name: '@universal-data-layer/plugin-source-contentful',
      options: {
        spaceId: process.env['CONTENTFUL_SPACE_ID'],
        accessToken: process.env['CONTENTFUL_ACCESS_TOKEN'],
      },
    },
  ],
});

Options

OptionTypeDefaultDescription
spaceIdstringrequiredYour Contentful space ID
accessTokenstringrequiredContentful Delivery API access token
localestring'en-US'Locale to extract from field values
hoststring'cdn.contentful.com'API host. Use 'preview.contentful.com' for draft content
environmentstring'master'Contentful environment
nodePrefixstring'Contentful'Prefix for generated node type names
downloadAssetsbooleanfalseWhether to download assets locally (not yet implemented)
contentTypeFilter(ct: ContentType) => boolean-Filter which content types to source
useNameForIdbooleantrueUse content type name (vs ID) for node type names
forceFullSyncbooleanfalseForce full sync, ignoring stored sync token
syncTokenStorageSyncTokenStoragefile-basedCustom storage for sync tokens

Generated Node Types

The plugin generates node types based on your Contentful content types:

  • Entries: {nodePrefix}{ContentTypeName} (e.g., ContentfulBlogPost, ContentfulAuthor)
  • Assets: {nodePrefix}Asset (e.g., ContentfulAsset)

Each node includes:

  • contentfulId - Original Contentful sys.id (indexed for lookups)
  • sys - Contentful system metadata (createdAt, updatedAt, revision, etc.)
  • All content type fields with transformed values

Sync API

The plugin uses Contentful's Sync API for efficient incremental updates:

  • Initial sync: Fetches all entries and assets
  • Delta sync: Only fetches changes since the last sync

Sync tokens are stored in .udl/cache/contentful-sync-tokens.json by default. You can provide custom storage:

{
  name: '@universal-data-layer/plugin-source-contentful',
  options: {
    spaceId: '...',
    accessToken: '...',
    locale: 'en-US',
    syncTokenStorage: {
      async getSyncToken(key) {
        // Return stored token or null
      },
      async setSyncToken(key, token) {
        // Store the token
      },
      async clearSyncToken(key) {
        // Clear the token (optional)
      },
    },
  },
}

Preview Mode

To fetch draft/unpublished content, use the Preview API:

{
  name: '@universal-data-layer/plugin-source-contentful',
  options: {
    spaceId: process.env['CONTENTFUL_SPACE_ID'],
    accessToken: process.env['CONTENTFUL_PREVIEW_TOKEN'],
    locale: 'en-US',
    host: 'preview.contentful.com',
  },
}

Multiple Spaces

Use nodePrefix to source from multiple Contentful spaces:

export const config = defineConfig({
  plugins: [
    {
      name: '@universal-data-layer/plugin-source-contentful',
      options: {
        spaceId: process.env['CMS_SPACE_ID'],
        accessToken: process.env['CMS_ACCESS_TOKEN'],
        locale: 'en-US',
        nodePrefix: 'CMS',
      },
    },
    {
      name: '@universal-data-layer/plugin-source-contentful',
      options: {
        spaceId: process.env['CRM_SPACE_ID'],
        accessToken: process.env['CRM_ACCESS_TOKEN'],
        locale: 'en-US',
        nodePrefix: 'CRM',
      },
    },
  ],
});

This generates separate node types: CMSBlogPost, CRMCustomer, etc.

Content Type Filtering

Filter which content types to source:

{
  name: '@universal-data-layer/plugin-source-contentful',
  options: {
    spaceId: '...',
    accessToken: '...',
    locale: 'en-US',
    contentTypeFilter: (contentType) => {
      // Only source 'blogPost' and 'author' content types
      return ['blogPost', 'author'].includes(contentType.sys.id);
    },
  },
}

References

Linked entries and assets are stored as references with their Contentful ID:

{
  _contentfulRef: true,
  contentfulId: 'abc123',
  linkType: 'Entry' | 'Asset',
}

Use the contentfulId index to resolve references at query time.

Rich Text

Rich text fields are stored with the raw JSON structure and extracted references:

{
  raw: { /* Contentful rich text document */ },
  references: [
    { _contentfulRef: true, contentfulId: '...', linkType: 'Entry' },
    { _contentfulRef: true, contentfulId: '...', linkType: 'Asset' },
  ],
}

Error Handling

The plugin exports error classes for specific error handling:

import {
  ContentfulConfigError,
  ContentfulApiError,
  ContentfulSyncError,
  isRateLimitError,
  isAuthError,
} from '@universal-data-layer/plugin-source-contentful';

try {
  // ...
} catch (error) {
  if (isRateLimitError(error)) {
    // Handle rate limiting
  }
  if (isAuthError(error)) {
    // Handle authentication errors
  }
}

License

MIT

FAQs

Package last updated on 23 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts