Custom Dictionary Text Parsing in Sitecore XM Cloud

A lightweight utility for rendering formatted and dynamic Sitecore dictionary text in Next.js projects.

May 30, 2025

By Sohrab Saboori

Formatting Dictionary Items in Sitecore XM Cloud Headless with a Custom Dictionary Text Parser

Sitecore XM Cloud is powerful for multilingual and personalized experiences, but when it comes to formatting localized dictionary items, it falls short out of the box. In this post, you’ll learn how to use a custom React parser that adds support for <b> tags, newline rendering, and dynamic placeholders. This approach is safe, scalable, and easily extendable for additional HTML or markdown-style formatting.

Why You Need This

Sitecore dictionary items are designed for simple text localization. However, modern UX often demands:

  • Bold emphasis
  • Multi-line messages
  • Dynamic variables (like dates, names, values)
  • Clean, safe React rendering without using dangerouslySetInnerHTML

What We’ll Build

We’ll create a custom dictionary text parser designed to be reusable across Sitecore XM Cloud projects. It is intended to parse and render dictionary items that include:

A custom parser with:

  • <b> tag parsing
  • \n newline rendering as <p> or <span>
  • {placeholder} replacements with dynamic values
  • Easily extendable pattern for supporting other tags (<i>, <u>, etc.)

The Code: Custom Text Parser

The full code is now maintained in a single, easy-to-import file: dictionaryParser.tsx Below is the complete code for quick reference or direct copy-paste into your project:

import React, { ReactNode } from "react";

/**
 * Parses bold tags in a line of text
 * @param line - The line to parse
 * @returns Array of React elements with bold formatting
 */
const parseBoldTags = (line: string): ReactNode[] => {
  return line.split(/(<b>.*?<\/b>)/).map((part, j) => {
    if (part.startsWith("<b>") && part.endsWith("</b>")) {
      const boldText = part.slice(3, -4);
      return <b key={j}>{boldText}</b>;
    }
    return part;
  });
};

/**
 * Parses text containing newlines and bold tags into React elements
 * @param text - The text to parse
 * @param tag - The HTML tag to wrap each line in ('p' or 'span')
 * @returns Array of React elements with proper formatting
 */
export const parseFormattedText = (
  text: string,
  tag: "p" | "span" = "p"
): ReactNode[] => {
  const Tag = tag; // Capitalize for JSX
  return text
    .split("\n")
    .map((line, i) => <Tag key={i}>{parseBoldTags(line)}</Tag>);
};

/**
 * Replaces placeholders in text with provided values
 * @param text - The text containing placeholders
 * @param replacements - Object containing placeholder keys and their replacement values
 * @returns Text with placeholders replaced
 */
export const replacePlaceholders = (
  text: string,
  replacements: Record<string, string>
): string => {
  let result = text;
  Object.entries(replacements).forEach(([key, value]) => {
    result = result.replace(`{${key}}`, value);
  });
  return result;
};

This utility:

  • Parses <b> tags into React <b> elements
  • Handles newlines (\n) by wrapping each line in a specified tag (like <p>)
  • Supports placeholder replacement using {key} syntax
  • Is written in TypeScript for full type safety

What Each Function Does

parseBoldTags

Takes a string and finds segments wrapped in <b> and returns them as React <b> elements, preserving other parts of the string as plain text.

parseFormattedText

Splits the input string by newlines \n and wraps each resulting line in a tag (<p> or <span>), then passes each line through parseBoldTags to format any <b> tags.

replacePlaceholders

Searches for {placeholder} keys in the string and replaces them with the corresponding values provided in a key-value object, allowing dynamic content like dates or names to be injected safely.

You can import everything from this one file in your project.

import {
  parseFormattedText,
  replacePlaceholders
} from '@/utils/dictionaryParser';

Example Usage in Sitecore XM Cloud

Dictionary item:

