---
title: "JSON RTE Registry"
description: "JSON RTE Registry"
url: "https://www.contentstack.com/docs/developers/sdks/studio-sdk/react/reference/json-rte-registry"
product: "Contentstack"
doc_type: "guide"
audience:
  - developers
  - admins
version: "current"
last_updated: "2026-06-09"
---

# JSON RTE Registry

## JSON RTE Registry

## registerJsonRte

The registerJsonRte method registers custom element types (blocks) and text wrappers (inline marks) for JSON RTE content.

**Use Case:** Extend the default rich-text rendering with branded components, custom formatting, and visual effects.

**Parameters:**

**Name**

**Type**

**Description**

config

IJsonToHtmlOptions

Configuration object for custom JSON RTE rendering.

  

```
import { registerJsonRte } from '@contentstack/studio-react';

registerJsonRte({
  customElementTypes: {
    // Custom block-level elements
    infoBox: (attrs, child, jsonBlock, extraProps) => {
      return `<div class="info-box" style="padding: 1rem; background-color: #e3f2fd; border-left: 4px solid #2196f3;">${child}</div>`;
    },
    callout: (attrs, child, jsonBlock, extraProps) => {
      const type = jsonBlock.attrs?.type || 'info';
      const colors = {
        info: '#e3f2fd',
        warning: '#fff3e0',
        error: '#ffebee',
        success: '#e8f5e9'
      };
      return `<div class="callout callout-${type}" style="padding: 1rem; background-color: ${colors[type]}; border-radius: 4px; margin: 1rem 0;">${child}</div>`;
    }
  },

  customTextWrapper: {
    // Custom inline text formatting
    highlight: (child, value) => {
      return `<span class="highlight" style="background-color: #ffeb3b; padding: 2px 4px;">${child}</span>`;
    },
    color: (child, value) => {
      return `<span class="text-color" style="color: ${value};">${child}</span>`;
    },
    code: (child, value) => {
      return `<code class="inline-code" style="background-color: #f5f5f5; padding: 2px 4px; border-radius: 3px; font-family: monospace;">${child}</code>`;
    }
  },

  allowNonStandardTypes: true
});
```

## Configuration Options

The configuration options let developers control how JSON RTE content is converted to HTML. You can define custom elements, text wrappers, and allow non-standard types to extend rendering behavior.

#### customElementTypes (IJsonToHtmlElementTags)

The customElementTypes option defines the block-level elements you want to support in rich text.

**Function Signature**

**Parameters**

**Name**

**Type**

**Description**

attrs

string

HTML attributes represented as a string.

child

string

The rendered inner HTML content of the element.

jsonBlock

object

The full JSON block object. Use jsonBlock.attrs to access attributes.

extraProps

object (optional)

Additional context props passed from the rendering environment.

```
customElementTypes: {
  // Custom info box component
  infoBox: (attrs, child, jsonBlock) => {
    const title = jsonBlock.attrs?.title || 'Information';
    const icon = jsonBlock.attrs?.icon || 'ℹ️';
    return `
<div class="info-box" style="border: 1px solid #ddd; border-radius: 8px; padding: 1rem; margin: 1rem 0;">
  <div style="display: flex; align-items: center; margin-bottom: 0.5rem;">
    <span style="font-size: 1.2rem; margin-right: 0.5rem;">${icon}</span>
    <strong>${title}</strong>
  </div>
  <div>${child}</div>
</div>
`;
  },

  // Custom quote component
  quote: (attrs, child, jsonBlock) => {
    const author = jsonBlock.attrs?.author || 'Unknown';
    const source = jsonBlock.attrs?.source || '';
    return `
<blockquote class="custom-quote" style="border-left: 4px solid #007bff; padding-left: 1rem; margin: 1rem 0; font-style: italic;">
  <div>${child}</div>
  <footer style="margin-top: 0.5rem; font-size: 0.9rem; color: #666;">
    — ${author}${source ? `, ${source}` : ''}
  </footer>
