مستند مخصص

يمكن للمستند المخصص Document تحديث وسوم <html> و <body> المستخدمة في عرض الصفحة.

للتجاوز عن المستند الافتراضي Document، قم بإنشاء ملف pages/_document كما هو موضح أدناه:

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

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}
import { Html, Head, Main, NextScript } from 'next/document'

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

معلومة مفيدة

  • يتم عرض _document فقط على الخادم، لذا لا يمكن استخدام معالجات الأحداث مثل onClick في هذا الملف.
  • مكونات <Html> و <Head /> و <Main /> و <NextScript /> مطلوبة لعرض الصفحة بشكل صحيح.

محاذير

  • مكون <Head /> المستخدم في _document ليس هو نفسه next/head. يجب استخدام مكون <Head /> هنا فقط لأي كود <head> مشترك بين جميع الصفحات. لجميع الحالات الأخرى، مثل وسوم <title>، نوصي باستخدام next/head في صفحاتك أو مكوناتك.
  • لن يتم تهيئة مكونات React خارج <Main /> بواسطة المتصفح. لا تضيف منطق التطبيق هنا أو CSS مخصص (مثل styled-jsx). إذا كنت بحاجة إلى مكونات مشتركة في جميع صفحاتك (مثل قائمة أو شريط أدوات)، اقرأ التخطيطات بدلاً من ذلك.
  • لا يدعم Document حاليًا طرق جلب البيانات في Next.js مثل getStaticProps أو getServerSideProps.

تخصيص renderPage

يعد تخصيص renderPage متقدمًا ومطلوبًا فقط لمكتبات مثل CSS-in-JS لدعم العرض من جانب الخادم (SSR). هذا غير مطلوب لدعم styled-jsx المدمج.

لا نوصي باستخدام هذا النمط. بدلاً من ذلك، ضع في اعتبارك التبني التدريجي لموجه التطبيق (App Router)، والذي يسمح لك بجلب البيانات بسهولة أكبر لـ الصفحات والتخطيطات.

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

class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const originalRenderPage = ctx.renderPage

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

    // تشغيل `getInitialProps` الأصلية، وهي الآن تتضمن `renderPage` المخصصة
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument
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,
      })

    // تشغيل `getInitialProps` الأصلية، وهي الآن تتضمن `renderPage` المخصصة
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

معلومة مفيدة

  • لا يتم استدعاء getInitialProps في _document أثناء الانتقالات من جانب العميل.
  • كائن ctx لـ _document يعادل الكائن المستلم في getInitialProps، مع إضافة renderPage.