Autore:
    Creazione:2025-02-07Ultimo aggiornamento:2026-09-21

    Markdown / Contenuti Rich Text

    Intlayer supporta contenuti rich text definiti utilizzando la sintassi Markdown. Questo ti permette di scrivere e mantenere facilmente contenuti con formattazione ricca, come blog, articoli e molto altro.

    Dichiarare Contenuti Markdown

    Puoi dichiarare i contenuti Markdown usando la funzione md o semplicemente come stringa (se contiene la sintassi Markdown).

    Dalla versione 8.10.0, puoi dichiarare i contenuti Markdown direttamente nei file .content.md. Intlayer rileverà e analizzerà automaticamente il contenuto Markdown.

    markdown-file.en.content.md
    ---
    key: my-markdown-content
    description: Il mio contenuto
    locale: en
    ---
    
    # Il mio contenuto
    
    Ecco un esempio di contenuto markdown
    

    Il campo front-matter locale è il campo che definisce la lingua del contenuto. È facoltativo. Se non viene fornito, Intlayer utilizzerà la lingua predefinita, che viene anche utilizzata come lingua di fallback se non è disponibile alcuna traduzione per una lingua specifica.

    Esempio di struttura dei file:

    text
    content
    ├── markdown-file.en.content.md
    ├── markdown-file.fr.content.md
    └── markdown-file.es.content.md
    

    Puoi aggiungere nel front-matter qualsiasi proprietà definita nella Definizione del Dizionario

    Usa la funzione md per dichiarare esplicitamente i contenuti Markdown. Questo è utile se vuoi assicurarti che una stringa venga trattata come Markdown anche se non contiene una sintassi evidente.

    markdownDictionary.content.ts
    import { md, type Dictionary } from "intlayer";
    
    const markdownDictionary = {
    key: "app",
    content: {
      myMarkdownContent: md("## Il mio titolo \n\nLorem Ipsum"),
    },
    } satisfies Dictionary;
    
    export default markdownDictionary;
    

    Importa direttamente i file .md usando la funzione file.

    markdownDictionary.content.ts
    import { md, file, t } from "intlayer";
    
    export default {
    key: "app",
    content: {
      content: t({
        en: md(file("./myMarkdown.en.md")),
        it: md(file("./myMarkdown.it.md")),
      }),
    },
    };
    

    Se la stringa contiene indicatori comuni di Markdown (come intestazioni, elenchi, link, ecc.), Intlayer la trasformerà automaticamente.

    markdownDictionary.content.ts
    export default {
    key: "app",
    contentAutoTransformation: true, // Abilita il rilevamento automatico dei contenuti Markdown - Può essere impostato globalmente in intlayer.config.ts
    content: {
      myMarkdownContent: "## Il mio titolo \n\nLorem Ipsum",
    },
    };
    

    Rendering del Markdown

    Intlayer fornisce due modi indipendenti per eseguire il rendering del Markdown:

    1. Tramite useIntlayer — Intlayer trasforma automaticamente il nodo md nell'output nativo del framework (JSX, VNode, stringa HTML).

      • Il Frontmatter viene analizzato ed esposto come .metadata. Puoi sovrascrivere il rendering su due livelli — globalmente con MarkdownProvider (o l'equivalente nel framework) e localmente per nodo con .use(). Entrambi possono essere combinati; .use() ha priorità su MarkdownProvider, il quale ha priorità su quello predefinito.
    2. Utility di supporto<MarkdownRenderer />, useMarkdownRenderer(), e renderMarkdown() sono strumenti indipendenti che accettano solo stringhe Markdown pure. Sono indipendenti da useIntlayer e non funzionano con i nodi decorati che esso restituisce.

    Il rendering del Markdown supporta MDX — usa qualsiasi componente JSX/framework tramite nome direttamente nel tuo Markdown.

    1. Rendering Automatico (tramite useIntlayer)

    I nodi Markdown possono essere renderizzati direttamente come JSX.

    App.tsx
    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} />, // Componente MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Se MarkdownProvider non è presente, Intlayer eseguirà il rendering del markdown usando il parser da Markdown a JSX predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Puoi recuperare il Markdown come stringa:

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    I nodi Markdown possono essere renderizzati direttamente come JSX.

    App.tsx
    import { useIntlayer } from "next-intlayer";
    import { MarkdownProvider } from "next-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} />, // Componente MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Se MarkdownProvider non è presente, Intlayer eseguirà il rendering del markdown usando il parser da Markdown a JSX predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Puoi recuperare il Markdown come stringa:

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    In Vue, il contenuto Markdown può essere renderizzato usando il tag component integrato o direttamente come nodo.

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

    Configura globalmente tramite il plugin intlayerMarkdown (supporta componenti MDX personalizzati):

    main.ts
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    
    app.use(intlayerMarkdown, {
    components: {
      h1: (props) => h('h1', { style: { color: 'green' } }, props.children),
      MyButton: (props) => h('button', props), // Componente MDX
    },
    });
    
    Se il plugin intlayerMarkdown non è installato, Intlayer eseguirà il rendering utilizzando il compilatore predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    vue
    <component :is="myMarkdownContent.use({
    h1: (props) => h('h1', { style: { color: 'red' } }, props.children),
    })" />
    

    Puoi recuperare il Markdown come stringa:

    vue
    {{ myMarkdownContent.value }}
    {{ String(myMarkdownContent) }}
    {{ myMarkdownContent.toString() }}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    vue
    <component :is="myMarkdownContent.metadata" />
    <component :is="myMarkdownContent.metadata.title" />
    

    Svelte renderizza il Markdown come una stringa HTML per impostazione predefinita. Usa {@html} per renderizzarlo.

    App.svelte
    <script lang="ts">
    import { useIntlayer } from "svelte-intlayer";
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    
    const content = useIntlayer("app");
    </script>
    
    <MarkdownProvider components={{ h1: MyHeading }}>
    {@html $content.myMarkdownContent}
    </MarkdownProvider>
    
    Se MarkdownProvider non è presente, Intlayer renderizzerà il markdown usando il compilatore predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    svelte
    {@html $content.myMarkdownContent.use({ ... })}
    

    Puoi recuperare il Markdown come stringa:

    svelte
    {$content.myMarkdownContent.value}
    {String($content.myMarkdownContent)}
    {$content.myMarkdownContent.toString()}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    svelte
    {$content.myMarkdownContent.metadata}
    {$content.myMarkdownContent.metadata.title}
    

    Preact supporta i nodi Markdown direttamente in JSX.

    App.tsx
    import { useIntlayer } from "preact-intlayer";
    import { MarkdownProvider } from "preact-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} />, // Componente MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Se MarkdownProvider non è presente, Intlayer eseguirà il rendering del markdown usando il parser da Markdown a JSX predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Puoi recuperare il Markdown come stringa:

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Solid supporta i nodi Markdown direttamente in JSX.

    App.tsx
    import { useIntlayer } from "solid-intlayer";
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    const AppContent = () => {
    const { myMarkdownContent } = useIntlayer("app");
    return <div>{myMarkdownContent}</div>;
    };
    
    const App = () => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 style={{ color: "red" }}>{props.children}</h1>,
        MyButton: (props) => <button {...props} />, // Componente MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Se MarkdownProvider non è presente, Intlayer eseguirà il rendering del markdown usando il parser da Markdown a JSX predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    tsx
    {myMarkdownContent.use({
    h1: (props) => <h1 style={{ color: "red" }}>{props.children}</h1>,
    })}
    

    Puoi recuperare il Markdown come stringa:

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Angular utilizza la direttiva [innerHTML] per eseguire il rendering del contenuto Markdown.

    app.component.ts
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
    selector: "app-root",
    template: `<div [innerHTML]="content().myMarkdownContent"></div>`,
    })
    export class AppComponent {
    content = useIntlayer("app");
    }
    
    Se il provider IntlayerMarkdown non è configurato, Intlayer eseguirà il rendering utilizzando il compilatore predefinito.

    Puoi anche fornire sovrascritture locali per nodi specifici utilizzando il metodo .use():

    typescript
    content().myMarkdownContent.use({
    h1: { class: "text-3xl font-bold" },
    })
    

    Puoi recuperare il Markdown come stringa:

    typescript
    content().myMarkdownContent.value
    String(content().myMarkdownContent)
    content().myMarkdownContent.toString()
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    typescript
    content().myMarkdownContent.metadata
    content().myMarkdownContent.metadata.title
    

    In Remix 3, i nodi Markdown vengono renderizzati sul server in una stringa HTML. Inseriscila con la prop innerHTML di Remix JSX o con html.raw in una vista html-template.

    src/views/home.tsx
    import { useIntlayer } from "remix-intlayer";
    
    export const HomePage = () => () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return <div innerHTML={myMarkdownContent.value} />;
    };
    
    src/views/home.ts
    import { html } from "remix/html-template";
    import { useIntlayer } from "remix-intlayer";
    
    export const renderHomePage = () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return html.raw`<div>${myMarkdownContent.value}</div>`;
    };
    
    Remix esegue l'escape dei valori interpolati per impostazione predefinita. innerHTML e html.raw sono i due meccanismi di esclusione, che è ciò di cui ha bisogno una stringa Markdown renderizzata.

    Puoi anche fornire override locali per tag specifici utilizzando il metodo .use(). Gli override sono funzioni che restituiscono una stringa HTML:

    tsx
    <div
    innerHTML={myMarkdownContent.use({
      h1: ({ children }) => `<h1 class="text-3xl font-bold">${children}</h1>`,
    })}
    />
    

    .value è la stringa HTML renderizzata, mentre String() / .toString() restituiscono il sorgente Markdown non elaborato:

    tsx
    myMarkdownContent.value // "<h1>…</h1>"
    String(myMarkdownContent) // "# …"
    myMarkdownContent.toString() // "# …"
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    tsx
    myMarkdownContent.metadata
    myMarkdownContent.metadata.title
    

    In Astro, i nodi Markdown vengono renderizzati in una stringa HTML. Inseriscila con la direttiva set:html nel template o con innerHTML in uno <script> client.

    src/pages/index.astro
    ---
    import { useIntlayer } from "astro-intlayer";
    
    const { myMarkdownContent } = useIntlayer("app");
    ---
    
    <div set:html={myMarkdownContent.value} />
    
    src/components/Content.astro
    <div id="content"></div>
    
    <script>
    import { useIntlayer } from "astro-intlayer";
    
    const { myMarkdownContent } = useIntlayer("app");
    
    document.querySelector("#content")!.innerHTML = myMarkdownContent.value;
    </script>
    
    Astro esegue l'escape di {espressioni} per impostazione predefinita. set:html è il meccanismo di esclusione, che è ciò di cui ha bisogno una stringa Markdown renderizzata.

    Puoi anche fornire override locali per tag specifici utilizzando il metodo .use(). Gli override sono funzioni che restituiscono una stringa HTML:

    astro
    <div
    set:html={myMarkdownContent.use({
      h1: ({ children }) => `<h1 class="text-3xl font-bold">${children}</h1>`,
    })}
    />
    

    .value è la stringa HTML renderizzata, mentre String() / .toString() restituiscono il sorgente Markdown non elaborato:

    astro
    myMarkdownContent.value // "<h1>…</h1>"
    String(myMarkdownContent) // "# …"
    myMarkdownContent.toString() // "# …"
    

    E puoi accedere ai metadati del tuo markdown in questo modo:

    astro
    myMarkdownContent.metadata
    myMarkdownContent.metadata.title
    

    2. Utility di Supporto (Solo Stringhe Markdown)

    Queste utility eseguono il rendering solo di stringhe Markdown pure e sono indipendenti da useIntlayer. Usale quando hai bisogno di renderizzare Markdown da fonti diverse dai tuoi dizionari.

    Componente <MarkdownRenderer />

    Esegue il rendering di una stringa Markdown con opzioni specifiche.

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Il Mio Titolo"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Ottieni una funzione di rendering preconfigurata.

    tsx
    import { useMarkdownRenderer } from "react-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({
    forceBlock: true,
    components: { h1: (props) => <h1 {...props} className="custom" /> }
    });
    
    return renderMarkdown("# Il Mio Titolo");
    

    Utility renderMarkdown()

    Utility indipendente per il rendering al di fuori dei componenti.

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";
    
    const jsx = renderMarkdown("# Il Mio Titolo", { forceBlock: true });
    

    Componente <MarkdownRenderer />

    Esegue il rendering di una stringa Markdown con opzioni specifiche.

    tsx
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Il Mio Titolo"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Ottieni una funzione di rendering preconfigurata.

    tsx
    import { useMarkdownRenderer } from "next-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({
    forceBlock: true,
    components: { h1: (props) => <h1 {...props} className="custom" /> }
    });
    
    return renderMarkdown("# Il Mio Titolo");
    

    Utility renderMarkdown()

    Utility indipendente per il rendering al di fuori dei componenti.

    tsx
    import { renderMarkdown } from "next-intlayer/markdown";
    
    const jsx = renderMarkdown("# Il Mio Titolo", { forceBlock: true });
    

    Componente <MarkdownRenderer />

    vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>
    
    <template>
    <MarkdownRenderer :forceBlock="true" content="# Il Mio Titolo" />
    </template>
    

    Componente <MarkdownRenderer />

    svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownRenderer forceBlock={true} value="# Il Mio Titolo" />
    

    Hook useMarkdownRenderer()

    svelte
    <script lang="ts">
    import { useMarkdownRenderer } from "svelte-intlayer/markdown";
    const render = useMarkdownRenderer();
    </script>
    
    {@html render("# Il Mio Titolo")}
    

    Utility renderMarkdown()

    svelte
    <script lang="ts">
    import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>
    
    {@html renderMarkdown("# Il Mio Titolo")}
    

    Componente <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Il Mio Titolo"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Il Mio Titolo")}</div>;
    

    Utility renderMarkdown()

    tsx
    import { renderMarkdown } from "preact-intlayer/markdown";
    
    return <div>{renderMarkdown("# Il Mio Titolo")}</div>;
    

    Componente <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Il Mio Titolo"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Il Mio Titolo")}</div>;
    

    Utility renderMarkdown()

    tsx
    import { renderMarkdown } from "solid-intlayer/markdown";
    
    return <div>{renderMarkdown("# Il Mio Titolo")}</div>;
    

    Servizio IntlayerMarkdownService

    Esegue il rendering di una stringa Markdown utilizzando il servizio.

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

    Hook useMarkdownRenderer()

    Ottieni una funzione di rendering preconfigurata da installIntlayerMarkdown(). Restituisce una stringa HTML.

    tsx
    import { useMarkdownRenderer } from "remix-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({ forceBlock: true });
    
    return <div innerHTML={renderMarkdown("# My Title")} />;
    

    Utility renderMarkdown()

    Utility autonoma che ignora la configurazione globale.

    tsx
    import { renderMarkdown } from "remix-intlayer/markdown";
    
    const html = renderMarkdown("# My Title", { forceBlock: true });
    

    Hook useMarkdownRenderer()

    Ottieni una funzione di rendering preconfigurata da installIntlayerMarkdown(). Restituisce una stringa HTML.

    astro
    ---
    import { useMarkdownRenderer } from "astro-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({ forceBlock: true });
    ---
    
    <div set:html={renderMarkdown("# My Title")} />
    

    Utility renderMarkdown()

    Utility autonoma che ignora la configurazione globale.

    astro
    ---
    import { renderMarkdown } from "astro-intlayer/markdown";
    
    const html = renderMarkdown("# My Title", { forceBlock: true });
    ---
    
    <div set:html={html} />
    

    Configurazione Globale con MarkdownProvider

    Il MarkdownProvider (o il suo equivalente nel framework) configura la pipeline di rendering Markdown per l'intera applicazione. Questo si applica sia al rendering automatico di useIntlayer che alle utility di supporto. Le opzioni impostate qui sono quelle predefinite — .use() le sovrascrive a livello di nodo.

    AppProvider.tsx
    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 è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    AppProvider.tsx
    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>
    );
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    AppProvider.tsx
    import { MarkdownProvider } from "next-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 è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    AppProvider.tsx
    import { MarkdownProvider } from "next-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('next-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    main.ts
    import { createApp } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerMarkdown, {
    components: {
      h1: (props) =>
      h('h1', { style: { color: 'orange' }, ...props }, props.children),
      ComponentDemo: () => h('div', { style: { background: 'grey' } }, 'DEMO'),
      bold: (props) => h('strong', props),
      code: (props) => h('code', props),
    },
    });
    
    app.mount("#app");
    
    MDX è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    main.ts
    import { createApp } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerMarkdown, {
    renderMarkdown: async (md) => {
      const { renderMarkdown } = await import('vue-intlayer/markdown');
      return renderMarkdown(md);
    },
    });
    
    app.mount("#app");
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    </script>
    
    <MarkdownProvider
    components={{
      h1: MyHeading,
    }}
    >
    <slot />
    </MarkdownProvider>
    
    MDX è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownProvider
    renderMarkdown={async (md) => {
      const { renderMarkdown } = await import('svelte-intlayer/markdown');
      return renderMarkdown(md);
    }}
    >
    <slot />
    </MarkdownProvider>
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    AppProvider.tsx
    import { MarkdownProvider } from "preact-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      components={{
        h1: ({ children }) => <h1 className="text-2xl font-bold">{children}</h1>,
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    MDX è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    AppProvider.tsx
    import { MarkdownProvider } from "preact-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        const { renderMarkdown } = await import('preact-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    AppProvider.tsx
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    export const AppProvider = (props) => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 className="text-2xl font-bold">{props.children}</h1>,
      }}
    >
      {props.children}
    </MarkdownProvider>
    );
    
    MDX è supportato — qualsiasi nome di componente usato all'interno del tuo Markdown (es. <MyCustomJSXComponent />) viene risolto tramite la mappa components.

    Puoi anche usare il tuo renderer markdown:

    AppProvider.tsx
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    export const AppProvider = (props) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        const { renderMarkdown } = await import('solid-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {props.children}
    </MarkdownProvider>
    );
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.
    app.config.ts
    import { createIntlayerMarkdownProvider } from "angular-intlayer/markdown";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerMarkdownProvider({
        components: {
          h1: { class: "text-2xl font-bold" },
        },
      }),
    ],
    };
    
    MDX è supportato — qualsiasi nome di componente utilizzato all'interno del tuo Markdown (ad es. <MyCustomJSXComponent />) viene risolto rispetto alla mappa components.

    Puoi anche usare il tuo markdown renderer personalizzato:

    app.module.ts
    import { NgModule } from '@angular/core';
    import { IntlayerMarkdownModule } from 'angular-intlayer/markdown';
    
    @NgModule({
    imports: [
      IntlayerMarkdownModule.forRoot({
        renderMarkdown: async (md) => {
          const { renderMarkdown } = await import('angular-intlayer/markdown');
          return renderMarkdown(md);
        }
      })
    ]
    })
    export class AppModule {}
    
    Importare dinamicamente il tuo renderer Markdown è un buon modo per ridurre le dimensioni del bundle della tua applicazione.

    Remix non ha un albero dei componenti per contenere un provider, quindi la configurazione viene installata una sola volta, come singleton, all'avvio del server. Configura il renderer restituito da useMarkdownRenderer(). I nodi md restituiti da useIntlayer vengono renderizzati con il compilatore predefinito; sovrascrivi i loro tag per nodo con .use().

    src/router.ts
    import { installIntlayerMarkdown } from "remix-intlayer/markdown";
    
    installIntlayerMarkdown({
    forceBlock: true,
    components: {
      h1: ({ children }) => `<h1 class="text-2xl font-bold">${children}</h1>`,
    },
    });
    

    Puoi anche utilizzare il tuo renderer markdown:

    src/router.ts
    import { installIntlayerMarkdown } from "remix-intlayer/markdown";
    
    installIntlayerMarkdown({
    renderMarkdown: async (md) => {
      const { marked } = await import("marked");
      return marked(md) as string;
    },
    });
    
    Usa installIntlayerMarkdownDynamic(async () => …) per caricare il renderer in modo lazy; il loader viene eseguito solo alla prima chiamata.

    Astro non ha un albero dei componenti per contenere un provider, quindi la configurazione viene installata una sola volta, come singleton, nel middleware (server) e in uno <script> client (browser). Configura il renderer restituito da useMarkdownRenderer(). I nodi md restituiti da useIntlayer vengono renderizzati con il compilatore predefinito; sovrascrivi i loro tag per nodo con .use().

    src/middleware.ts
    import { installIntlayerMarkdown } from "astro-intlayer/markdown";
    import { defineMiddleware } from "astro:middleware";
    
    // Viene eseguito una sola volta all'avvio del server; il middleware Intlayer stesso è
    // registrato dall'integrazione, prima di questo file.
    installIntlayerMarkdown({
    forceBlock: true,
    components: {
      h1: ({ children }) => `<h1 class="text-2xl font-bold">${children}</h1>`,
    },
    });
    
    export const onRequest = defineMiddleware((_context, next) => next());
    

    Puoi anche utilizzare il tuo renderer markdown:

    src/middleware.ts
    import { installIntlayerMarkdown } from "astro-intlayer/markdown";
    
    installIntlayerMarkdown({
    renderMarkdown: async (md) => {
      const { marked } = await import("marked");
      return marked(md) as string;
    },
    });
    
    Usa installIntlayerMarkdownDynamic(async () => …) per caricare il renderer in modo lazy; il loader viene eseguito solo alla prima chiamata.

    Suspense

    Il renderer Markdown di Intlayer è caricato dinamicamente. Sebbene ottimizzato, il chunk del parser sottostante è di circa 55 kb. Il caricamento sincrono ritarda il rendering iniziale della pagina e riduce il First Contentful Paint (FCP).

    Per evitare di bloccare l'interfaccia utente, Intlayer si integra con l'API Suspense di React. Recupera il parser in background e lancia una Promise durante il download.

    Avvolgi qualsiasi componente che renderizza Intlayer Markdown in un limite <Suspense>. Questo visualizza uno stato di fallback localizzato durante il download del chunk, consentendo al resto del DOM di essere renderizzato immediatamente.

    Avviso: Se non si fornisce un limite <Suspense>, React sospenderà a livello di root o bloccherà il rendering dell'intero albero dei componenti fino al completo caricamento del chunk di 55 kb.

    In Next.js App Router, puoi utilizzare React Suspense per i componenti client o un file loading.tsx per i componenti server.

    Componente Client:

    components/MyComponent.tsx
    "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>
      );
    };
    

    Componente Server con loading.tsx:

    app/loading.tsx
    export default function Loading() {
      return <div>Loading...</div>;
    }
    
    app/page.tsx
    import { useIntlayer } from "next-intlayer/server";
    
    const MyPage = () => {
      const markdownContent = useIntlayer("my-markdown");
      return <div>{markdownContent}</div>;
    };
    
    export default MyPage;
    
    tsx
    import { useIntlayer } from "react-intlayer";
    import { Suspense } from "react";
    
    const MyComponent = () => {
      const markdownContent = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Vue ha un componente <Suspense> integrato. Avvolgi il componente che renderizza il contenuto Markdown in un limite <Suspense>.

    MyComponent.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    
    const { markdownContent } = useIntlayer("my-markdown");
    </script>
    
    <template>
      <Suspense>
        <component :is="markdownContent" />
        <template #fallback>
          <div>Loading...</div>
        </template>
      </Suspense>
    </template>
    

    Svelte non ha un equivalente dell'API Suspense. Usa un blocco {#await} per gestire il rendering asincrono del contenuto Markdown.

    MyComponent.svelte
    <script lang="ts">
    import { useIntlayer } from "svelte-intlayer";
    
    const content = useIntlayer("my-markdown");
    </script>
    
    {#await $content.markdownContent}
      <div>Loading...</div>
    {:then rendered}
      {@html rendered}
    {/await}
    

    Preact supporta l'API Suspense di React tramite preact/compat.

    MyComponent.tsx
    import { useIntlayer } from "preact-intlayer";
    import { Suspense } from "preact/compat";
    
    const MyComponent = () => {
      const markdownContent = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Solid ha il suo componente <Suspense> da solid-js.

    MyComponent.tsx
    import { useIntlayer } from "solid-intlayer";
    import { Suspense } from "solid-js";
    
    const MyComponent = () => {
      const { markdownContent } = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Angular non ha un'API Suspense. Usa le viste differite (@defer) per gestire i contenuti Markdown caricati in modo lazy (richiede Angular 17+).

    my.component.ts
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
      selector: "app-my",
      template: `
        @defer {
          <div [innerHTML]="content().markdownContent"></div>
        } @loading {
          <div>Loading...</div>
        }
      `,
    })
    export class MyComponent {
      content = useIntlayer("my-markdown");
    }
    

    Rendering Lato Server (SSR) e Idratazione

    Rispetto ad altri parser Markdown come remark / rehype, Intlayer Markdown è privo di dipendenze e viene eseguito sia sul client che sul server.

    Tuttavia, Intlayer ottimizza l'analisi per i framework di rendering lato server (SSR) (come Next.js App Router, React Router, Nuxt, SvelteKit, ecc.).

    Invece di inviare stringhe Markdown grezze al client e analizzarle nel browser (il che comporta una penalizzazione delle prestazioni), Intlayer consente di pre-analizzare il Markdown in un albero sintattico astratto (AST) sul server.

    È possibile utilizzare la funzione parseMarkdown del pacchetto Intlayer del proprio framework lato server per generare un AST serializzabile (oggetto ParsedMarkdown) e passarlo direttamente al frontend. Tutte le utilità di rendering di Intlayer (come <MarkdownRenderer>, useMarkdownRenderer, ecc.) accettano automaticamente questo oggetto AST e lo renderizzano perfettamente.

    Esempio in un'Architettura Server/Client

    server.ts
    import { parseMarkdown } from "react-intlayer/markdown";
    
    // 1. Sul server: Analizza il markdown in un AST serializzabile
    export const loader = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Restituisce l'AST come JSON al client
    return Response.json({ content: ast });
    };
    
    client.tsx
    import { useLoaderData } from "react-router";
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    // 2. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare
    export default function Page() {
    const { content } = useLoaderData();
    
    // Il renderer accetta una stringa grezza o l'AST analizzato
    return <MarkdownRenderer content={content} />;
    }
    
    app/page.tsx
    import { parseMarkdown } from "next-intlayer/markdown";
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    export default async function Page() {
    // 1. Analizza il markdown in un AST serializzabile sul server
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // 2. Esegue il rendering dell'AST direttamente
    // In un Server Component, questo funziona perfettamente e passa l'AST
    // direttamente ai componenti client sottostanti se necessario.
    return <MarkdownRenderer content={ast} />;
    }
    
    pages/index.vue
    <script setup lang="ts">
    import { parseMarkdown } from "vue-intlayer/markdown";
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    
    // 1. Recupera e analizza il markdown in un AST sul server
    const { data: ast } = await useAsyncData('markdown', () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    return parseMarkdown(markdownString);
    });
    </script>
    
    <template>
    <!-- 2. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare -->
    <MarkdownRenderer :content="ast" />
    </template>
    
    +page.server.ts
    import { parseMarkdown } from "svelte-intlayer/markdown";
    
    // 1. Sul server: Analizza il markdown in un AST serializzabile
    export const load = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Restituisce l'AST al client
    return { content: ast };
    };
    
    +page.svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    export let data;
    </script>
    
    <!-- 2. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare -->
    <MarkdownRenderer value={data.content} />
    

    L'SSR di Angular in genere risolve i dati sul server durante il caricamento iniziale e si idrata sul client. È possibile utilizzare i resolver per passare l'AST.

    app.resolver.ts
    import { Injectable } from "@angular/core";
    import { Resolve } from "@angular/router";
    import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";
    
    @Injectable({ providedIn: "root" })
    export class MarkdownResolver implements Resolve<ParsedMarkdown> {
    resolve(): ParsedMarkdown {
      const markdownString = "## My title \n\nLorem Ipsum";
      // 1. Sul server: Analizza il markdown in un AST serializzabile
      return parseMarkdown(markdownString);
    }
    }
    
    app.component.ts
    import { Component } from "@angular/core";
    import { ActivatedRoute } from "@angular/router";
    import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";
    
    @Component({
    selector: "app-root",
    template: `<div [innerHTML]="renderedMarkdown"></div>`,
    })
    export class AppComponent {
    renderedMarkdown: string = "";
    
    constructor(
      private route: ActivatedRoute,
      private markdownService: IntlayerMarkdownService
    ) {
      // 2. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare
      this.route.data.subscribe((data) => {
        this.renderedMarkdown = this.markdownService.renderMarkdown(
          data.markdownAst
        ) as string;
      });
    }
    }
    

    Remix 3 esegue il rendering sul server e trasmette l'HTML in streaming, quindi nessun AST deve raggiungere il client. Esegui il parsing una volta e renderizza l'AST ovunque venga creata la pagina:

    src/views/article.tsx
    import { parseMarkdown, renderMarkdown } from "remix-intlayer/markdown";
    
    // 1. Esegui il parsing del markdown in un AST serializzabile (es. una volta, al caricamento del modulo)
    const ast = parseMarkdown("## My title \n\nLorem Ipsum");
    
    export const ArticlePage = () => () => (
    // 2. Renderizza l'AST: il renderer accetta una stringa non elaborata o l'AST analizzato
    <article innerHTML={renderMarkdown(ast)} />
    );
    

    Le pagine Astro vengono renderizzate sul server, quindi nessun AST deve raggiungere il client. Esegui il parsing del Markdown nel frontmatter e renderizzalo con set:html:

    src/pages/article.astro
    ---
    import { parseMarkdown, renderMarkdown } from "astro-intlayer/markdown";
    
    // 1. Esegui il parsing del markdown in un AST serializzabile
    const ast = parseMarkdown("## My title \n\nLorem Ipsum");
    ---
    
    <!-- 2. Renderizza l'AST: il renderer accetta una stringa non elaborata o l'AST analizzato -->
    <article set:html={renderMarkdown(ast)} />
    

    Questo modello garantisce che la logica di analisi del Markdown venga eseguita interamente sul server, riducendo significativamente il tempo di esecuzione lato client e migliorando la velocità di idratazione iniziale.

    Riferimento opzioni

    Queste opzioni possono essere passate a MarkdownProvider, MarkdownRenderer, useMarkdownRenderer e renderMarkdown.

    OptionTypeDefaultDescrizione
    forceBlockbooleanfalseForza l'output a essere avvolto in un elemento a livello di blocco (es. <div>).
    forceInlinebooleanfalseForza l'output a essere avvolto in un elemento in linea (es. <span>).
    tagfilterbooleantrueAbilita il GitHub Tag Filter per una maggiore sicurezza rimuovendo i tag HTML pericolosi.
    preserveFrontmatterbooleanfalseSe true, il frontmatter all'inizio della stringa Markdown non verrà rimosso.
    componentsOverrides{}Una mappa di tag HTML per componenti personalizzati (es. { h1: MyHeading }).
    wrapperComponentnullUn componente personalizzato per avvolgere il Markdown renderizzato.
    renderMarkdownFunctionnullUna funzione di rendering personalizzata per sostituire completamente il compilatore Markdown predefinito.