</blockquote>
`;
  }
}
```

#### customTextWrapper (IJsonToHtmlTextTags)

The customTextWrapper option defines inline text wrappers or marks used for applying formatting and effects to text within JSON RTE content.

**Use Case:** Enables custom styles such as highlights, keyboard inputs, or branded inline elements in rich-text fields.

**Function Signature**

```
(child: any, value: any) => string
```

**Parameters**

**Name**

**Type**

**Description**

child

string

The text content to wrap.

value

any

The attribute value applied to the wrapper (for example, a color code, style, or effect).

**Example**

```
customTextWrapper: {
  // Highlight text with custom colors
  highlight: (child, value) => {
    const colors = {
      yellow: '#ffeb3b',
      green: '#4caf50',
      blue: '#2196f3',
      red: '#f44336'
    };
    const color = colors[value] || value;
    return `<span class="highlight" style="background-color: ${color}; padding: 2px 4px; border-radius: 3px;">${child}</span>`;
  },

  // Custom text styling
  style: (child, value) => {
    const styles = {
      bold: 'font-weight: bold;',
      italic: 'font-style: italic;',
      underline: 'text-decoration: underline;',
      strikethrough: 'text-decoration: line-through;'
    };
    const style = styles[value] || '';
    return `<span style="${style}">${child}</span>`;
  },

  // Custom font sizes
  fontSize: (child, value) => {
    return `<span style="font-size: ${value}px;">${child}</span>`;
  }
}
```

#### allowNonStandardTypes (boolean)

The allowNonStandardTypes option enables the use of non-standard element types in JSON RTE content.

**Use Case:**

*   **Custom Components:** Add branded elements such as info boxes, callouts, or product cards.
*   **Enhanced Text:** Format text with highlights, colors, or special fonts.
*   **Interactive Elements:** Insert interactive components, like buttons or widgets, into rich text.
*   **Brand Consistency:** Ensure rich text content aligns with your design system and styling standards.

  

**Real World Example**

```
import { registerJsonRte } from '@contentstack/studio-react';

// Register custom JSON RTE components for a marketing website
registerJsonRte({
  customElementTypes: {
    // Product showcase within rich text
    productShowcase: (attrs, child, jsonBlock) => {
      const product = jsonBlock.attrs;
      return `
<div class="product-showcase" style="
  border: 2px solid #e0e0e0;
  border-radius: 12px;
  padding: 1.5rem;
  margin: 1.5rem 0;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
">
  <div style="display: flex; align-items: center; gap: 1rem;">
    <img src="${product.image || '/placeholder.jpg'}"
      alt="${product.name || 'Product'}"
      style="width: 80px; height: 80px; border-radius: 8px; object-fit: cover;">
    <div>
      <h4 style="margin: 0 0 0.5rem 0; color: #2c3e50;">${product.name || 'Product Name'}</h4>
      <p style="margin: 0 0 0.5rem 0; color: #7f8c8d;">${product.description || 'Product description'}</p>
      <div style="font-size: 1.25rem; font-weight: bold; color: #e74c3c;">
        $${product.price || '0.00'}
      </div>
    </div>
  </div>
  ${child}
</div>
`;
    },

    // Testimonial block
    testimonial: (attrs, child, jsonBlock) => {
      const testimonial = jsonBlock.attrs;
      return `
<div class="testimonial" style="
  background-color: #f8f9fa;
  border-left: 4px solid #007bff;
  padding: 1.5rem;
  margin: 1.5rem 0;
  border-radius: 0 8px 8px 0;
">
  <div style="font-style: italic; margin-bottom: 1rem; color: #495057;">
    "${child}"
  </div>
  <div style="display: flex; align-items: center; gap: 0.5rem;">
    <img src="${testimonial.avatar || '/default-avatar.jpg'}"
      alt="${testimonial.author || 'Author'}"
      style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;">
    <div>
      <strong style="color: #2c3e50;">${testimonial.author || 'Author Name'}</strong>
      ${testimonial.title ? `<br><span style="color: #6c757d; font-size: 0.9rem;">${testimonial.title}</span>` : ''}
    </div>
  </div>
