ماركداون و MDX
ماركداون (Markdown) هي لغة ترميز خفيفة الوزن تستخدم لتنسيق النصوص. تتيح لك الكتابة باستخدام صيغة نصية عادية وتحويلها إلى HTML صالح هيكليًا. تُستخدم عادةً لكتابة المحتوى على المواقع والمدونات.
عند الكتابة...
I **love** using [Next.js](https://nextjs.org/)
المخرجات:
<p>I <strong>love</strong> using <a href="https://nextjs.org/">Next.js</a></p>
MDX هي مجموعة شاملة من ماركداون تتيح لك كتابة JSX مباشرة في ملفات ماركداون. إنها طريقة قوية لإضافة تفاعل ديناميكي وتضمين مكونات React داخل محتواك.
يدعم Next.js محتوى MDX المحلي داخل تطبيقك، وكذلك ملفات MDX البعيدة التي يتم جلبها ديناميكيًا من الخادم. يقوم ملحق Next.js بتحويل ماركداون ومكونات React إلى HTML، بما في ذلك دعم الاستخدام في مكونات الخادم (الافتراضي في موجه التطبيق).
@next/mdx
يُستخدم حزمة @next/mdx
لتكوين Next.js حتى يتمكن من معالجة ماركداون وMDX. تقوم بجلب البيانات من الملفات المحلية، مما يسمح لك بإنشاء صفحات بامتداد .mdx
، مباشرة في مجلد /pages
أو /app
.
لنستعرض كيفية تكوين واستخدام MDX مع Next.js.
البدء
قم بتثبيت الحزم اللازمة لعرض MDX:
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
قم بإنشاء ملف mdx-components.tsx
في جذر تطبيقك (src/
أو المجلد الأصلي لـ app/
):
معلومة مفيدة:
mdx-components.tsx
مطلوب لاستخدام MDX مع موجه التطبيق ولن يعمل بدونه.
import type { MDXComponents } from 'mdx/types'
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
}
}
export function useMDXComponents(components) {
return {
...components,
}
}
قم بتحديث ملف next.config.js
في جذر مشروعك لتكوينه لاستخدام MDX:
const withMDX = require('@next/mdx')()
/** @type {import('next').NextConfig} */
const nextConfig = {
// تكوين `pageExtensions` لتشمل ملفات MDX
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
// اختياريًا، أضف أي تكوين آخر لـ Next.js أدناه
}
module.exports = withMDX(nextConfig)
ثم، قم بإنشاء صفحة MDX جديدة داخل مجلد /app
:
your-project
├── app
│ └── my-mdx-page
│ └── page.mdx
└── package.json
الآن يمكنك استخدام ماركداون واستيراد مكونات React مباشرة داخل صفحة MDX الخاصة بك:
import { MyComponent } from 'my-components'
# مرحبًا بكم في صفحة MDX الخاصة بي!
هذا بعض النصوص **عريضة** و _مائلة_.
هذه قائمة في ماركداون:
- واحد
- اثنان
- ثلاثة
تحقق من مكون React الخاص بي:
<MyComponent />
التصفح إلى مسار /my-mdx-page
يجب أن يعرض MDX المقدم الخاص بك.
MDX البعيد
إذا كانت ملفات أو محتوى ماركداون أو MDX موجودة في مكان آخر، يمكنك جلبها ديناميكيًا من الخادم. هذا مفيد للمحتوى المخزن في مجلد محلي منفصل، نظام إدارة المحتوى (CMS)، قاعدة بيانات، أو أي مكان آخر. حزمة مجتمعية شائعة لهذا الاستخدام هي next-mdx-remote
.
معلومة مفيدة: يرجى المتابعة بحذر. يترجم MDX إلى JavaScript ويتم تنفيذه على الخادم. يجب عليك فقط جلب محتوى MDX من مصدر موثوق، وإلا يمكن أن يؤدي هذا إلى تنفيذ كود بعيد (RCE).
المثال التالي يستخدم next-mdx-remote
:
import { MDXRemote } from 'next-mdx-remote/rsc'
export default async function RemoteMdxPage() {
// نص MDX - يمكن أن يكون من ملف محلي، قاعدة بيانات، نظام إدارة محتوى، جلب، أي مكان...
const res = await fetch('https://...')
const markdown = await res.text()
return <MDXRemote source={markdown} />
}
import { MDXRemote } from 'next-mdx-remote/rsc'
export default async function RemoteMdxPage() {
// نص MDX - يمكن أن يكون من ملف محلي، قاعدة بيانات، نظام إدارة محتوى، جلب، أي مكان...
const res = await fetch('https://...')
const markdown = await res.text()
return <MDXRemote source={markdown} />
}
التصفح إلى مسار /my-mdx-page-remote
يجب أن يعرض MDX المقدم الخاص بك.
التخطيطات
لمشاركة تخطيط عبر صفحات MDX، يمكنك استخدام دعم التخطيط المدمج مع موجه التطبيق.
export default function MdxLayout({ children }: { children: React.ReactNode }) {
// إنشاء أي تخطيط أو أنماط مشتركة هنا
return <div style={{ color: 'blue' }}>{children}</div>
}
export default function MdxLayout({ children }) {
// إنشاء أي تخطيط أو أنماط مشتركة هنا
return <div style={{ color: 'blue' }}>{children}</div>
}
ملحقات Remark و Rehype
يمكنك اختياريًا توفير ملحقات remark
و rehype
لتحويل محتوى MDX.
على سبيل المثال، يمكنك استخدام remark-gfm
لدعم ماركداون بنكهة GitHub.
نظرًا لأن نظام remark
و rehype
يعمل فقط مع ESM، ستحتاج إلى استخدام next.config.mjs
كملف تكوين.
import remarkGfm from 'remark-gfm'
import createMDX from '@next/mdx'
/** @type {import('next').NextConfig} */
const nextConfig = {
// تكوين `pageExtensions` لتشمل ملفات MDX
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
// اختياريًا، أضف أي تكوين آخر لـ Next.js أدناه
}
const withMDX = createMDX({
// أضف ملحقات ماركداون هنا، كما تريد
options: {
remarkPlugins: [remarkGfm],
rehypePlugins: [],
},
})
// قم بتغليف تكوين MDX وNext.js مع بعضهما البعض
export default withMDX(nextConfig)
Frontmatter
Frontmatter هو زوج مفتاح/قيمة يشبه YAML يمكن استخدامه لتخزين بيانات حول الصفحة. لا يدعم @next/mdx
Frontmatter بشكل افتراضي، على الرغم من وجود العديد من الحلول لإضافته إلى محتوى MDX الخاص بك، مثل:
للوصول إلى بيانات وصفية للصفحة مع @next/mdx
، يمكنك تصدير كائن بيانات وصفية من داخل ملف .mdx
:
export const metadata = {
author: 'John Doe',
}
# صفحة MDX الخاصة بي
العناصر المخصصة
أحد الجوانب الممتعة لاستخدام ماركداون، هو أنها تعين إلى عناصر HTML
الأصلية، مما يجعل الكتابة سريعة وبديهية:
هذه قائمة في ماركداون:
- واحد
- اثنان
- ثلاثة
يولد ما سبق HTML
التالي:
<p>هذه قائمة في ماركداون:</p>
<ul>
<li>واحد</li>
<li>اثنان</li>
<li>ثلاثة</li>
</ul>
عندما تريد تصميم عناصرك الخاصة لمظهر مخصص لموقعك أو تطبيقك، يمكنك تمرير رموز قصيرة. هذه هي مكوناتك المخصصة التي تعين إلى عناصر HTML
.
للقيام بذلك، افتح ملف mdx-components.tsx
في جذر تطبيقك وأضف عناصر مخصصة:
import type { MDXComponents } from 'mdx/types'
import Image, { ImageProps } from 'next/image'
// يسمح لك هذا الملف بتوفير مكونات React مخصصة
// لاستخدامها في ملفات MDX. يمكنك استيراد واستخدام أي
// مكون React تريده، بما في ذلك الأنماط المضمنة،
// مكونات من مكتبات أخرى، والمزيد.
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
// يسمح بتخصيص المكونات المدمجة، مثل إضافة أنماط.
h1: ({ children }) => <h1 style={{ fontSize: '100px' }}>{children}</h1>,
img: (props) => (
<Image
sizes="100vw"
style={{ width: '100%', height: 'auto' }}
{...(props as ImageProps)}
/>
),
...components,
}
}
import Image from 'next/image'
// يسمح لك هذا الملف بتوفير مكونات React مخصصة
// لاستخدامها في ملفات MDX. يمكنك استيراد واستخدام أي
// مكون React تريده، بما في ذلك الأنماط المضمنة،
// مكونات من مكتبات أخرى، والمزيد.
export function useMDXComponents(components) {
return {
// يسمح بتخصيص المكونات المدمجة، مثل إضافة أنماط.
h1: ({ children }) => <h1 style={{ fontSize: '100px' }}>{children}</h1>,
img: (props) => (
<Image
sizes="100vw"
style={{ width: '100%', height: 'auto' }}
{...props}
/>
),
...components,
}
}
الغوص العميق: كيف تحول ماركداون إلى HTML؟
لا يفهم React ماركداون بشكل أصلي. يجب تحويل النص العادي لـ ماركداون أولاً إلى HTML. يمكن تحقيق ذلك باستخدام remark
و rehype
.
remark
هو نظام أدوات حول ماركداون. rehype
هو نفسه، ولكن لـ HTML. على سبيل المثال، تحول مقتطف الكود التالي ماركداون إلى HTML:
import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'
main()
async function main() {
const file = await unified()
.use(remarkParse) // التحويل إلى شجرة ماركداون المجردة (AST)
.use(remarkRehype) // التحويل إلى شجرة HTML المجردة (AST)
.use(rehypeSanitize) // تعقيم مدخلات HTML
.use(rehypeStringify) // تحويل AST إلى HTML متسلسل
.process('Hello, Next.js!')
console.log(String(file)) // <p>Hello, Next.js!</p>
}
يحتوي نظام remark
و rehype
على ملحقات لـ تلوين الصيغة (syntax highlighting)، ربط العناوين، إنشاء جدول محتويات، والمزيد.
عند استخدام @next/mdx
كما هو موضح أعلاه، لا تحتاج إلى استخدام remark
أو rehype
مباشرة، حيث يتم التعامل معها لك. نحن نصفها هنا لفهم أعمق لما تقوم به حزمة @next/mdx
تحت الغطاء.
استخدام مترجم MDX المبني على Rust (تجريبي)
يدعم Next.js مترجم MDX جديد مكتوب بلغة Rust. هذا المترجم لا يزال تجريبيًا ولا يُنصح باستخدامه للإنتاج. لاستخدام المترجم الجديد، تحتاج إلى تكوين next.config.js
عند تمريره إلى withMDX
:
module.exports = withMDX({
experimental: {
mdxRs: true,
},
})