Using Markdown syntax
Format text content with lightweight markup.
Markdown is a lightweight markup language that lets you add formatting to plain text using a simple syntax. You can use it to style headings, bold text, links, lists, and other rich text elements without directly using HTML or CSS.
To give content editors more flexibility when creating and managing content, you can support markdown in text attributes by using a Markdown parser in your application and rendering the formatted output in your components.
Below are some general best practices and considerations when working with markdown content.
Markdown parser
Text attributes store plain text, so your application needs to convert the markdown syntax into HTML or UI elements to render it properly.
One option is to use this lightweight parser, which supports a minimal subset of the markdown syntax, such as bold, italic, and links, making it ideal for short texts like titles, subtitles, and descriptions.
Installation
To install it, run the command:
npm install @croct/md-liteUsage
Suppose a description attribute contains the following markdown:
**Save 20%** on your [first order](https://example.com/offers)Because the attribute stores a plain string, the markdown syntax would show up as-is. To display it as formatted content, use the render function to convert each markdown element into HTML or UI elements:
import {render} from '@croct/md-lite';
const html = render(content.description, { fragment: node => node.children.join(''), text: node => node.content, bold: node => `<b>${node.children}</b>`, italic: node => `<i>${node.children}</i>`, strike: node => `<s>${node.children}</s>`, code: node => `<code>${node.content}</code>`, link: node => `<a href="${node.href}">${node.children}</a>`, image: node => `<img src="${node.src}" alt="${node.alt}">`, paragraph: node => `<p>${node.children.join('')}</p>`,});
document.querySelector('.description').innerHTML = html;Best practices
Markdown gives content editors flexibility, but a few practices help keep your content consistent and your code maintainable.
Create a reusable renderer
In most applications, you want the rendered elements to match your design system. A convenient approach is to wrap the render call in a helper that accepts a class name for each markdown element:
import type {ReactNode} from 'react';import {render} from '@croct/md-lite';
export type MarkdownClasses = { bold?: string, italic?: string, strike?: string, code?: string, link?: string, paragraph?: string,};
export function renderMarkdown(content: string, classes: MarkdownClasses = {}): ReactNode { return render<ReactNode>(content, { fragment: node => node.children, text: node => node.content, bold: node => <b key={node.index} className={classes.bold}>{node.children}</b>, italic: node => <i key={node.index} className={classes.italic}>{node.children}</i>, strike: node => <s key={node.index} className={classes.strike}>{node.children}</s>, code: node => <code key={node.index} className={classes.code}>{node.content}</code>, link: node => <a key={node.index} className={classes.link} href={node.href}>{node.children}</a>, image: node => <img key={node.index} src={node.src} alt={node.alt} />, paragraph: node => <p key={node.index} className={classes.paragraph}>{node.children}</p>, });}This helper gives you full control over how each element looks in every context. A common use case is letting content editors emphasize part of a heading. For example, suppose a heading attribute contains the following markdown:
Personalization made **simple**Instead of rendering the emphasized part in bold, you can highlight it with your brand color or a gradient. For example, using Tailwind CSS classes:
import {renderMarkdown} from './markdown';
export function HeroTitle({content}: HeroTitleProps) { return ( <h1 className="text-5xl font-bold"> {renderMarkdown(content.heading, { bold: 'bg-gradient-to-r from-indigo-500 to-purple-500 bg-clip-text text-transparent', })} </h1> );}Keep formatting simple
Use it for simple formatting needs such as:
- **bold text**
- *italicized text*
- [Links](https://example.com\)
- `inline code`
If any part of the content needs validation, consistency, or reuse, prefer dedicated attributes over embedding everything in a markdown field. For example, CTA labels, URLs, or product information are usually better represented as separate attributes.
Specify formatting expectations
If content editors can use markdown, it is important to document which syntax your application supports to avoid inconsistencies and prevent unsupported formatting from appearing broken in the UI.
You can use the attribute descriptions for this, specifying something like “Supports markdown syntax for **bold**, *italic*, and [links](https://example.com\).”