</div>
`;
    },

    // Code block with syntax highlighting
    codeBlock: (attrs, child, jsonBlock) => {
      const language = jsonBlock.attrs?.language || 'text';
      return `
<div class="code-block" style="
  background-color: #2d3748;
  border-radius: 8px;
  padding: 1rem;
  margin: 1rem 0;
  overflow-x: auto;
">
  <div style="
    color: #e2e8f0;
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
    font-size: 0.9rem;
    line-height: 1.5;
  ">
    <div style="
      color: #a0aec0;
      border-bottom: 1px solid #4a5568;
      padding-bottom: 0.5rem;
      margin-bottom: 1rem;
      font-size: 0.8rem;
      text-transform: uppercase;
      letter-spacing: 0.05em;
    ">
      ${language}
    </div>
    <pre style="margin: 0; white-space: pre-wrap;">${child}</pre>
  </div>
</div>
`;
    }
  },

  customTextWrapper: {
    // Brand colors for text
    brandColor: (child, value) => {
      const brandColors = {
        primary: '#007bff',
        secondary: '#6c757d',
        success: '#28a745',
        danger: '#dc3545',
        warning: '#ffc107',
        info: '#17a2b8'
      };
      const color = brandColors[value] || value;
      return `<span style="color: ${color}; font-weight: 500;">${child}</span>`;
    },

    // Custom text effects
    textEffect: (child, value) => {
      const effects = {
        glow: 'text-shadow: 0 0 10px currentColor;',
        shadow: 'text-shadow: 2px 2px 4px rgba(0,0,0,0.3);',
        outline: 'text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;'
      };
      const effect = effects[value] || '';
      return `<span style="${effect}">${child}</span>`;
    }
  },

  allowNonStandardTypes: true
});
```

## Conditional Props

Conditional props are component props whose values depend on the values of other props. They enable components to change behavior or configuration dynamically, based on user selections or predefined logic.

**Use Case:** Show or modify a prop’s value only when another related prop meets a certain condition — for example, displaying a "link URL" field only when "link enabled" is set to true.

**Example**

```
props: {
  showAdvanced: {
    type: "boolean",
    displayName: "Show Advanced Options",
    defaultValue: false
  },
  advancedConfig: {
    type: "object",
    displayName: "Advanced Configuration",
    defaultValue: {},
    // This prop will only be shown when showAdvanced is true
    // (handled automatically by the Studio)
  }
}
```

## Binding Support

Binding Support allows all component props to connect to external data sources using data binding.

**Use Case:** Dynamically populate component values  such as text, images, or links  by binding them to CMS entries, API responses, or environment variables within Studio.

## Styles Configuration

The styles object defines the styling options available for your component, enabling customization of its visual appearance.

**Example**

```
styles: {
  // Default style group
  default: {
    styleSections: ["size", "spacing", "background", "border"],
    defaultClasses: ["my-component", "rounded"],
    defaultStyles: { padding: "1rem" },
    displayName: "Default Styles"
  },

  // Custom style group
  custom: {
    styleSections: ["typography", "transform"],
    defaultClasses: ["custom-text"],
    defaultStyles: { fontSize: "16px" },
    displayName: "Custom Styles"
  }
}
```

  

**Available Style Sections**

**Section**

**Description**

class

Custom CSS classes.

size

Width, height, min/max dimensions.

spacing

Margin and padding.

position

Position and z-index.

visibility

Display and opacity.

layout

Flexbox and grid properties.

typography

Font properties and text alignment.

transform

Transform properties.

media

Media query styles.

background

Background properties.

shadow

Box and text shadow.

effect

Filter and backdrop-filter.

