نمط استعراض الصفحات في Next.js

من موسوعة حسوب

تنبيه: تُخصص صفحة التوثيق هذه للنسخة 9.3 من Next.js والنسخ الأعلى.

تحدثنا في توثيق صفحات Next.js وتوثيق إحضار البيانات عن كيفية تصيير الصفحات مسبقًا أثناء بناء التطبيق (التوليد الساكن Static Generation) باستخدام getStaticProps و getStaticPaths.

تظهر فائدة التوليد الساكن في إحضار البيانات من منظومة إدارة محتوى دون واجهة headless CMS، لكنه ليس مثاليًا عندما تضيف مسودة في منظومة إدارة المحتوى تلك دون واجهة وتريد استعراض مسوّدة عملك مباشرة على الصفحة. فقد ترغب في هذه الحالة في تصيير صفحتك عند الطلب بدل تصييرها أثناء بناء التطبيق، وإحضار محتوى المسودة بدلًا من المحتوى المنشور. أي قد ترغب بتجاوز التوليد الساكن في هذه الحالة بالتحديد.

تمتلك Next.js ميزة تُدعى نمط الاستعراض Preview Mode لحل هذا الأمر. وإليك طريقة استخدامه.

الخطوة الأولى: أنشئ مسار API للاستعراض وانتقل إليه

تلميح: الق نظرة أولًا على توثيق مسارات API إن لم تكن على دراية بها.

أنشئ أولًا مسار API لاستعراض الصفحة وسمِّه ما تشاء مثل pages/api/preview.js أو (استخدم الامتداد ts. إن كنت تستخدم TypeScript). عليك أن تستدعي ضمن هذا المسار الدالة setPreviewData من خلال كائن الاستجابة res، وينبغي أن يكون وسيطها كائنًا قد يُستخدم لاحقًا مع الدالة getStaticProps. أما الآن فسنستخدم القوسين الفارغين {}.

 export default function handler(req, res) {
  // ...  
  res.setPreviewData({})
  // ...
}

تهيئ الدالة res.setPreviewData بعض ملفات تعريف الارتباط cookies في المتصفح والتي تفعّل نمط الاستعراض. تُعد أية طلبات تتضمن ملفات تعريف الارتباط تلك ضمن نمط الاستعراض، ويتغير سلوك التوليد الساكن للصفحات. بإمكانك اختبار الأمر يدويًا، بإنشاء مسار API كما في المثال التالي والولوج إليه من خلال المتصفح:

// مثال بسيط للاختبار اليدوي
//موجودًا pages/api/preview.js إن كان المسار
//ضمن المتصفح api/preview افتح الصفحة 
export default function handler(req, res) {
  res.setPreviewData({})
  res.end('Preview mode enabled')
}

قد تلاحظ إن كنت تستخدم أدوات مطوري ويب أن ملفات تعريف ارتباط prerender_bypass__ و next_preview_data__ ستُهيئ عند إرسال هذا الطلب.

الولوج الآمن إلى الصفحة من منظومة إدارة محتوى دون واجهة

قد ترغب عمليًا باستدعاء مسار API بشكل آمن من منظومة إدارة محتوى CMS، وستختلف خطوات إنجاز الأمر وفقًا للمنظومة التي تستخدمها. لهذا سنستعرض بعض الخطوات الشائعة التي يمكنك اتخاذها. تفترض هذه الخطوات أن المنظومة التي تستخدمها تدعم ضبط عناوين URL مخصصة للاستعراض، فإن لم تكن كذلك، ستبقى قادرًا على استخدام هذه الطريقة لتأمين عناوين الاستعراض، لكن عليك أن تبني وتلج إلى هذه العناوين يدويًا.

أولًا، عليك إنشاء مفتاح استيثاق نصي سري مستخدمًا موّلد مفاتيح استيثاق token تختاره، وسيعرفه فقط تطبيق Next.js والمنظومة. وهكذا لن يتمكن الأشخاص الذين لا يُسمح لهم بدخول المنظومة من الوصول إلى عناوين URL.

ثانيًا، إن كانت تدعم منظومة إدارة المحتوى التي لا تستخدم الترويسات ضبط عناوين استعراض مخصصة، حدد العنوان التالي كعنوان URL للاستعراض (على افتراض أن وجهة مسار API هي pages/api/preview.js).

https://<your-site>/api/preview?secret=<token>&slug=<path>

