الفرق بين المراجعتين لصفحة: «Next.js/custom document»
لا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(مراجعتان متوسطتان بواسطة مستخدمين اثنين آخرين غير معروضتين) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: | <noinclude>{{DISPLAYTITLE:استخدام مستند مخصص Document في Next.js}}</noinclude> | ||
يمكن للمكوّن <code>Document</code> أن يُحدّث العنصرين <code><html></code> و <code><body></code> المستخدمان في تصيير [[Next.js/ | '''ملاحظة''': بدأت Next.js في الإصدار 13 دعم استخدام المجلد <code>/app</code> كنسخة تجريبية، ويمكن باستعمال المجلد ذاك دعم التخطيطات layouts والوجهات المتداخلة nested routes واستعمال مكونات خادم Server افتراضيًا، كما يمكنك جلب بيانات تُستعمل في كل تطبيقك. | ||
يمكن للمكوّن <code>Document</code> أن يُحدّث العنصرين <code>[[HTML/html|<html>]]</code> و <code>[[HTML/body|<body>]]</code> المستخدمان في تصيير [[Next.js/pages|صفحة 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' | ||
سطر 14: | سطر 16: | ||
) | ) | ||
} | } | ||
</syntaxhighlight>تمثل الشيفرة السابقة المكوّن <code>Document</code> الافتراضي الذي تضيفه Next.js، ويُسمح بالسمات المخصصة | </syntaxhighlight>تمثل الشيفرة السابقة المكوّن <code>Document</code> الافتراضي الذي تضيفه Next.js، ويُسمح بالسمات المخصصة على شكل خاصيات. فقد ترغب مثلًا في إضافة <code>lang="en"</code> إلى العنصر <code><html></code>:<syntaxhighlight lang="html"> | ||
<Html lang="en"> | <Html lang="en"> | ||
</syntaxhighlight>أو أن تضيف السمة <code>className</code> إلى العنصر <code>body</code>:<syntaxhighlight lang="html"> | </syntaxhighlight>أو أن تضيف السمة <code>className</code> إلى العنصر <code>body</code>:<syntaxhighlight lang="html"> | ||
سطر 20: | سطر 22: | ||
</syntaxhighlight>ولا بد من استخدام المكوّنات <code><Html></code> و <code></ Head></code> و <code></ Main></code> و <code>< /NextScript></code> حتى تُصيًر الصفحة بالشكل الصحيح. | </syntaxhighlight>ولا بد من استخدام المكوّنات <code><Html></code> و <code></ Head></code> و <code></ Main></code> و <code>< /NextScript></code> حتى تُصيًر الصفحة بالشكل الصحيح. | ||
== | == محاذير == | ||
* يختلف المكوّن <code></ Head></code> الذي يُستخدم في <code> | * يختلف المكوّن <code></ Head></code> الذي يُستخدم في <code>document_</code> عن مكوّن الترويسة <code>[[Next.js/next head|next/head]]</code>، إذ ينبغي أن يُستخدم هنا للترويسات <code>[[HTML/head|<head>]]</code> المشتركة بين عدة صفحات فقط. أما في بقية الحالات مثل حالة استخدام العنصر <code>[[HTML/title|<title>]]</code>، فننصح باستخدام <code>next/head</code> في صفحتك أو مكوّناتك. | ||
* لا تُهيأ مكوّنات الموجودة خارج من قبل | * لا تُهيأ مكوّنات [[React]] الموجودة خارج <code></ Main></code> من قبل المتصفح، فلا تضع فيها ما يخص منطق التطبيق أو تنسيقات CSS مخصصة (مثل styled-jsx ). وإن أردت مكوّنات تتشاركها جميع صفحاتك (كالقوائم أو شريط الأدوات) استخدم المكوّن [[Next.js/layouts|<code>layout</code>]]. | ||
* لا يدعم المكوّن <code> | * لا يدعم المكوّن <code>Document</code> حاليًا طرق إحضار البيانات في Next.js مثل <code>getStaticProps</code> أو <code>getServerSideProps</code>. | ||
== تخصيص التابع <code>renderPage</code> == | == تخصيص التابع <code>renderPage</code> == | ||
<blockquote>'''تنويه''': هذا الموضوع متقدم ويُستخدم فقط لتدعم المكتبات مثل CSS-in-JS للتصيير من جانب الخادم. لن تحتاج إلى ذلك عند استخدام الدعم المدمج لتنسيقات <code>styled-jsx</code>.</blockquote>ننصحك أن | <blockquote>'''تنويه''': هذا الموضوع متقدم ويُستخدم فقط لتدعم المكتبات مثل CSS-in-JS للتصيير من جانب الخادم. لن تحتاج إلى ذلك عند استخدام الدعم المدمج لتنسيقات <code>styled-jsx</code>.</blockquote>ننصحك أن تتحاشى استخدام نسخ مخصصة من الدالة <code>getInitialProps</code> والتابع <code>renderPage</code> قدر الإمكان وذلك استعدادًا لمتطلبات [[Next.js/react 18|React 18]]. ويكافئ الكائن <code>ctx</code> الذي نعرضه في الشيفرة التالية الكائن الذي تتلقاه في الدالة <code>getInitialProps</code> بالإضافة إلى التابع <code>renderPage</code>:<syntaxhighlight lang="javascript"> | ||
import Document, { Html, Head, Main, NextScript } from 'next/document' | import Document, { Html, Head, Main, NextScript } from 'next/document' | ||
سطر 67: | سطر 67: | ||
</syntaxhighlight><blockquote>'''ملاحظة''': لا تُستدعى الدالة <code>getInitialProps</code> ضمن المستند المخصص <code>document_</code> أثناء التنقلات من جانب العميل.</blockquote> | </syntaxhighlight><blockquote>'''ملاحظة''': لا تُستدعى الدالة <code>getInitialProps</code> ضمن المستند المخصص <code>document_</code> أثناء التنقلات من جانب العميل.</blockquote> | ||
== استخدام TypeScript | == استخدام TypeScript == | ||
بإمكانك استخدام النوع المدمج <code>DocumentContext</code> وتغيّر اسم الملف إلى <code>pages/_document.tsx/.</code> كالتالي:<syntaxhighlight lang="javascript"> | بإمكانك استخدام النوع المدمج <code>DocumentContext</code> وتغيّر اسم الملف إلى <code>pages/_document.tsx/.</code> كالتالي:<syntaxhighlight lang="javascript"> | ||
import Document, { DocumentContext } from 'next/document' | import Document, { DocumentContext } from 'next/document' | ||
سطر 85: | سطر 85: | ||
* الصفحة [https://nextjs.org/docs/advanced-features/custom-document Custom Document] من توثيق Next.js الرسمي. | * الصفحة [https://nextjs.org/docs/advanced-features/custom-document Custom Document] من توثيق Next.js الرسمي. | ||
[[تصنيف:Next.js|{{SUBPAGENAME}}]] | |||
[[تصنيف:Next.js Advanced Features|{{SUBPAGENAME}}]] |
المراجعة الحالية بتاريخ 17:08، 3 يناير 2023
ملاحظة: بدأت Next.js في الإصدار 13 دعم استخدام المجلد /app
كنسخة تجريبية، ويمكن باستعمال المجلد ذاك دعم التخطيطات layouts والوجهات المتداخلة nested routes واستعمال مكونات خادم Server افتراضيًا، كما يمكنك جلب بيانات تُستعمل في كل تطبيقك.
يمكن للمكوّن Document
أن يُحدّث العنصرين <html>
و <body>
المستخدمان في تصيير صفحة Page. ويُصيّر هذا الملف في جانب الخادم فقط، وبالتالي لا يمكن استخدام معالجات الأحداث مثل 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>
حتى تُصيًر الصفحة بالشكل الصحيح.
محاذير
- يختلف المكوّن
</ Head>
الذي يُستخدم فيdocument_
عن مكوّن الترويسةnext/head
، إذ ينبغي أن يُستخدم هنا للترويسات<head>
المشتركة بين عدة صفحات فقط. أما في بقية الحالات مثل حالة استخدام العنصر<title>
، فننصح باستخدامnext/head
في صفحتك أو مكوّناتك. - لا تُهيأ مكوّنات React الموجودة خارج
</ Main>
من قبل المتصفح، فلا تضع فيها ما يخص منطق التطبيق أو تنسيقات CSS مخصصة (مثل styled-jsx ). وإن أردت مكوّنات تتشاركها جميع صفحاتك (كالقوائم أو شريط الأدوات) استخدم المكوّنlayout
. - لا يدعم المكوّن
Document
حاليًا طرق إحضار البيانات في Next.js مثلgetStaticProps
أوgetServerSideProps
.
تخصيص التابع renderPage
تنويه: هذا الموضوع متقدم ويُستخدم فقط لتدعم المكتبات مثل CSS-in-JS للتصيير من جانب الخادم. لن تحتاج إلى ذلك عند استخدام الدعم المدمج لتنسيقات
styled-jsx
.
ننصحك أن تتحاشى استخدام نسخ مخصصة من الدالة getInitialProps
والتابع renderPage
قدر الإمكان وذلك استعدادًا لمتطلبات React 18. ويكافئ الكائن ctx
الذي نعرضه في الشيفرة التالية الكائن الذي تتلقاه في الدالة 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
بإمكانك استخدام النوع المدمج 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
المصادر
- الصفحة Custom Document من توثيق Next.js الرسمي.