Ask your question and get a summary of the document by referencing this page and the AI provider of your choice
If you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Intlayer supports rich text content defined using Markdown syntax. This allows you to easily write and maintain content with rich formatting, such as blogs, articles, and more.
You can declare Markdown content using the md function or simply as a string (if it contains Markdown syntax).
Since version 8.10.0, you can declare Markdown content directly in .content.md files. Intlayer will
automatically detect and parse the Markdown content.
Copy the code to the clipboard
---key: my-markdown-contentdescription: My contentlocale: en---# My contentHere an example of markdown contentThe locale front-matter field is the field that define the locale of the content. It is optional. If not provided, Intlayer will use the default locale, which is also used as fallback locale if no translation is available for a specific locale.
Example of file structure:
Copy the code to the clipboard
content├── markdown-file.en.content.md├── markdown-file.fr.content.md└── markdown-file.es.content.mdYou can add in front-matter any properties defined in the Dictionary definition
Intlayer provides two independent ways to render Markdown:
Via useIntlayer
— Intlayer automatically transforms the md node into the framework's native output (JSX, VNode, HTML string).
.metadata. You can override rendering at two levels — globally with MarkdownProvider (or the framework equivalent) and locally per-node with .use(). Both can be combined; .use() takes priority over MarkdownProvider, which takes priority over the default.Helper utilities — <MarkdownRenderer />, useMarkdownRenderer(), and renderMarkdown() are standalone tools that accept raw Markdown strings only. They are independent of useIntlayer and do not work with the decorated nodes it returns.
Markdown rendering supports MDX — use any JSX/framework component by name directly in your Markdown.
useIntlayer)Markdown nodes can be rendered directly as JSX.
Copy the code to the clipboard
import { useIntlayer } from "react-intlayer";import { MarkdownProvider } from "react-intlayer/markdown";const AppContent = () => { const { myMarkdownContent } = useIntlayer("app"); return <div>{myMarkdownContent}</div>;};const App = () => ( <MarkdownProvider components={{ h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>, MyButton: (props) => <button {...props} />, // MDX component }} > <AppContent /> </MarkdownProvider>);If MarkdownProvider not present, intlayer will render the markdown using the default Markdown to JSX parser.
You can also provide local overrides for specific nodes using the .use() method:
Copy the code to the clipboard
{myMarkdownContent.use({ h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,})}You can retrieve the Markdown as string:
Copy the code to the clipboard
{myMarkdownContent.value}{String(myMarkdownContent)}{myMarkdownContent.toString()}And you can access your markdown metadata like :
Copy the code to the clipboard
{myMarkdownContent.metadata}{myMarkdownContent.metadata.title}These utilities render raw Markdown strings and are independent of useIntlayer. Use them when you need to render Markdown from sources other than your dictionaries.
<MarkdownRenderer /> ComponentRender a Markdown string with specific options.
Copy the code to the clipboard
import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer forceBlock={true} tagfilter={true}> {"# My Title"}</MarkdownRenderer>useMarkdownRenderer() HookGet a pre-configured renderer function.
Copy the code to the clipboard
import { useMarkdownRenderer } from "react-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({ forceBlock: true, components: { h1: (props) => <h1 {...props} className="custom" /> }});return renderMarkdown("# My Title");renderMarkdown() UtilityStandalone utility for rendering outside of components.
Copy the code to the clipboard
import { renderMarkdown } from "react-intlayer/markdown";const jsx = renderMarkdown("# My Title", { forceBlock: true });MarkdownProviderMarkdownProvider (or its framework equivalent) configures the Markdown rendering pipeline for your entire application. It applies to both the automatic useIntlayer rendering and the helper utilities. Options set here are the defaults — .use() overrides them at the node level.
Copy the code to the clipboard
import { MarkdownProvider } from "react-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider components={{ h1: (props) => <h1 style={{color: 'green'}} {...props} />, a: ({ href, ...props }) => <a style={{color: 'red'}} {...props} />, MyCustomJSXComponent: (props) => <span style={{color: 'red'}} {...props} />, }} > {children} </MarkdownProvider>);MDX is supported — any component name used inside your Markdown (e.g.<MyCustomJSXComponent />) is resolved against thecomponentsmap.
You can also use your own markdown renderer:
Copy the code to the clipboard
import { MarkdownProvider } from "react-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider renderMarkdown={async (md) => { // Use dynamic import to reduce the bundle size of your application const { renderMarkdown } = await import('react-intlayer/markdown'); return renderMarkdown(md); }} > {children} </MarkdownProvider>);Importing your Markdown renderer dynamically is a good way to reduce the bundle size of your application.
The Intlayer Markdown renderer is dynamically loaded. Although optimized, the underlying parser chunk is approximately 55kb. Loading this synchronously delays the initial page rendering and degrades First Contentful Paint (FCP).
To prevent blocking the UI, Intlayer integrates with React's Suspense API. It fetches the parser in the background and throws a Promise during the download.
Wrap any component rendering Intlayer Markdown in a <Suspense> boundary. This displays a localized fallback state while the chunk downloads, allowing the rest of your DOM to render immediately.
Warning: If you do not provide a <Suspense> boundary, React will suspend at the root level or block the entire component tree from rendering until the 55kb chunk is fully loaded.
In Next.js App Router, you can use either React Suspense for client components or a loading.tsx file for server components.
Client Component:
Copy the code to the clipboard
"use client";import { useIntlayer } from "next-intlayer";import { Suspense } from "react";const MyComponent = () => {const markdownContent = useIntlayer("my-markdown");return ( <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>);};Server Component with loading.tsx:
Copy the code to the clipboard
export default function Loading() {return <div>Loading...</div>;}Copy the code to the clipboard
import { useIntlayer } from "next-intlayer/server";const MyPage = () => {const markdownContent = useIntlayer("my-markdown");return <div>{markdownContent}</div>;};export default MyPage;In comparison of other Markdown parser such as remark / rehype, the Intlayer Markdown is dependency free and run on client as server side.
But Intlayer optimized the parsing for Server-Side Rendering (SSR) frameworks (such as Next.js App Router, React Router, Nuxt, SvelteKit, etc.).
Instead of sending raw Markdown strings to the client and parsing them on the browser (which incurs a performance penalty), Intlayer allows you to pre-parse the Markdown into an Abstract Syntax Tree (AST) on the server.
You can use the parseMarkdown function from your framework's Intlayer package on the server side to generate a serializable AST (ParsedMarkdown object), and pass it directly to the frontend. All Intlayer rendering utilities (like <MarkdownRenderer>, useMarkdownRenderer, etc.) automatically accept this AST object and render it seamlessly.
Copy the code to the clipboard
import { parseMarkdown } from "react-intlayer/markdown";// 1. On the server: Parse the markdown into a serializable ASTexport const loader = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Return the AST as JSON to the client return Response.json({ content: ast });};Copy the code to the clipboard
import { useLoaderData } from "react-router";import { MarkdownRenderer } from "react-intlayer/markdown";// 2. On the client: Render the AST directly without re-parsingexport default function Page() { const { content } = useLoaderData(); // The renderer accepts either a raw string or the parsed AST return <MarkdownRenderer content={content} />;}This pattern ensures that the Markdown parsing logic is executed entirely on the server, significantly reducing the client-side execution time and improving the initial hydration speed.
These options can be passed to MarkdownProvider, MarkdownRenderer, useMarkdownRenderer, and renderMarkdown.
Open the table in a modal to view all data content clearly
| Option | Type | Default | Description |
|---|---|---|---|
forceBlock | boolean | false | Forces the output to be wrapped in a block-level element (e.g., <div>). |
forceInline | boolean | false | Forces the output to be wrapped in an inline element (e.g., <span>). |
tagfilter | boolean | true | Enables the GitHub Tag Filter for improved security by stripping dangerous HTML tags. |
preserveFrontmatter | boolean | false | If true, frontmatter at the beginning of the Markdown string will not be stripped. |
components | Overrides | {} | A map of HTML tags to custom components (e.g., { h1: MyHeading }). |
wrapper | Component | null | A custom component to wrap the rendered Markdown. |
renderMarkdown | Function | null | A custom rendering function to completely replace the default Markdown compiler. |