Autor:
    Data utworzenia:2025-02-07Ostatnia aktualizacja:2026-05-19

    Markdown / Treść w postaci tekstu sformatowanego

    Intlayer obsługuje treści w postaci tekstu sformatowanego (Rich Text) definiowane za pomocą składni Markdown. Pozwala to na łatwe pisanie i utrzymywanie bogato sformatowanych treści, takich jak blogi, artykuły i inne.

    Deklarowanie treści Markdown

    Możesz zadeklarować treść Markdown używając funkcji md lub po prostu jako ciąg znaków (jeśli zawiera składnię Markdown).

    Począwszy od wersji 8.10.0, możesz deklarować treść Markdown bezpośrednio w plikach .content.md. Intlayer automatycznie wykryje i przetworzy treść Markdown.

    markdown-file.en.content.md
    ---
    key: my-markdown-content
    description: Moja treść
    locale: en
    ---
    
    # Moja treść
    
    Oto przykład treści markdown
    

    Pole front-matter locale to pole, które definiuje język treści. Jest ono opcjonalne. Jeśli nie zostanie podane, Intlayer użyje języka domyślnego, który służy również jako język zastępczy, jeśli nie jest dostępne tłumaczenie dla określonego języka.

    Przykład struktury plików:

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

    Do front-matter można dodać dowolne właściwości zdefiniowane w Definicji słownika

    Użyj funkcji md, aby jawnie zadeklarować treść Markdown. Jest to przydatne, jeśli chcesz upewnić się, że ciąg znaków jest traktowany jako Markdown, nawet jeśli nie zawiera wyraźnej składni.

    markdownDictionary.content.ts
    import { md, type Dictionary } from "intlayer";
    
    const markdownDictionary = {
    key: "app",
    content: {
      myMarkdownContent: md("## Mój tytuł \n\nLorem Ipsum"),
    },
    } satisfies Dictionary;
    
    export default markdownDictionary;
    

    Importuj pliki .md bezpośrednio za pomocą funkcji file.

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

    Jeśli ciąg znaków zawiera typowe wskaźniki Markdown (takie jak nagłówki, listy, linki itp.), Intlayer automatycznie je przekształci.

    markdownDictionary.content.ts
    export default {
    key: "app",
    contentAutoTransformation: true, // Włącz automatyczne wykrywanie treści Markdown - Można ustawić globalnie w intlayer.config.ts
    content: {
      myMarkdownContent: "## Mój tytuł \n\nLorem Ipsum",
    },
    };
    

    Renderowanie Markdown

    Intlayer zapewnia dwa niezależne sposoby renderowania Markdown:

    1. Przez useIntlayer — Intlayer automatycznie przekształca węzeł md w natywny wynik frameworka (JSX, VNode, ciąg znaków HTML).

      • Frontmatter jest analizowany i eksponowany jako .metadata. Możesz nadpisać renderowanie na dwóch poziomach — globalnie za pomocą MarkdownProvider (lub odpowiednika frameworka) i lokalnie dla węzła za pomocą .use(). Oba można łączyć; .use() ma pierwszeństwo przed MarkdownProvider, który z kolei ma pierwszeństwo przed ustawieniami domyślnymi.
    2. Narzędzia pomocnicze<MarkdownRenderer />, useMarkdownRenderer() i renderMarkdown() to samodzielne narzędzia, które akceptują tylko surowe ciągi znaków Markdown. Są one niezależne od useIntlayer i nie działają ze zwracanymi przez nie udekorowanymi węzłami.

    Renderowanie Markdown obsługuje MDX — użyj dowolnego komponentu JSX/frameworka podając jego nazwę bezpośrednio w swoim Markdown.

    1. Automatyczne renderowanie (przez useIntlayer)

    Węzły Markdown można renderować bezpośrednio jako 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} />, // Komponent MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Jeśli MarkdownProvider nie jest obecny, Intlayer użyje domyślnego parsera Markdown do JSX do wyrenderowania markdownu.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    Węzły Markdown można renderować bezpośrednio jako 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} />, // Komponent MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Jeśli MarkdownProvider nie jest obecny, Intlayer użyje domyślnego parsera Markdown do JSX do wyrenderowania markdownu.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    W Vue, treść Markdown można renderować przy użyciu wbudowanego tagu component lub bezpośrednio jako węzeł.

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

    Skonfiguruj globalnie za pomocą wtyczki intlayerMarkdown (obsługuje komponenty niestandardowe MDX):

    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), // Komponent MDX
    },
    });
    
    Jeśli wtyczka intlayerMarkdown nie jest zainstalowana, Intlayer wyrenderuje za pomocą domyślnego kompilatora.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    Svelte domyślnie renderuje Markdown jako ciąg znaków HTML. Użyj {@html}, aby go wyrenderować.

    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>
    
    Jeśli MarkdownProvider nie jest obecny, Intlayer wyrenderuje markdown używając domyślnego kompilatora.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    Preact obsługuje węzły Markdown bezpośrednio w 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} />, // Komponent MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Jeśli MarkdownProvider nie jest obecny, Intlayer użyje domyślnego parsera Markdown do JSX do wyrenderowania markdownu.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    Solid obsługuje węzły Markdown bezpośrednio w 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} />, // Komponent MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Jeśli MarkdownProvider nie jest obecny, Intlayer użyje domyślnego parsera Markdown do JSX do wyrenderowania markdownu.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    Angular używa dyrektywy [innerHTML] do renderowania treści 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");
    }
    
    Jeśli dostawca IntlayerMarkdown nie jest skonfigurowany, Intlayer wyrenderuje za pomocą domyślnego kompilatora.

    Możesz również zapewnić lokalne nadpisania dla określonych węzłów za pomocą metody .use():

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

    Możesz pobrać Markdown jako ciąg znaków:

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

    Możesz uzyskać dostęp do metadanych markdown w ten sposób:

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

    2. Narzędzia pomocnicze (tylko ciągi znaków Markdown)

    Te narzędzia renderują tylko surowe ciągi znaków Markdown i są niezależne od useIntlayer. Używaj ich, gdy musisz wyrenderować Markdown ze źródeł innych niż słowniki.

    Komponent <MarkdownRenderer />

    Renderuje ciąg znaków Markdown z określonymi opcjami.

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Mój Tytuł"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Pobierz wstępnie skonfigurowaną funkcję renderowania.

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

    Narzędzie renderMarkdown()

    Samodzielne narzędzie do renderowania poza komponentami.

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";
    
    const jsx = renderMarkdown("# Mój Tytuł", { forceBlock: true });
    

    Komponent <MarkdownRenderer />

    Renderuje ciąg znaków Markdown z określonymi opcjami.

    tsx
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Mój Tytuł"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Pobierz wstępnie skonfigurowaną funkcję renderowania.

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

    Narzędzie renderMarkdown()

    Samodzielne narzędzie do renderowania poza komponentami.

    tsx
    import { renderMarkdown } from "next-intlayer/markdown";
    
    const jsx = renderMarkdown("# Mój Tytuł", { forceBlock: true });
    

    Komponent <MarkdownRenderer />

    vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>
    
    <template>
    <MarkdownRenderer :forceBlock="true" content="# Mój Tytuł" />
    </template>
    

    Komponent <MarkdownRenderer />

    svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownRenderer forceBlock={true} value="# Mój Tytuł" />
    

    Hook useMarkdownRenderer()

    svelte
    <script lang="ts">
    import { useMarkdownRenderer } from "svelte-intlayer/markdown";
    const render = useMarkdownRenderer();
    </script>
    
    {@html render("# Mój Tytuł")}
    

    Narzędzie renderMarkdown()

    svelte
    <script lang="ts">
    import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>
    
    {@html renderMarkdown("# Mój Tytuł")}
    

    Komponent <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Mój Tytuł"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Mój Tytuł")}</div>;
    

    Narzędzie renderMarkdown()

    tsx
    import { renderMarkdown } from "preact-intlayer/markdown";
    
    return <div>{renderMarkdown("# Mój Tytuł")}</div>;
    

    Komponent <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Mój Tytuł"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Mój Tytuł")}</div>;
    

    Narzędzie renderMarkdown()

    tsx
    import { renderMarkdown } from "solid-intlayer/markdown";
    
    return <div>{renderMarkdown("# Mój Tytuł")}</div>;
    

    Usługa IntlayerMarkdownService

    Renderuje ciąg znaków Markdown przy użyciu usługi.

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

    Konfiguracja globalna z MarkdownProvider

    MarkdownProvider (lub jego odpowiednik we frameworku) konfiguruje potok renderowania Markdown dla całej aplikacji. Dotyczy to zarówno automatycznego renderowania useIntlayer, jak i narzędzi pomocniczych. Ustawione tutaj opcje są ustawieniami domyślnymi — .use() nadpisuje je na poziomie węzła.

    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 jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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>
    );
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    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 jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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>
    );
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    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 jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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");
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    </script>
    
    <MarkdownProvider
    components={{
      h1: MyHeading,
    }}
    >
    <slot />
    </MarkdownProvider>
    
    MDX jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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>
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    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 jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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>
    );
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    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 jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera 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>
    );
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.
    app.config.ts
    import { createIntlayerMarkdownProvider } from "angular-intlayer/markdown";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerMarkdownProvider({
        components: {
          h1: { class: "text-2xl font-bold" },
        },
      }),
    ],
    };
    
    MDX jest obsługiwany — każda nazwa komponentu użyta wewnątrz twojego Markdown (np. <MyCustomJSXComponent />) jest rozwiązywana względem mapy components.

    Możesz również użyć własnego renderera markdown:

    app.config.ts
    import { createIntlayerMarkdownProvider } from "angular-intlayer/markdown";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerMarkdownProvider({
        renderMarkdown: async (md) => {
          const { renderMarkdown } = await import('angular-intlayer/markdown');
          return renderMarkdown(md);
        },
      }),
    ],
    };
    
    Dynamiczne importowanie twojego renderera Markdown to świetny sposób na zmniejszenie rozmiaru pakietu twojej aplikacji.

    Suspense

    Renderer Markdown Intlayer jest ładowany dynamicznie. Mimo optymalizacji, bazowy fragment parsera zajmuje około 55 kb. Synchroniczne ładowanie tego opóźnia początkowe renderowanie strony i pogarsza First Contentful Paint (FCP).

    Aby zapobiec blokowaniu interfejsu użytkownika, Intlayer integruje się z API Suspense Reacta. Pobiera parser w tle i rzuca Promise podczas pobierania.

    Zawiń dowolny komponent renderujący Intlayer Markdown w granicę <Suspense>. Wyświetli to zlokalizowany stan rezerwowy podczas pobierania fragmentu, umożliwiając natychmiastowe renderowanie reszty DOM.

    Ostrzeżenie: Jeśli nie zapewnisz granicy <Suspense>, React wstrzyma działanie na poziomie głównym lub zablokuje renderowanie całego drzewa komponentów do czasu pełnego załadowania 55 kb fragmentu.

    W Next.js App Router można użyć React Suspense dla komponentów klienckich lub pliku loading.tsx dla komponentów serwerowych.

    Komponent kliencki:

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

    Komponent serwerowy z 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 ma wbudowany komponent <Suspense>. Zawiń komponent renderujący zawartość Markdown w granicę <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 nie ma odpowiednika API Suspense. Użyj bloku {#await}, aby obsłużyć asynchroniczne renderowanie zawartości 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 obsługuje API Suspense Reacta przez 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 ma swój własny komponent <Suspense> z 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 nie ma API Suspense. Użyj odroczonych widoków (@defer) w Angular, aby obsługiwać leniwie ładowaną zawartość Markdown (wymaga 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");
    }
    

    Renderowanie po stronie serwera (SSR) i hydratacja

    W porównaniu do innych parserów Markdown, takich jak remark / rehype, Intlayer Markdown jest pozbawiony zależności i działa zarówno po stronie klienta, jak i serwera.

    Jednak Intlayer optymalizuje parsowanie dla frameworków renderowania po stronie serwera (SSR) (takich jak Next.js App Router, React Router, Nuxt, SvelteKit itp.).

    Zamiast wysyłać surowe ciągi Markdown do klienta i parsować je w przeglądarce (co powoduje spadek wydajności), Intlayer pozwala na wstępne sparsowanie Markdown do abstrakcyjnego drzewa składniowego (AST) na serwerze.

    Możesz użyć funkcji parseMarkdown z pakietu Intlayer swojego frameworka po stronie serwera, aby wygenerować serializowalne AST (obiekt ParsedMarkdown) i przekazać je bezpośrednio do frontendu. Wszystkie narzędzia renderujące Intlayer (takie jak <MarkdownRenderer>, useMarkdownRenderer itp.) automatycznie akceptują ten obiekt AST i renderują go bez zakłóceń.

    Przykład w architekturze serwer/klient

    server.ts
    import { parseMarkdown } from "react-intlayer/markdown";
    
    // 1. Na serwerze: Sparsuj markdown do serializowalnego AST
    export const loader = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Zwróć AST jako JSON do klienta
    return Response.json({ content: ast });
    };
    
    client.tsx
    import { useLoaderData } from "react-router";
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    // 2. Na kliencie: Renderuj AST bezpośrednio bez ponownego parsowania
    export default function Page() {
    const { content } = useLoaderData();
    
    // Renderer akceptuje surowy ciąg znaków lub sparsowane AST
    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. Sparsuj markdown do serializowalnego AST na serwerze
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // 2. Renderuj AST bezpośrednio
    // W Server Component działa to bezproblemowo i przekazuje AST
    // bezpośrednio do bazowych komponentów klienckich, jeśli to konieczne.
    return <MarkdownRenderer content={ast} />;
    }
    
    pages/index.vue
    <script setup lang="ts">
    import { parseMarkdown } from "vue-intlayer/markdown";
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    
    // 1. Pobierz i sparsuj markdown do AST na serwerze
    const { data: ast } = await useAsyncData('markdown', () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    return parseMarkdown(markdownString);
    });
    </script>
    
    <template>
    <!-- 2. Na kliencie: Renderuj AST bezpośrednio bez ponownego parsowania -->
    <MarkdownRenderer :content="ast" />
    </template>
    
    +page.server.ts
    import { parseMarkdown } from "svelte-intlayer/markdown";
    
    // 1. Na serwerze: Sparsuj markdown do serializowalnego AST
    export const load = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Zwróć AST do klienta
    return { content: ast };
    };
    
    +page.svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    export let data;
    </script>
    
    <!-- 2. Na kliencie: Renderuj AST bezpośrednio bez ponownego parsowania -->
    <MarkdownRenderer value={data.content} />
    

    Angular SSR zazwyczaj pobiera dane na serwerze podczas początkowego ładowania i hydratuje na kliencie. Możesz użyć resolverów do przekazania 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. Na serwerze: Sparsuj markdown do serializowalnego AST
      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. Na kliencie: Renderuj AST bezpośrednio bez ponownego parsowania
      this.route.data.subscribe((data) => {
        this.renderedMarkdown = this.markdownService.renderMarkdown(
          data.markdownAst
        ) as string;
      });
    }
    }
    

    Ten wzorzec zapewnia, że logika parsowania Markdown jest wykonywana całkowicie na serwerze, co znacznie skraca czas wykonywania po stronie klienta i poprawia szybkość początkowej hydratacji.

    Opcje referencyjne

    Te opcje można przekazać do MarkdownProvider, MarkdownRenderer, useMarkdownRenderer i renderMarkdown.

    Option Type Default Opis
    forceBlock boolean false Wymusza zawijanie wyjścia w element blokowy (np. <div>).
    forceInline boolean false Wymusza zawijanie wyjścia w element liniowy (np. <span>).
    tagfilter boolean true Włącza GitHub Tag Filter w celu zwiększenia bezpieczeństwa poprzez usuwanie niebezpiecznych tagów HTML.
    preserveFrontmatter boolean false Jeśli true, frontmatter na początku ciągu Markdown nie zostanie usunięty.
    components Overrides {} Mapa tagów HTML na niestandardowe komponenty (np. { h1: MyHeading }).
    wrapper Component null Niestandardowy komponent do zawijania renderowanego Markdown.
    renderMarkdown Function null Niestandardowa funkcja renderowania, aby całkowicie zastąpić domyślny kompilator Markdown.