npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@commercetools-demo/contentools-content-item-renderer

v1.1.5

Published

Content item renderer

Readme

Content Item Renderer

A React component for dynamically rendering content items based on their content types in the CMS system. Supports both direct content item rendering and fetching content items by key.

Installation

npm install @commercetools-demo/contentools-content-item-renderer

Prerequisites

⚠️ Important: This component can work with or without a StateProvider. If no StateProvider is present and a baseURL is provided, it will automatically wrap itself in a StateProvider.

import { StateProvider } from '@commercetools-demo/contentools-state';
import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';

// Option 1: With StateProvider (recommended for multiple components)
function App() {
  return (
    <StateProvider baseURL="https://your-cms-api.com">
      <ContentItemRenderer component={contentItem} />
    </StateProvider>
  );
}

// Option 2: Standalone usage (automatically creates StateProvider)
function App() {
  return (
    <ContentItemRenderer 
      itemKey="hero-banner-key" 
      baseURL="https://your-cms-api.com" 
    />
  );
}

Usage

Basic Usage with Content Item Object

import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';
import { StateProvider } from '@commercetools-demo/contentools-state';

const MyApp = () => {
  const contentItem = {
    id: 'content-item-id',
    type: 'hero-banner',
    properties: {
      title: 'Welcome to our site',
      subtitle: 'Discover amazing products'
    }
  };

  return (
    <StateProvider baseURL="https://your-cms-api.com">
      <ContentItemRenderer 
        component={contentItem}
        locale="en-US"
        className="my-custom-class"
      />
    </StateProvider>
  );
};

Usage with Item Key (Fetch from CMS)

import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';

const MyApp = () => {
  return (
    <ContentItemRenderer 
      itemKey="hero-banner-homepage"
      baseURL="https://your-cms-api.com"
      businessUnitKey="my-business-unit"
      locale="en-US"
      className="my-custom-class"
    />
  );
};

Usage with Draft Content

import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';

const MyApp = () => {
  return (
    <ContentItemRenderer 
      itemKey="hero-banner-homepage"
      isDraft={true}
      baseURL="https://your-cms-api.com"
      businessUnitKey="my-business-unit"
    />
  );
};

With Error Handling

import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';
import { StateProvider } from '@commercetools-demo/contentools-state';

const MyApp = () => {
  const handleError = (error: Error) => {
    console.error('Content item rendering failed:', error);
    // Handle error (e.g., send to error reporting service)
  };

  return (
    <StateProvider baseURL="https://your-cms-api.com">
      <ContentItemRenderer 
        component={contentItem}
        onError={handleError}
        style={{ marginBottom: '20px' }}
      />
    </StateProvider>
  );
};

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | component | ContentItem | ⚠️ | - | The content item to render (required if itemKey not provided) | | itemKey | string | ⚠️ | - | The key of the content item to fetch and render (required if component not provided) | | isDraft | boolean | ❌ | false | Whether to fetch the draft version of the content item (only applies when using itemKey) | | baseURL | string | ❌ | '' | Base URL for API calls (required if no StateProvider) | | businessUnitKey | string | ❌ | - | The business unit key for fetching content items (only applies when using itemKey) | | locale | string | ❌ | 'en-US' | Locale for rendering | | className | string | ❌ | - | Additional CSS class name | | style | React.CSSProperties | ❌ | - | Additional inline styles | | loading | boolean | ❌ | false | Show loading state | | error | string \| null | ❌ | null | Custom error message | | onError | (error: Error) => void | ❌ | - | Callback when component fails to render |

⚠️ Note: Either component OR itemKey must be provided, but not both.

ContentItem Type

interface ContentItem {
  id: string;
  type: string; // Content type identifier
  properties: Record<string, any>; // Properties passed to the rendered component
}

How It Works

Direct Component Rendering

  1. Content Type Resolution: The renderer fetches the content type definition using the type field from the content item
  2. Dynamic Loading: It dynamically loads and transpiles the React component code associated with the content type
  3. Component Rendering: The loaded component is rendered with the properties from the content item passed as props

Content Item Fetching (itemKey)

  1. Content Item Fetching: The renderer fetches the content item from the CMS using the provided itemKey
  2. Draft/Published Selection: Based on the isDraft prop, fetches either draft or published version
  3. Content Type Resolution: Once the content item is fetched, proceeds with the same steps as direct rendering
  4. Component Rendering: The loaded component is rendered with the fetched content item properties

Error Handling

  • Loading States: Shows loading indicators while fetching content items or component code
  • Content Item Not Found: Displays appropriate error when itemKey doesn't exist
  • Component Not Found: Shows error when content type component cannot be loaded
  • Runtime Errors: Handles React component errors during rendering
  • Error Boundary: Catches and displays errors with helpful debugging information

Error States

The component handles various error scenarios:

  • Validation Errors: Shows error when neither component nor itemKey is provided
  • Content Item Fetch Errors: Displays detailed error when content item cannot be fetched by itemKey
  • Loading States: Shows loading indicators while fetching content items or component code
  • Component Not Found: Displays error when content type component cannot be loaded
  • Runtime Errors: Shows detailed error messages with component/item information
  • Error Boundary: Catches and handles React component errors during rendering

StateProvider Integration

The ContentItemRenderer automatically handles StateProvider requirements:

import { StateProvider } from '@commercetools-demo/contentools-state';
import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';

// ✅ Option 1: With existing StateProvider (recommended for multiple CMS components)
<StateProvider baseURL="https://your-cms-api.com">
  <ContentItemRenderer component={contentItem} />
  <ContentItemRenderer itemKey="another-item" />
</StateProvider>

// ✅ Option 2: Standalone usage (automatically creates StateProvider)
<ContentItemRenderer 
  itemKey="hero-banner" 
  baseURL="https://your-cms-api.com" 
/>

// ✅ Option 3: Mixed usage (inherits existing StateProvider or creates new one)
<StateProvider baseURL="https://your-cms-api.com">
  <ContentItemRenderer component={contentItem} />
  <ContentItemRenderer 
    itemKey="different-item" 
    baseURL="https://different-api.com" 
  />
</StateProvider>

API Endpoints Used

When using itemKey, the component makes API calls to:

  • Published Content Items: GET {baseURL}/{businessUnitKey}/published/content-items/{itemKey}
  • Draft Content Items: GET {baseURL}/{businessUnitKey}/content-items/{itemKey} (when isDraft=true)
  • Content Types: GET {baseURL}/content-types/{contentTypeKey}

Dependencies

  • @commercetools-demo/contentools-state - For state management and API calls
  • @commercetools-demo/contentools-types - For TypeScript type definitions
  • react - React library (peer dependency)

Browser Compatibility

This component uses modern JavaScript features and requires:

  • ES2018+ support
  • React 19.0.0 or higher
  • Modern bundler with dynamic import support

Migration from ComponentRenderer

If you're migrating from the previous ComponentRenderer:

// Old usage
import { ComponentRenderer } from '@commercetools-demo/contentools-content-item-renderer';

<ComponentRenderer component={contentItem} />

// New usage (backward compatible)
import { ContentItemRenderer } from '@commercetools-demo/contentools-content-item-renderer';

<ContentItemRenderer component={contentItem} />

// Or use the new itemKey functionality
<ContentItemRenderer itemKey="my-content-key" baseURL="..." />

The ContentItemRenderer is fully backward compatible with ComponentRenderer usage patterns.