مستند مخصص

يمكن للمستند 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.