يتألف من الأقسام التالية:

  • <your-site>: اسم نطاق التطوير الخاص بك.
  • <token>: يُستبدل بمفتاح الاستيثاق الذي ولّدته.
  • <path>: مسار الصفحة التي تريد استعراضها. فإن أردت استعراض الصفحة posts/foo/ مثلًا، عليك أن تستخدم slug=/posts/foo&. وقد تسمح لك المنظومة بأن تضع متغيرًا في عنوان الاستعراض، وبالتالي يمكن أن يُضبط المسار <path> ديناميكيًا وفقًا لبيانات المنظومة كالتالي: slug=/posts/{entry.fields.slug}&.

أخيرًا، نفّذ ما يلي في مسار API الخاص بالاستعراض:

  • تأكد من تطابق مفتاح الاستيثاق، وأن معاملات slug موجودة (ينبغي أن يخفق الطلب إن لم تكن موجودة).
  • استدع الدالة res.setPreviewData.
  • وجّه المتصفح إلى المسار المحدد في <path> (يستخدم المثال التالي التوجيه 307 إعادة توجيه مؤقت).
export default async (req, res) => {
  // تأكد من تطابق مفتاح الاستيثاق والمعاملات 
  //يجب أن يُعرف فقط من قبل التطبيق ومنظومة إدارة المحتوى
  if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
    return res.status(401).json({ message: 'Invalid token' })
  }

  //`slug` تأكد من وجود معاملات 
  // CMS منطق إحضارات البيانات من منظومة getPostBySlug ستنجز الدالة 
  const post = await getPostBySlug(req.query.slug)

  //موجودة `slug` لا تمكّن نمط الاستعراض ما لم تكن 
  if (!post) {
    return res.status(401).json({ message: 'Invalid slug' })
  }

  // مكّن نمط الاستعراض من خلال ضبط ملفات تعريف الارتباط
  res.setPreviewData({})

  // أعد التوجيه إلى المسار الذي أُحضر
  //لأن ذلك قد يسبب ضعفًا req.query.slug لا نعيد التوجيه إلى 
  res.redirect(post.slug)
}

إن نجح الأمر، سينتقل بك المتصفح إلى الوجهة التي تريد استعراضها بعد ضبط ملفات تعريف الارتباط التي تفعّل نمط الاستعراض.

الخطوة الثانية: حدّث قيم الخاصيات باستخدام getStaticProps

تقتضي الخطوة التالية تحديث getStaticProps لدعم نمط الاستعراض. فإن طلبت صفحة تحتوي getStaticProps وقد ضُبطت ملفات تعريف الارتباط فيها على وضع الاستعراض (من خلال res.setPreviewData)، عندها تُستدعى الدالة getStaticProps عند الطلب بدلًا من وقت البناء.

إضافة إلى ذلك، تُستدعى الدالة مع الكائن context إذ:

  • يحمل context.preview القيمة true.
  • context.previewData هو نفسه الوسيط المستخدم في setPreviewData.
export async function getStaticProps(context) {
  // إن استدعيت الصفحة وقد ضُبطت ملفات تعريف الارتباط على نمط الاستعراض
  //
  // سيكون محققًا context.preview 
  // هو نفسه الوسيط المستخدم في context.previewData 
  // `setPreviewData`
}

لقد استخدمنا الدالة ({})res.setPreviewData في مسار API الخاص بالاستعراض، لذا ستكون قيمة context.previewData هي {}. يمكن الاستفادة من ذلك في تمرير معلومات جلسة العمل من مسار API الخاص بالاستعراض إلى getStaticProps عند الحاجة. وسيكون context.params متاحًا إيضًا إن كنت تستخدم getStaticPaths.

إحضار بيانات الاستعراض

يمكنك تحديث getStaticProps لإحضار البيانات المختلفة وفقًا للخاصية context.preview أو/و context.previewData. فقد تمتلك منظومة إدارة المحتوى CMS لديك على سبيل المثال وصلات API مختلفة لمسودات المنشورات، وبالتالي ستتمكن حينها من استخدام context.preview لتعديل عنوان URL لوصلة API كما يلي:

export async function getStaticProps(context) {
  // API إلى وصلة "/preview" محققًا اربط context.preview إن كان 
  //  سيختلف طلب البيانات التجريبية (المسودة)
  // عن بيانات النشر وفقًا لمنظومة إدارة المحتوى التي لا تحمل ترويسات
  const res = await fetch(`https://.../${context.preview ? 'preview' : ''}`)
  // ...
}

