الفرق بين المراجعتين لصفحة: «Next.js/custom document»

من موسوعة حسوب
أنشأ الصفحة ب' = المستندات المخصصة في Next.js باستخدام المكوّن <code>Document</code> = يمكن للمكوّن <code>Document</code> أن يُحدّث...'
 
لا ملخص تعديل
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:المستندات المخصصة في Next.js باستخدام المكوّن <code>Document</code>}}</noinclude>
= المستندات المخصصة في Next.js باستخدام المكوّن <code>Document</code> =
يمكن للمكوّن <code>Document</code> أن يُحدّث العنصرين <code><html></code> و <code><body></code> المستخدمان في تصيير [[Next.js/page|الصفحة]]. ويُصيّر هذا الملف في جانب الخادم فقط، وبالتالي لا يمكن استخدام معالجات الأحداث مثل <code>onClick</code> ضمن <code>document_</code>. ولكي تتجاوز المكوّن <code>Document</code> الافتراضي، أنشئ الملف <code>pages/_document.js</code> كما يلي:<syntaxhighlight lang="javascript">
يمكن للمكوّن <code>Document</code> أن يُحدّث العنصرين <code><html></code> و <code><body></code> المستخدمان في تصيير [[Next.js/page|الصفحة]]. ويُصيّر هذا الملف في جانب الخادم فقط، وبالتالي لا يمكن استخدام معالجات الأحداث مثل <code>onClick</code> ضمن <code>document_</code>. ولكي تتجاوز المكوّن <code>Document</code> الافتراضي، أنشئ الملف <code>pages/_document.js</code> كما يلي:<syntaxhighlight lang="javascript">
import { Html, Head, Main, NextScript } from 'next/document'
import { Html, Head, Main, NextScript } from 'next/document'

مراجعة 05:38، 3 يونيو 2022

يمكن للمكوّن Document أن يُحدّث العنصرين <html> و <body> المستخدمان في تصيير الصفحة. ويُصيّر هذا الملف في جانب الخادم فقط، وبالتالي لا يمكن استخدام معالجات الأحداث مثل onClick ضمن document_. ولكي تتجاوز المكوّن Document الافتراضي، أنشئ الملف pages/_document.js كما يلي:

import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

تمثل الشيفرة السابقة المكوّن Document الافتراضي الذي تضيفه Next.js، ويُسمح بالسمات المخصصة كخاصيات. فقد ترغب مثلًا في إضافة lang="en" إلى العنصر <html>:

<Html lang="en">

أو أن تضيف السمة className إلى العنصر body:

<body className="bg-white">

ولا بد من استخدام المكوّنات <Html> و </ Head> و </ Main> و < /NextScript> حتى تُصيًر الصفحة بالشكل الصحيح.

التحفظات على استخدام document

  • يختلف المكوّن </ Head> الذي يُستخدم في _document عن مكوّن الترويسة next/head، إذ ينبغي أن يُستخدم هنا للترويسات <head> المشتركة بين عدة صفحات فقط. أما في بقية الحالات مثل حالة استخدام العنصر <title>، فننصح باستخدام next/head في صفحتك أو مكوّناتك.
  • لا تُهيأ مكوّنات الموجودة خارج من قبل المتصفج، فلا تضع فيها ما يخص منطق التطبيق أو تنسيقات CSS مخصصة (مثل ). وإن أردت مكوّنات تتشاركها جميع صفحاتك (كالقوائم أو شريط الأدوات) استخدم المكوّن layout.
  • لا يدعم المكوّن document حاليًا طرق إحضار البيانات في مثل getStaticProps أو getServerSideProps.

تخصيص التابع renderPage

تنويه: هذا الموضوع متقدم ويُستخدم فقط لتدعم المكتبات مثل CSS-in-JS للتصيير من جانب الخادم. لن تحتاج إلى ذلك عند استخدام الدعم المدمج لتنسيقات styled-jsx.

ننصحك أن تتحاشي استخدام نسخ مخصصة من الدالة getInitialProps والتابع renderPage قدر الإمكان وذلك استعدادًا لمتطلبات React 18. يكافئ الكائن الذي نعرضه في الشيفرة التالية الكائن الذي تتلقاه في الدالة getInitialProps بالإضافة إلى التابع renderPage:

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const originalRenderPage = ctx.renderPage

    //بشكل متزامن React شغّل منطق تصيير 
    ctx.renderPage = () =>
      originalRenderPage({
        // React يفيد في تغليف كامل شجرة 
        enhanceApp: (App) => App,
        // يفيد في التغليف على أساس الصفحة
        enhanceComponent: (Component) => Component,
      })
    //`renderPage` إذ تضم الآن التابع المخصص getInitialProps شغّل الدالة الأب 

    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

ملاحظة: لا تُستدعى الدالة getInitialProps ضمن المستند المخصص document_ أثناء التنقلات من جانب العميل.

استخدام TypeScript مع المستندات المخصصة في Next.js

بإمكانك استخدام النوع المدمج DocumentContext وتغيّر اسم الملف إلى pages/_document.tsx/. كالتالي:

import Document, { DocumentContext } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }
}

export default MyDocument

المصادر