المؤلف:
    إنشاء:2025-02-07آخر تحديث:2026-05-19

    Markdown / محتوى نصي غني

    يدعم Intlayer المحتوى النصي الغني المعرف باستخدام بناء جملة Markdown. يتيح لك هذا كتابة المحتوى ذي التنسيق الغني والحفاظ عليه بسهولة مثل المدونات والمقالات والمزيد.

    الإعلان عن محتوى Markdown

    يمكنك الإعلان عن محتوى Markdown باستخدام وظيفة md أو ببساطة كسلسلة نصية (إذا كانت تحتوي على بناء جملة Markdown).

    بدءًا من الإصدار 8.10.0 ، يمكنك الإعلان عن محتوى Markdown مباشرةً في ملفات .content.md. سيكتشف Intlayer محتوى Markdown ويحلله تلقائيًا.

    markdown-file.en.content.md
    ---
    key: my-markdown-content
    description: محتواي
    locale: en
    ---
    
    # محتواي
    
    فيما يلي مثال على محتوى markdown
    

    حقل front-matter locale هو الحقل الذي يحدد لغة المحتوى. إنه اختياري. في حالة عدم توفيره ، سيستخدم Intlayer اللغة الافتراضية ، والتي تُستخدم أيضًا كلغة احتياطية إذا لم تتوفر ترجمة للغة معينة.

    مثال على بنية الملفات:

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

    يمكنك إضافة أي خصائص معرفة في تعريف القاموس في front-matter

    استخدم الوظيفة md للإعلان بشكل صريح عن محتوى Markdown. يكون هذا مفيدًا إذا كنت تريد التأكد من التعامل مع سلسلة نصية على أنها Markdown حتى لو كانت لا تحتوي على بناء جملة واضح.

    markdownDictionary.content.ts
    import { md, type Dictionary } from "intlayer";
    
    const markdownDictionary = {
    key: "app",
    content: {
      myMarkdownContent: md("## عنواني \n\nLorem Ipsum"),
    },
    } satisfies Dictionary;
    
    export default markdownDictionary;
    

    قم باستيراد ملفات .md مباشرة باستخدام وظيفة file.

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

    إذا كانت السلسلة النصية تحتوي على مؤشرات Markdown شائعة (مثل العناوين والقوائم والروابط وما إلى ذلك) ، فسيقوم Intlayer بتحويلها تلقائيًا.

    markdownDictionary.content.ts
    export default {
    key: "app",
    contentAutoTransformation: true, // تمكين الاكتشاف التلقائي لمحتوى Markdown - يمكن تعيينه عالميًا في intlayer.config.ts
    content: {
      myMarkdownContent: "## عنواني \n\nLorem Ipsum",
    },
    };
    

    عرض Markdown

    يوفر Intlayer طريقتين مستقلتين لعرض Markdown:

    1. عبر useIntlayer — يحول Intlayer تلقائيًا عقدة md إلى الإخراج الأصلي لإطار العمل (JSX ، VNode ، سلسلة HTML).

      • يتم تحليل Frontmatter وكشفه كـ .metadata. يمكنك تجاوز التقديم على مستويين — عالميًا باستخدام MarkdownProvider (أو ما يعادله في إطار العمل) ومحليًا لكل عقدة باستخدام .use(). يمكن دمج كليهما ؛ .use() له الأسبقية على MarkdownProvider ، والذي له الأسبقية على الافتراضي.
    2. الأدوات المساعدة<MarkdownRenderer /> ، useMarkdownRenderer() ، و renderMarkdown() هي أدوات مستقلة لا تقبل سوى سلاسل Markdown الخام. إنها مستقلة عن useIntlayer ولا تعمل مع العقد المزخرفة التي تعيدها.

    يدعم عرض Markdown MDX — استخدم أي مكون JSX/framework بالاسم مباشرة داخل Markdown الخاص بك.

    1. العرض التلقائي (عبر useIntlayer)

    يمكن عرض عقد Markdown مباشرة كـ 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} />, // مكون MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    إذا لم يكن MarkdownProvider موجودًا ، فسيقوم Intlayer بعرض markdown باستخدام المحلل اللغوي الافتراضي من Markdown إلى JSX.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    يمكن عرض عقد Markdown مباشرة كـ 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} />, // مكون MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    إذا لم يكن MarkdownProvider موجودًا ، فسيقوم Intlayer بعرض markdown باستخدام المحلل اللغوي الافتراضي من Markdown إلى JSX.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    في Vue ، يمكن عرض محتوى Markdown باستخدام علامة component المضمنة أو مباشرة كعقدة.

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

    التكوين العالمي عبر إضافة intlayerMarkdown (يدعم مكونات 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), // مكون MDX
    },
    });
    
    إذا لم يتم تثبيت إضافة intlayerMarkdown ، فسيقوم Intlayer بالعرض باستخدام المترجم الافتراضي.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    يعرض Svelte Markdown كسلسلة HTML افتراضيًا. استخدم {@html} لعرضه.

    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>
    
    إذا لم يكن MarkdownProvider موجودًا ، فسيقوم Intlayer بعرض markdown باستخدام المترجم الافتراضي.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    يدعم Preact عقد Markdown مباشرة في 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} />, // مكون MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    إذا لم يكن MarkdownProvider موجودًا ، فسيقوم Intlayer بعرض markdown باستخدام المحلل اللغوي الافتراضي من Markdown إلى JSX.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    يدعم Solid عقد Markdown مباشرة في 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} />, // مكون MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    إذا لم يكن MarkdownProvider موجودًا ، فسيقوم Intlayer بعرض markdown باستخدام المحلل اللغوي الافتراضي من Markdown إلى JSX.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    يستخدم Angular التوجيه [innerHTML] لعرض محتوى 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");
    }
    
    إذا لم يتم تكوين مزود IntlayerMarkdown ، فسيقوم Intlayer بالعرض باستخدام المترجم الافتراضي.

    يمكنك أيضًا توفير تجاوزات محلية لعقد معينة باستخدام طريقة .use():

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

    يمكنك استرداد Markdown كسلسلة نصية:

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

    ويمكنك الوصول إلى بيانات markdown الوصفية الخاصة بك على النحو التالي:

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

    2. الأدوات المساعدة (سلاسل Markdown فقط)

    هذه الأدوات تعرض فقط سلاسل Markdown الخام وهي مستقلة عن useIntlayer. استخدمها عندما تحتاج إلى عرض Markdown من مصادر أخرى غير قواميسك.

    مكون <MarkdownRenderer />

    يعرض سلسلة Markdown مع خيارات محددة.

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# عنواني"}
    </MarkdownRenderer>
    

    خطاف useMarkdownRenderer()

    احصل على وظيفة عارض مكونة مسبقًا.

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

    أداة renderMarkdown()

    أداة مستقلة للعرض خارج المكونات.

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";
    
    const jsx = renderMarkdown("# عنواني", { forceBlock: true });
    

    مكون <MarkdownRenderer />

    يعرض سلسلة Markdown مع خيارات محددة.

    tsx
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# عنواني"}
    </MarkdownRenderer>
    

    خطاف useMarkdownRenderer()

    احصل على وظيفة عارض مكونة مسبقًا.

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

    أداة renderMarkdown()

    أداة مستقلة للعرض خارج المكونات.

    tsx
    import { renderMarkdown } from "next-intlayer/markdown";
    
    const jsx = renderMarkdown("# عنواني", { forceBlock: true });
    

    مكون <MarkdownRenderer />

    vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>
    
    <template>
    <MarkdownRenderer :forceBlock="true" content="# عنواني" />
    </template>
    

    مكون <MarkdownRenderer />

    svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownRenderer forceBlock={true} value="# عنواني" />
    

    خطاف useMarkdownRenderer()

    svelte
    <script lang="ts">
    import { useMarkdownRenderer } from "svelte-intlayer/markdown";
    const render = useMarkdownRenderer();
    </script>
    
    {@html render("# عنواني")}
    

    أداة renderMarkdown()

    svelte
    <script lang="ts">
    import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>
    
    {@html renderMarkdown("# عنواني")}
    

    مكون <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# عنواني"}
    </MarkdownRenderer>
    

    خطاف useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# عنواني")}</div>;
    

    أداة renderMarkdown()

    tsx
    import { renderMarkdown } from "preact-intlayer/markdown";
    
    return <div>{renderMarkdown("# عنواني")}</div>;
    

    مكون <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# عنواني"}
    </MarkdownRenderer>
    

    خطاف useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# عنواني")}</div>;
    

    أداة renderMarkdown()

    tsx
    import { renderMarkdown } from "solid-intlayer/markdown";
    
    return <div>{renderMarkdown("# عنواني")}</div>;
    

    خدمة IntlayerMarkdownService

    تعرض سلسلة Markdown باستخدام الخدمة.

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

    التكوين العالمي باستخدام MarkdownProvider

    يقوم MarkdownProvider (أو ما يعادله في إطار العمل) بتكوين خط أنابيب عرض Markdown لتطبيقك بالكامل. ينطبق هذا على كل من العرض التلقائي useIntlayer والأدوات المساعدة. الخيارات المعينة هنا هي الإعدادات الافتراضية — يتجاوزها .use() على مستوى العقدة.

    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 مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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>
    );
    
    الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.
    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 مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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>
    );
    
    الاستيراد الديناميكي لعارض 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, {
    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 مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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");
    
    الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.
    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    </script>
    
    <MarkdownProvider
    components={{
      h1: MyHeading,
    }}
    >
    <slot />
    </MarkdownProvider>
    
    MDX مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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>
    
    الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.
    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 مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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>
    );
    
    الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.
    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 مدعوم — يتم حل أي اسم مكون يستخدم داخل Markdown الخاص بك (على سبيل المثال <MyCustomJSXComponent />) مقابل خريطة components.

    يمكنك أيضًا استخدام عارض 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>
    );
    
    الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.
    MDX مدعوم — أي اسم مكون يُستخدم داخل Markdown (مثل <MyCustomJSXComponent />) يتم حله مقابل خريطة components.

    يمكنك أيضًا استخدام markdown renderer الخاص بك:

    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 {}
    
    > الاستيراد الديناميكي لعارض Markdown الخاص بك هو طريقة رائعة لتقليل حجم حزمة تطبيقك.

    التعليق (Suspense)

    يتم تحميل محرك Markdown في Intlayer ديناميكيًا. على الرغم من تحسينه، يبلغ حجم الجزء الأساسي للمحلل حوالي 55 كيلوبايت. يؤدي تحميل هذا بشكل متزامن إلى تأخير عرض الصفحة الأولي ويقلل من سرعة عرض المحتوى الأول (FCP).

    لمنع حظر واجهة المستخدم، يتكامل Intlayer مع واجهة برمجة تطبيقات React Suspense. حيث يقوم بجلب المحلل في الخلفية ويرمي Promise أثناء التنزيل.

    قم بتغليف أي مكون يعرض Intlayer Markdown في حدود <Suspense>. يعرض هذا حالة احتياطية محلية أثناء تنزيل الجزء، مما يسمح لبقية DOM الخاص بك بالعرض على الفور.

    تحذير: إذا لم تقم بتوفير حدود <Suspense>، سيقوم React بالتعليق على مستوى الجذر أو حظر شجرة المكونات بأكملها من العرض حتى يتم تحميل جزء الـ 55 كيلوبايت بالكامل.

    في Next.js App Router، يمكنك استخدام إما React Suspense لمكونات العميل أو ملف loading.tsx لمكونات الخادم.

    مكون العميل:

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

    مكون الخادم مع 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 على مكون <Suspense> مضمن. قم بتغليف المكون الذي يعرض محتوى Markdown في حدود <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 على واجهة برمجة تطبيقات Suspense مماثلة. استخدم كتلة {#await} للتعامل مع العرض غير المتزامن لمحتوى 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 واجهة برمجة تطبيقات Suspense الخاصة بـ React عبر 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 على مكون <Suspense> الخاص به من 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 على واجهة برمجة تطبيقات Suspense. استخدم طرق العرض المؤجلة (@defer) للتعامل مع محتوى Markdown المحمل ببطء (يتطلب 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");
    }
    

    العرض من جانب الخادم (SSR) والترطيب (Hydration)

    بالمقارنة مع محللات Markdown الأخرى مثل remark / rehype، فإن Intlayer Markdown خالي من الاعتماديات ويعمل على جانب العميل وجانب الخادم على حد سواء.

    ولكن قامت Intlayer بتحسين التحليل لإطارات عمل العرض من جانب الخادم (SSR) (مثل Next.js App Router و React Router و Nuxt و SvelteKit وما إلى ذلك).

    بدلاً من إرسال سلاسل Markdown الخام إلى العميل وتحليلها في المتصفح (مما يؤدي إلى تراجع الأداء)، تتيح لك Intlayer تحليل Markdown مسبقًا إلى شجرة لغة مجردة (AST) على الخادم.

    يمكنك استخدام دالة parseMarkdown من حزمة Intlayer الخاصة بإطار العمل لديك على جانب الخادم لإنشاء AST قابل للتسلسل (كائن ParsedMarkdown)، وتمريره مباشرة إلى الواجهة الأمامية. تقبل جميع أدوات عرض Intlayer (مثل <MarkdownRenderer> و useMarkdownRenderer وما إلى ذلك) كائن AST هذا تلقائيًا وتعرضه بسلاسة.

    مثال في بنية خادم/عميل

    server.ts
    import { parseMarkdown } from "react-intlayer/markdown";
    
    // 1. على الخادم: تحليل markdown إلى AST قابل للتسلسل
    export const loader = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // إرجاع AST كـ JSON إلى العميل
    return Response.json({ content: ast });
    };
    
    client.tsx
    import { useLoaderData } from "react-router";
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    // 2. على العميل: عرض AST مباشرة دون إعادة تحليل
    export default function Page() {
    const { content } = useLoaderData();
    
    // يقبل العارض إما سلسلة خام أو 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. تحليل markdown إلى AST قابل للتسلسل على الخادم
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // 2. عرض AST مباشرة
    // في مكون الخادم (Server Component)، يعمل هذا بسلاسة ويمرر AST
    // مباشرة إلى مكونات العميل الأساسية إذا لزم الأمر.
    return <MarkdownRenderer content={ast} />;
    }
    
    pages/index.vue
    <script setup lang="ts">
    import { parseMarkdown } from "vue-intlayer/markdown";
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    
    // 1. جلب وتحليل markdown إلى AST على الخادم
    const { data: ast } = await useAsyncData('markdown', () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    return parseMarkdown(markdownString);
    });
    </script>
    
    <template>
    <!-- 2. على العميل: عرض AST مباشرة دون إعادة تحليل -->
    <MarkdownRenderer :content="ast" />
    </template>
    
    +page.server.ts
    import { parseMarkdown } from "svelte-intlayer/markdown";
    
    // 1. على الخادم: تحليل markdown إلى AST قابل للتسلسل
    export const load = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // إرجاع AST إلى العميل
    return { content: ast };
    };
    
    +page.svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    export let data;
    </script>
    
    <!-- 2. على العميل: عرض AST مباشرة دون إعادة تحليل -->
    <MarkdownRenderer value={data.content} />
    

    يعمل Angular SSR عادةً على حل البيانات على الخادم أثناء التحميل الأولي وترطيبها على العميل. يمكنك استخدام أدوات الحل (resolvers) لتمرير 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. على الخادم: تحليل markdown إلى 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. على العميل: عرض AST مباشرة دون إعادة تحليل
      this.route.data.subscribe((data) => {
        this.renderedMarkdown = this.markdownService.renderMarkdown(
          data.markdownAst
        ) as string;
      });
    }
    }
    

    يضمن هذا النمط تنفيذ منطق تحليل Markdown بالكامل على الخادم، مما يقلل بشكل كبير من وقت التنفيذ من جانب العميل ويحسن سرعة الترطيب الأولية.

    مرجع الخيارات

    يمكن تمرير هذه الخيارات إلى MarkdownProvider و MarkdownRenderer و useMarkdownRenderer و renderMarkdown.

    Option Type Default الوصف
    forceBlock boolean false يجبر الإخراج على الالتفاف في عنصر على مستوى الكتلة (مثل <div>).
    forceInline boolean false يجبر الإخراج على الالتفاف في عنصر مضمن (مثل <span>).
    tagfilter boolean true يمكّن عامل تصفية علامات GitHub لتحسين الأمان عن طريق إزالة علامات HTML الخطيرة.
    preserveFrontmatter boolean false إذا كان true، فلن يتم إزالة البيانات الأولية (frontmatter) في بداية سلسلة Markdown.
    components Overrides {} خريطة لعلامات HTML إلى مكونات مخصصة (مثل { h1: MyHeading }).
    wrapper Component null مكون مخصص لتغليف Markdown المعروض.
    renderMarkdown Function null وظيفة عرض مخصصة لاستبدال مترجم Markdown الافتراضي بالكامل.