فإن ولجت الآن إلى مسار API باستخدام secret و slug من خلال منظومة إدارة محتوى دون واجهة headless CMS أو يدويًا، من المفترض أن ترى المحتوى الذي تنوي استعراضه. وإن حدَّثت مسودتك دون أن تنشرها، من المفترض أن تكون قادرًا على استعراضها أيضًا:

# للاستعراض URL يضبط ما يلي عنوان
# من خلال منظومة إدارة محتوى أو يدويًا وستكون قادرًا على استعراض المحتوى
https://<your-site>/api/preview?secret=<token>&slug=<path>

تفاصيل أكثر عن نمط الاستعراض في Next.js

إليك بعض التفاصيل الهامة التي تتعلق بنمط الاستعراض.

ملاحظة: أثناء التصيير يوفر next/router الراية isPreview، وارجع إلى قسم الكائن router لمزيد من التفاصيل.

حذف ملفات تعريف ارتباط نمط الاستعراض

لا توجد مدة إنتهاء صلاحية محددة افتراضيًا لملفات تعريف الارتباط، وبالتالي ستنتهي جلسة الاستعراض مع إغلاق المتصفح.

لإزالة ملفات تعريف الارتباط لنمط الاستعراض يدويًا، أنشئ مسار API يستدعي الدالة ()clearPreviewData:

// pages/api/clear-preview-mode-cookies.js

export default function handler(req, res) {
  res.clearPreviewData()
}

أرسل بعد ذلك طلبًا إلى api/clear-preview-mode-cookies/ لتفعيل مسار API. وإن كنت تستدعي هذا المسار مستخدمًا المكوّن next/link، فلا بد من تمرير prefetch={false} لمنع استدعاء clearPreviewData خلال الإحضار المسبق للرابط.

تحديد المدة الزمنية لنمط الاستعراض

تأخذ الدالة setPreviewData معاملًا اختياريًا ثانيًا يُفترض أن يكون كائن خيارات. يقبل هذا الكائن المفاتيح التالية:

  • maxAge: يحدد عدد الثواني التي ينبغي أن تدومها جلسة العمل.
  • path: يحدد المسار الذي يجب لملفات تعريف الارتباط أن ترتبط به، وقيمته الافتراضية / الذي يفعل وضع الاستعراض لكل المسارات.
setPreviewData(data, {
  maxAge: 60 * 60, //تبقى ملفات تعريف الارتباط الخاصة بالاستعراض ساعة
  path: '/about', // فقط /about تطبق ملفات تعريف الارتباط لوضع الاستعراض مع مسار
})

حدود حجم بيانات الاستعراض previewData

بإمكانك تمرير كائن إلى الدالة setPreviewData ومن ثم جعله متاحًا للاستخدام من قبل الدالة getStaticProps. لكن ونظرًا لتخزين البيانات في ملفات تعريف الارتباط، فهنالك محدودية في حجم الكائن، وتحدد حاليًا بحوالي 2 كيلوبايت.

العمل مع الدالة getServerSideProps

يعمل نمط الاستعراض مع الدالة getServerSideProps أيضًا، وسيكون متاحًا مع الكائن context الذي يضم preview و previewData.

العمل مع مسارات API

يمكن لمسارات API الوصول إلى قيم preview و previewData ضمن كائن الطلب req. إليك مثالًا:

export default function myApiRoute(req, res) {
  const isPreview = req.preview
  const previewData = req.previewData
  // ...
}

مفاتيح وملفات ارتباط خاصة لكل عملية بناء next build

تتغير قيم ملفات تعريف الارتباط التي تفرض حالة الاستعراض ومفتاح الاستيثاق لتشفير بيانات previewData مع اكتمال كل عملية بناء next build. يضمن ذلك عدم القدرة على تخمين قيم ملفات تعريف الارتباط.

ملاحظة: عليك أن تسمح باستخدام ملفات تعريف ارتباط مصدرها طرف آخر وإذنًا بالوصول إلى التخزين المحلي، لاختبار نمط الاستعراض محليًا ضمن متصفحك عبر طلبات HTTP.

أمثلة

اقرأ أيضًا

المصادر

  • الصفحة Preview Mode من توثيق Next.js الرسمي.