Autore:
    Creazione:2025-02-07Ultimo aggiornamento:2026-05-19

    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
    

    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);
    }
    }
    

    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.
    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.

    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;
      });
    }
    }
    

    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.

    Option Type Default Descrizione
    forceBlock boolean false Forza l'output a essere avvolto in un elemento a livello di blocco (es. <div>).
    forceInline boolean false Forza l'output a essere avvolto in un elemento in linea (es. <span>).
    tagfilter boolean true Abilita il GitHub Tag Filter per una maggiore sicurezza rimuovendo i tag HTML pericolosi.
    preserveFrontmatter boolean false Se true, il frontmatter all'inizio della stringa Markdown non verrà rimosso.
    components Overrides {} Una mappa di tag HTML per componenti personalizzati (es. { h1: MyHeading }).
    wrapper Component null Un componente personalizzato per avvolgere il Markdown renderizzato.
    renderMarkdown Function null Una funzione di rendering personalizzata per sostituire completamente il compilatore Markdown predefinito.