استخدام 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 أو 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
استخدام التخطيطات
إن أردت إضافة تخطيط إلى صفحة 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 على تهيئة العنصر المخصص.
المصادر
- الصفحة Using MDX with Next.js من توثيق Next.js الرسمي.