You’re outside your period <b>{startDate}</b> to <b>{endDate}</b>.

Component usage:

<div className="text-sm p-3">
  {parseFormattedText(
    replacePlaceholders(translations.outsidePeriod, {
      startDate: now(),
      endDate: addDays(now(), 2)
    }),
    'p'
  )}
</div>

Extending This Parser

This parser is designed to be easily extendable. You can add support for additional tags beyond <b> by expanding the tag parsing logic. Here's an example of how to support <i> and <u> tags using a more general parser function:

Support <i> and <u> Tags

const parseCustomTags = (line: string): ReactNode[] => {
  return line.split(/(<\/?[a-z]+>.*?<\/[a-z]+>)/).map((part, i) => {
    if (part.match(/^<b>.*<\/b>$/)) {
      return <b key={i}>{part.slice(3, -4)}</b>;
    }
    if (part.match(/^<i>.*<\/i>$/)) {
      return <i key={i}>{part.slice(3, -4)}</i>;
    }
    if (part.match(/^<u>.*<\/u>$/)) {
      return <u key={i}>{part.slice(3, -4)}</u>;
    }
    return part;
  });
};

Best Practices and Gotchas

Do Don’t
Use consistent tag structure Forget closing tags like </b>
Always sanitize dynamic data Use dangerouslySetInnerHTML
Wrap each line with semantic tags Hard-code HTML into dictionary values

Integration with Sitecore Dictionary Hook

We retrieve and update dictionary values using a custom hook with useEffect to support dynamic values in the client-rendered app, as described in this blog post.

const t = useDictionary();
const message = t.outsidePeriod;

const content = parseFormattedText(
  replacePlaceholders(message, {
    startDate: now(),
    endDate: addDays(now(), 2),
  })
);

Future Ideas

  • Support markdown-like syntax (*bold**, _italic_)
  • Create a reusable hook like useParsedText(key, replacements)
  • Add unit tests for parsing logic
  • Build a visual formatter in Sitecore editing UI

How to Use This in Your Project

You can use the parser by copying just one file: dictionaryParser.tsx from the official repository.

# Suggested folder structure
src/
  utils/
    dictionaryParser.tsx

Then import and use it directly in your components:

import {
  parseFormattedText,
  replacePlaceholders
} from '@/utils/dictionaryParser';

👉 View on GitHub

Final Thoughts on Sitecore Dictionary Parser

This parser is intentionally lightweight — the parsing logic is fast and has negligible impact on render performance, even when used frequently in client-rendered dictionary content. It does not rely on any heavy parsing libraries or runtime DOM manipulation.

This approach allows you to get the most out of Sitecore dictionary items while keeping your codebase clean and maintainable. By supporting rich formatting, dynamic placeholders, and extensibility in a single utility file, you can dramatically improve the flexibility and user experience of your localized content in Sitecore XM Cloud.

Whether you're building a small POC or a scalable enterprise app, this lightweight parser bridges the gap between Sitecore's backend content management and your React-based frontend rendering.

Have ideas to improve it or want to contribute? Fork the project or submit a pull request on GitHub!

Photo of Fishtank employee Sohrab Saboori

Sohrab Saboori

Senior Full-Stack Developer

Sohrab is a Senior Front-End Developer with extensive experience in React, Next.js, JavaScript, and TypeScript. Sohrab is committed to delivering outstanding digital solutions that not only meet but exceed clients' expectations. His expertise in building scalable and efficient web applications, responsive websites, and e-commerce platforms is unparalleled. Sohrab has a keen eye for detail and a passion for creating seamless user experiences. He is a problem-solver at heart and enjoys working with clients to find innovative solutions to their digital needs. When he's not coding, you can find him lifting weights at the gym, pounding the pavement on the run, exploring the great outdoors, or trying new restaurants and cuisines. Sohrab believes in a healthy and balanced lifestyle and finds that these activities help fuel his creativity and problem-solving skills.