Author:
    Creation:2026-01-20Last update:2026-03-24

    HTML Content / HTML in Intlayer

    Intlayer supports HTML content, allowing you to embed rich, structured content within your dictionaries. This content can be rendered with standard HTML tags or replaced with custom components at runtime.

    Declaring HTML Content

    You can declare HTML content using the html function or simply as a string.

    Use the html function to explicitly declare HTML content. This ensures standard tags are mapped correctly even if automatic detection is disabled.

    htmlDictionary.content.ts
    import { html, type Dictionary } from "intlayer";
    
    const htmlDictionary = {
    key: "app",
    contentAutoTransformation: true, // can be set in config file
    content: {
      myHtmlContent:  html("<p>Hello <strong>World</strong></p>"),
    },
    } satisfies Dictionary;
    
    export default htmlDictionary;
    

    If the string contains common HTML tags (e.g., <p>, <div>, <strong>, etc.), Intlayer will automatically transform it.

    htmlDictionary.content.ts
    export default {
    key: "app",
    contentAutoTransformation: true, // can be set in config file
    content: {
      myHtmlContent: "<p>Hello <strong>World</strong></p>",
    },
    };
    

    Import HTML content from files. Note that currently file() function returns a string, which will be auto-detected as HTML if it contains tags.

    htmlDictionary.content.ts
    import { html, file, t } from "intlayer";
    
    export default {
    key: "app",
    content: {
      content: t({
        en: html(file("./content.en.html")),
        fr: html(file("./content.fr.html")),
      }),
    },
    };
    

    The html() Node

    The html() function is a new feature in Intlayer v8 that allows you to explicitly define HTML content in your dictionaries. While Intlayer can often auto-detect HTML content, using the html() function provides several advantages:

    • Type Safety: The html() function allows you to define the expected props for custom components, providing better autocompletion and type checking in your editor.
    • Explicit Declaration: It ensures that a string is always treated as HTML, even if it doesn't contain standard HTML tags that would trigger auto-detection.
    • Custom Component Definition: You can pass a second argument to html() to define the custom components and their expected prop types.
    typescript
    import { html } from "intlayer";
    
    const myContent = html(
      "<MyCustomComponent title='Hello'>World</MyCustomComponent>",
      {
        MyCustomComponent: {
          title: "string",
          children: "node",
        },
      }
    );
    

    When using the .use() method on an HTML node, the components you provide will be checked against the definition provided in the html() function (if available).


    Rendering HTML

    Rendering can be handled automatically by Intlayer's content system or manually using specialized tools.

    Automatic Rendering (using useIntlayer)

    When you access content via useIntlayer, HTML nodes are already prepared for rendering.

    HTML nodes can be rendered directly as JSX. Standard tags work automatically.

    App.tsx
    import { useIntlayer } from "react-intlayer";
    
    const AppContent = () => {
    const { myHtmlContent } = useIntlayer("app");
    return <div>{myHtmlContent}</div>;
    };
    

    Use the .use() method to provide custom components or override tags:

    tsx
    {myHtmlContent.use({
    p: (props) => <p className="prose" {...props} />,
    CustomLink: ({ children }) => <a href="/details">{children}</a>,
    })}
    

    In Vue, HTML content can be rendered using the component built-in.

    App.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    const { myHtmlContent } = useIntlayer("app");
    </script>
    
    <template>
    <component :is="myHtmlContent" />
    </template>
    

    Use .use() for overrides:

    vue
    <component :is="myHtmlContent.use({ h1: 'h2' })" />
    

    Svelte renders HTML nodes as strings. Use {@html} to render it.

    svelte
    <script lang="ts">
    import { useIntlayer } from "svelte-intlayer";
    const content = useIntlayer("app");
    </script>
    
    {@html $content.myHtmlContent}
    

    Preact supports HTML nodes directly in the JSX.

    App.tsx
    import { useIntlayer } from "preact-intlayer";
    
    const AppContent = () => {
    const { myHtmlContent } = useIntlayer("app");
    return <div>{myHtmlContent}</div>;
    };
    

    Solid supports HTML nodes directly in the JSX.

    App.tsx
    import { useIntlayer } from "solid-intlayer";
    
    const AppContent = () => {
    const { myHtmlContent } = useIntlayer("app");
    return <div>{myHtmlContent}</div>;
    };
    

    Angular uses the [innerHTML] directive to render HTML content.

    app.component.ts
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
    selector: "app-root",
    template: `<div [innerHTML]="content().myHtmlContent"></div>`,
    })
    export class AppComponent {
    content = useIntlayer("app");
    }
    

    Use the .use() method to provide custom components or override tags:

    typescript
    content().myHtmlContent.use({
    p: { class: "prose" },
    CustomLink: { href: "/details" },
    })
    

    Global Configuration with HTMLProvider

    You can configure HTML rendering globally for your entire application. This is ideal for defining custom components that should be available in all HTML content.

    AppProvider.tsx
    import { HTMLProvider } from "react-intlayer/html";
    
    export const AppProvider = ({ children }) => (
    <HTMLProvider
      components={{
        p: (props) => <p className="prose" {...props} />,
        CustomLink: ({ children }) => <a href="/details">{children}</a>,
      }}
    >
      {children}
    </HTMLProvider>
    );
    

    You can also use your own HTML renderer:

    AppProvider.tsx
    import { HTMLProvider } from "react-intlayer/html";
    
    export const AppProvider = ({ children }) => (
    <HTMLProvider
      renderHTML={async (html) => {
        const { renderHTML } = await import('react-intlayer/html');
        return renderHTML(html);
      }}
    >
      {children}
    </HTMLProvider>
    );
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.
    main.ts
    import { createApp, h } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerHTML } from "vue-intlayer/html";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerHTML, {
    components: {
      p: (props, { slots }) => h("p", { class: "prose", ...props }, slots.default?.()),
      CustomLink: (props, { slots }) => h("a", { href: "/details", ...props }, slots.default?.()),
    },
    });
    
    app.mount("#app");
    

    You can also use your own HTML renderer:

    main.ts
    import { createApp, h } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerHTML } from "vue-intlayer/html";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerHTML, {
    renderHTML: async (html) => {
      const { renderHTML } = await import('vue-intlayer/html');
      return renderHTML(html);
    },
    });
    
    app.mount("#app");
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.
    App.svelte
    <script lang="ts">
    import { HTMLProvider } from "svelte-intlayer/html";
    import MyCustomP from "./MyCustomP.svelte";
    </script>
    
    <HTMLProvider
    components={{
      p: MyCustomP,
    }}
    >
    <slot />
    </HTMLProvider>
    

    You can also use your own HTML renderer:

    App.svelte
    <script lang="ts">
    import { HTMLProvider } from "svelte-intlayer/html";
    </script>
    
    <HTMLProvider
    renderHTML={async (html) => {
      const { renderHTML } = await import('svelte-intlayer/html');
      return renderHTML(html);
    }}
    >
    <slot />
    </HTMLProvider>
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.
    AppProvider.tsx
    import { HTMLProvider } from "preact-intlayer/html";
    
    export const AppProvider = ({ children }) => (
    <HTMLProvider
      components={{
        p: (props) => <p className="prose" {...props} />,
      }}
    >
      {children}
    </HTMLProvider>
    );
    

    You can also use your own HTML renderer:

    AppProvider.tsx
    import { HTMLProvider } from "preact-intlayer/html";
    
    export const AppProvider = ({ children }) => (
    <HTMLProvider
      renderHTML={async (html) => {
        const { renderHTML } = await import('preact-intlayer/html');
        return renderHTML(html);
      }}
    >
      {children}
    </HTMLProvider>
    );
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.
    AppProvider.tsx
    import { HTMLProvider } from "solid-intlayer/html";
    
    export const AppProvider = (props) => (
    <HTMLProvider
      components={{
        p: (props) => <p className="prose" {...props} />,
      }}
    >
      {props.children}
    </HTMLProvider>
    );
    

    You can also use your own HTML renderer:

    AppProvider.tsx
    import { HTMLProvider } from "solid-intlayer/html";
    
    export const AppProvider = (props) => (
    <HTMLProvider
      renderHTML={async (html) => {
        const { renderHTML } = await import('solid-intlayer/html');
        return renderHTML(html);
      }}
    >
      {props.children}
    </HTMLProvider>
    );
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.
    app.config.ts
    import { createIntlayerHTMLProvider } from "angular-intlayer/html";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerHTMLProvider({
        components: {
          p: { class: "prose" },
          CustomLink: { href: "/details" },
        },
      }),
    ],
    };
    

    You can also use your own HTML renderer:

    app.config.ts
    import { createIntlayerHTMLProvider } from "angular-intlayer/html";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerHTMLProvider({
        renderHTML: async (html) => {
          const { renderHTML } = await import('angular-intlayer/html');
          return renderHTML(html);
        },
      }),
    ],
    };
    
    Importing your HTML renderer dynamically is a good way to reduce the bundle size of your application.

    Manual Rendering & Advanced Tools

    If you need to render raw HTML strings or have more control over the component mapping, use the following tools.

    <HTMLRenderer /> Component

    Render an HTML string with specific components.

    tsx
    import { HTMLRenderer } from "react-intlayer/html";
    
    <HTMLRenderer components={{ p: MyCustomP }}>
    {"<p>Hello World</p>"}
    </HTMLRenderer>
    

    useHTMLRenderer() Hook

    Get a pre-configured renderer function.

    tsx
    import { useHTMLRenderer } from "react-intlayer/html";
    
    const renderHTML = useHTMLRenderer({
    components: { strong: (props) => <strong {...props} className="text-red-500" /> }
    });
    
    return renderHTML("<p>Hello <strong>World</strong></p>");
    

    renderHTML() Utility

    Standalone utility for rendering outside of components.

    tsx
    import { renderHTML } from "react-intlayer/html";
    
    const jsx = renderHTML("<p>Hello</p>", { components: { p: 'div' } });
    

    <HTMLRenderer /> Component

    vue
    <script setup>
    import { HTMLRenderer } from "vue-intlayer/html";
    </script>
    
    <template>
    <HTMLRenderer content="<p>Hello World</p>" />
    </template>
    

    <HTMLRenderer /> Component

    svelte
    <script lang="ts">
    import { HTMLRenderer } from "svelte-intlayer/html";
    </script>
    
    <HTMLRenderer value="<p>Hello World</p>" />
    

    useHTMLRenderer() Hook

    svelte
    <script lang="ts">
    import { useHTMLRenderer } from "svelte-intlayer/html";
    const render = useHTMLRenderer();
    </script>
    
    {@html render("<p>Hello World</p>")}
    

    renderHTML() Utility

    svelte
    <script lang="ts">
    import { renderHTML } from "svelte-intlayer/html";
    </script>
    
    {@html renderHTML("<p>Hello World</p>")}
    

    <HTMLRenderer /> Component

    tsx
    import { HTMLRenderer } from "preact-intlayer/html";
    
    <HTMLRenderer>
    {"<p>Hello World</p>"}
    </HTMLRenderer>
    

    useHTMLRenderer() Hook

    tsx
    import { useHTMLRenderer } from "preact-intlayer/html";
    
    const render = useHTMLRenderer();
    
    return <div>{render("<p>Hello World</p>")}</div>;
    

    renderHTML() Utility

    tsx
    import { renderHTML } from "preact-intlayer/html";
    
    return <div>{renderHTML("<p>Hello World</p>")}</div>;
    

    <HTMLRenderer /> Component

    tsx
    import { HTMLRenderer } from "solid-intlayer/html";
    
    <HTMLRenderer>
    {"<p>Hello World</p>"}
    </HTMLRenderer>
    

    useHTMLRenderer() Hook

    tsx
    import { useHTMLRenderer } from "solid-intlayer/html";
    
    const render = useHTMLRenderer();
    
    return <div>{render("<p>Hello World</p>")}</div>;
    

    renderHTML() Utility

    tsx
    import { renderHTML } from "solid-intlayer/html";
    
    return <div>{renderHTML("<p>Hello World</p>")}</div>;
    

    IntlayerHTMLService Service

    Render an HTML string using the service.

    typescript
    import { IntlayerHTMLService } from "angular-intlayer/html";
    
    export class MyComponent {
    constructor(private markdownService: IntlayerHTMLService) {}
    
    renderHTML(html: string) {
      return this.markdownService.renderHTML(html);
    }
    }
    

    Options Reference

    These options can be passed to HTMLProvider, HTMLRenderer, useHTMLRenderer, and renderHTML.

    Option Type Default Description
    components Record<string, any> {} A map of HTML tags or custom component names to components.
    renderHTML Function null A custom rendering function to completely replace the default HTML parser (Only for Vue/Svelte providers).
    Note: For React and Preact, standard HTML tags are automatically provided. You only need to pass the components prop if you want to override them or add custom components.