دعم صيغة MDX في Next.js
تُعد صيغة MDX صيغة موّسعة التي تُشتق منها تنسيقات ماركداون markdown والتي تتيح لك بدورها كتابة شيفرة JSX في ملفات ماركداون markdown. وهي طريقة سريعة لإضافة تفاعلية ديناميكية ومكوّنات مضمّنة ضمن المحتوى الذي تقدّمه مما يجعل صفحاتك أكثر حيوية.
تدعم Next.js صيغة MDX بطرق مختلفة، وسنرشدك في هذه الصفحة إلى بعض طرق تكامل MDX مع تطبيقات Next.js.
لماذا نستخدم MDX؟
إن كتابة المحتوى بتنسيق ماركداون markdown هي طريقة حدسية نظرًا لبساطة قواعد التنسيق التي تمكّنك -عندما تألفها- من كتابة محتوى سهل القراءة والتعديل. ونظرًا لإمكانية استخدام عناصر HTML
في ملفات markdown، ستتمكن من تنسيق هذه الملفات بطريقة إبداعية.
وطالما أن محتويات ماركداون markdown هي محتويات ساكنة، لا يمكنك إنشاء محتوى ديناميكي يعتمد على تفاعل المستخدم. وتظهر روعة MDX في قدرتها على استخدام مكوّنات React مباشرة في توصيفها، وهذا ما يفتح مجالًا واسعًا من الإمكانيات عند تأليف صفحات ويب مع الأخذ بعين الاعتبار تفاعلية هذه الصفحات.
إضافات MXD
تستخدم MDX داخليًا كل من remark و rehype. يُعد Remark معالجًا مدعّمًا بمحيط من الإضافات plugins التي تساعدك على تحليل الشيفرة وتحويل عناصر HTML
وتغيير الصياغة واستخلاص بيانات Frontmatter وغير ذلك. بينما يُعد Rehype معالج HTML
مدعومًا أيضًا بمحيط من الإضافات التي تساعدك على إجراء التعديلات على البيانات وتنظيفها وتصريفها وتهيئتها، ويعد استخدام remark-gfm خيارًا شائعًا.
ملاحظة: عليك أن تشير إلى أية إضافة من إضافات remark أو rehype تريد استخدامها وذلك ضمن إعدادات الحزمة MDX.
استخدام الحزمة next/mdx@
تُهيّأ الحزمة next/mdx@
ضمن الملف next.config.js
في مشروعك. تأتي بياناتها المصدرية من ملفاتك، وتسمح لك بإنشاء صفحات لها الإمتداد mdx.
مباشرة في المجلد pages/
.
إعداد الحزمة next/mdx@
في Next.js
تشرح لك الخطوات التالية طريقة إعداد next/mdx@
في مشروعك:
أولًا: ثبِّت الحزم اللازمة:
npm install @next/mdx @mdx-js/loader
ثانيًا: اطلب هذه الحزم وهيئها لدعم صفحات mdx.
ذات المستوى الأعلى. تُضيف الشيفرة التالية الكائن المفتاحي options
الذي يتيح لك المرور إلي أية إضافات:
// next.config.js
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [],
rehypePlugins: [],
//أزل التعليق عن السطر التالي `MDXProvider` إن كنت تستخدم
// providerImportSource: "@mdx-js/react",
},
})
module.exports = withMDX({
//MXD ربط القيمة الافتراضية بامتدادات
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
})
ثالثًا: أنشئ صفحة MDX جديدة ضمن المجلد pages/
:
- /pages
- my-mdx-page.mdx
- package.json
استخدام المكوّنات والتخطيطيات والعناصر المخصصة
بإمكانك الآن إدراج مكوّنات React مباشرة ضمن صفحة MDX:
import { MyComponent } from 'my-components'
# My MDX page
This is a list in markdown:
- One
- Two
- Three
Checkout my React component:
<MyComponent/>
استخلاص بيانات Frontmatter
يُعد Frontmatter تنسيق بيانات على شكل أزواج مفتاح/قيمة يشبه تنسيق YAML، ويُستخدم لتخزين بيانات وصفية عن الصفحة. لا يدعم next/mdx@
تنسيق frontmatter افتراضيًا لكن هناك حلول عديدة لإضافته إلى محتوى MDX مثل الإضافة gray-matter.
للوصول إلى البيانات الوصفية للصفحة من خلال next/mdx@
، يمكنك تصدير كائن بيانات وصفية ضمن الملف mdx.
:
export const meta = {
author: 'Rich Haines'
}
# My MDX page
استخدام التخطيطات Layouts
إن أردت إضافة تخطيط إلى صفحة MDX، أنشئ مكوّنًا جديدًا وأدرجه ضمن الصفحة، ومن ثم غلّف الصفحة ضمن مكوّن تخطيط :
import { MyComponent, MyLayoutComponent } from 'my-components'
export const meta = {
author: 'Rich Haines'
}
# My MDX Page with a Layout
This is a list in markdown:
- One
- Two
- Three
Checkout my React component:
<MyComponent/>
export default ({ children }) => <MyLayoutComponent meta={meta}>{children}</MyLayoutComponent>
العناصر المخصصة
من الميزات الرائعة لتنسيق markdown هو إمكانية ربط التنسيقات بعناصر HTML
المقابلة مما يُسرّع الإنجاز:
# H1 heading
## H2 heading
This is a list in markdown:
- One
- Two
- Three
ستوّلد التنسيقات السابقة عناصر HTML
التالية:
<h1>H1 heading</h1>
<h2>H2 heading</h2>
<p>This is a list in markdown:</p>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
وإن أردت تنسيق عناصرك الخاصة لإضفاء لمستك على التطبيق، يمكنك تمرير شيفرة مختصرة shortcodes، وهي مكوّناتك الخاصة التي تقترن بعناصر HTML
. ولتنفيذ الأمر، استخدم المزوّد MDXProvider
لتمرير كائن مكوّنات على شكل خاصية. يرتبط كل كائن من هذه الكائنات باسم عنصر HTML
. ولكي تفعّل الميزة، لا بد من تحديد الخيار "providerImportSource: "@mdx-js/react
في الملف next.config.js
:
// next.config.js
const withMDX = require('@next/mdx')({
// ...
options: {
providerImportSource: '@mdx-js/react',
},
})
هيئ بعد ذلك المزوّد في صفحتك:
// pages/index.js
import { MDXProvider } from '@mdx-js/react'
import Image from 'next/image'
import { Heading, InlineCode, Pre, Table, Text } from 'my-components'
const ResponsiveImage = (props) => (
<Image alt={props.alt} layout="responsive" {...props} />
)
const components = {
img: ResponsiveImage,
h1: Heading.H1,
h2: Heading.H2,
p: Text,
pre: Pre,
code: InlineCode,
}
export default function Post(props) {
return (
<MDXProvider components={components}>
<main {...props} />
</MDXProvider>
)
}
إن أردت توسيع استخدام العنصر ليشمل كامل الموقع، أضف المزوّد إلى الملف app.js_
لكي تتعرف كل صفحات MDX على تهيئة العنصر المخصص.
استخدام مصرف MDX يعتمد على لغة Rust (تجريبي)
تدعم Next.js مصرف MDX جديد مكتوبة بلغة Rust ولكنه قيد التجربة والتطوير حاليًا ولا يُنصح باستعماله في بيئة إنتاجية.
لاستعمال هذا المصرف، تحتاج إلى التصريح عن ذلك في ملف next.config.js بالشكل التالي:
// next.config.js
module.exports = withMDX({
experimental: {
mdxRs: true,
},
})
روابط مفيدة
المصادر
- الصفحة Using MDX with Next.js من توثيق Next.js الرسمي.