دعم صيغة 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,
  },
})

روابط مفيدة

المصادر