overflow

Overflow properties.

border

Border properties.

responsive

Responsive design utilities.

  

**Style Section Categories**

**Category**

**Description**

block

All block-level styling options.

text

Typography-focused styling options.

## Registry Options

The registerComponents configuration object controls built-in component availability, user overrides, and debug logging behavior.

#### allowedBuiltInComponents

The allowedBuiltInComponents option controls the built-in components available in the registry.

**Type:** boolean | string\[\]

**Values:**

*   true: Enable all built-ins (default)
*   false: Disable all built-ins
*   string\[\]: Enable only specific built-in types

#### overrideDefaultComponents

The overrideDefaultComponents option determines if user components override built-in components with the same type identifier.

**Type:** boolean

**Values:**

*   false: Prevent overriding built-ins (default)
*   true: Allow user components to override

#### debug

The debug option enables debug logging for troubleshooting during component registration.

**Type:** boolean

**Values:**

*   false: Disable logging (default)
*   true: Enable logging

#### Usage Example

```
// Basic component registration
registerComponents([
  {
    type: "hero-section",
    component: HeroSection,
    displayName: "Hero Section",
    description: "A prominent section for main content",
    sections: ["Custom Components"]
  }
]);

// Advanced component with full configuration
registerComponents([
  {
    type: "product-card",
    component: ProductCard,
    displayName: "Product Card",
    description: "Display product information in a card format",
    sections: ["Custom Components", "E-commerce"],
    wrap: false,
    thumbnailUrl: "/images/product-card-thumbnail.png",
    hideFromContentCreators: false,
    hideFromComponentList: false,
    props: {
      productId: {
        type: "string",
        displayName: "Product ID",
        placeholder: "Enter product ID"
      },
      showPrice: {
        type: "boolean",
        displayName: "Show Price",
        defaultValue: true
      }
    },
    styles: {
      default: {
        styleSections: ["size", "spacing", "background", "border"],
        defaultClasses: ["product-card"],
        displayName: "Card Styles"
      },
      content: {
        styleSections: ["typography"],
        defaultClasses: ["product-content"],
        displayName: "Content Styles"
      }
    }
  }
]);

// Component with validation
registerComponents([
  {
    type: "contact-form",
    component: ContactForm,
    displayName: "Contact Form",
    description: "A form for collecting contact information",
    sections: ["Forms"],
    props: {
      email: {
        type: "string",
        displayName: "Email",
        placeholder: "Enter email address"
      }
    }
  }
]);
```

## registerComponents

The registerComponents method makes custom React components available in Studio. Once registered, these components can be added, configured, and styled by content creators within the Studio interface alongside built-in components.

**Returns**

Type void

**Parameters**

**Name**

**Type**

**Description**

componentConfig (required)

Component configuration object

One or more component configurations to register.

options

Optional registry configuration

Controls built-ins, overrides, and debugging.

**Example**

```
import { registerComponents } from '@contentstack/studio-react';

registerComponents(componentConfig, options);
```

## Best Practices

*   **Performance:** Keep custom element renders lightweight and avoid complex DOM manipulation.
*   **Accessibility:** Use semantic HTML and include appropriate ARIA attributes to ensure custom elements are usable with assistive technologies.
*   **Responsiveness:** Apply CSS and layout techniques that adapt well across devices.
*   **Consistency:** Align custom elements with your design system to maintain a cohesive appearance across content.
*   **Testing:** Validate custom elements with varied content scenarios, edge cases, and real-world usage to ensure stability and reliability.

**Note:**

*   **Unique type:** Each component requires a unique identifier.
*   **System protection:** Built-in components cannot be overridden.
*   **Validation:** Props can include custom validation rules.
*   **Styling:** Components have access to design tokens and CSS-in-JS.
*   **Interactivity:** Use useHiddenElementNotification with wrap: false for interactive components.
*   **Performance:** Components are registered once and cached for efficiency.