الصفحات والتخطيطات
نوصي بقراءة صفحات أساسيات التوجيه وتحديد المسارات قبل المتابعة.
قدم موجه التطبيق (App Router) في Next.js 13 اصطلاحات ملفات جديدة لإنشاء صفحات، تخطيطات مشتركة، وقوالب بسهولة. سيرشدك هذا الصفحة حول كيفية استخدام هذه الملفات الخاصة في تطبيق Next.js الخاص بك.
الصفحات
الصفحة هي واجهة مستخدم فريدة لمسار معين. يمكنك تعريف الصفحات عن طريق تصدير مكون من ملف page.js
. استخدم المجلدات المتداخلة لتحديد مسار وملف page.js
لجعل المسار متاحًا للجمهور.
أنشئ صفحتك الأولى عن طريق إضافة ملف page.js
داخل مجلد app
:

// `app/page.tsx` هو واجهة المستخدم لمسار `/`
export default function Page() {
return <h1>مرحبًا، الصفحة الرئيسية!</h1>
}
// `app/page.js` هو واجهة المستخدم لمسار `/`
export default function Page() {
return <h1>مرحبًا، الصفحة الرئيسية!</h1>
}
// `app/dashboard/page.tsx` هو واجهة المستخدم لمسار `/dashboard`
export default function Page() {
return <h1>مرحبًا، صفحة لوحة التحكم!</h1>
}
// `app/dashboard/page.js` هو واجهة المستخدم لمسار `/dashboard`
export default function Page() {
return <h1>مرحبًا، صفحة لوحة التحكم!</h1>
}
جيد أن تعرف:
- الصفحة دائمًا هي ورقة الشجرة لشجرة المسار الفرعية.
- يمكن استخدام امتدادات الملفات
.js
أو.jsx
أو.tsx
للصفحات.- ملف
page.js
مطلوب لجعل جزء المسار متاحًا للجمهور.- الصفحات هي مكونات خادم (Server Components) افتراضيًا ولكن يمكن تعيينها كمكون عميل (Client Component).
- يمكن للصفحات جلب البيانات. راجع قسم جلب البيانات لمزيد من المعلومات.
التخطيطات
التخطيط هو واجهة مستخدم مشتركة بين عدة صفحات. عند التنقل، تحافظ التخطيطات على الحالة، تبقى تفاعلية، ولا تعيد التصيير. يمكن أيضًا تداخل التخطيطات.
يمكنك تعريف تخطيط عن طريق تصدير مكون React افتراضي من ملف layout.js
. يجب أن يقبل المكون خاصية children
التي سيتم تعبئتها بتخطيط فرعي (إذا كان موجودًا) أو صفحة فرعية أثناء التصيير.

export default function DashboardLayout({
children, // سيكون صفحة أو تخطيط متداخل
}: {
children: React.ReactNode
}) {
return (
<section>
{/* ضع واجهة المستخدم المشتركة هنا مثل رأس أو شريط جانبي */}
<nav></nav>
{children}
</section>
)
}
export default function DashboardLayout({
children, // سيكون صفحة أو تخطيط متداخل
}) {
return (
<section>
{/* ضع واجهة المستخدم المشتركة هنا مثل رأس أو شريط جانبي */}
<nav></nav>
{children}
</section>
)
}
جيد أن تعرف:
- يسمى التخطيط الأعلى بـ تخطيط الجذر (Root Layout). هذا التخطيط مطلوب ويتم مشاركته عبر جميع الصفحات في التطبيق. يجب أن تحتوي تخطيطات الجذر على وسم
html
وbody
.- يمكن لأي جزء من المسار اختياريًا تعريف تخطيطه الخاص. ستتم مشاركة هذه التخطيطات عبر جميع الصفحات في هذا الجزء.
- التخطيطات في المسار متداخلة افتراضيًا. كل تخطيط رئيسي يلف التخطيطات الفرعية تحته باستخدام خاصية React
children
.- يمكنك استخدام مجموعات المسار (Route Groups) لاختيار أجزاء مسار معينة داخل أو خارج التخطيطات المشتركة.
- التخطيطات هي مكونات خادم (Server Components) افتراضيًا ولكن يمكن تعيينها كمكون عميل (Client Component).
- يمكن للتخطيطات جلب البيانات. راجع قسم جلب البيانات لمزيد من المعلومات.
- لا يمكن تمرير البيانات بين التخطيط الرئيسي وأطفاله. ومع ذلك، يمكنك جلب نفس البيانات في مسار أكثر من مرة، وسيقوم React بإزالة التكرارات تلقائيًا دون التأثير على الأداء.
- لا يمكن للتخطيطات الوصول إلى أجزاء المسار أسفلها. للوصول إلى جميع أجزاء المسار، يمكنك استخدام
useSelectedLayoutSegment
أو [useSelectedLayoutSegments
في مكون عميل.- يمكن استخدام امتدادات الملفات
.js
أو.jsx
أو.tsx
للتخطيطات.- يمكن تعريف ملف
layout.js
وpage.js
في نفس المجلد. سيلف التخطيط الصفحة.
تخطيط الجذر (مطلوب)
يتم تعريف تخطيط الجذر في المستوى الأعلى من مجلد app
وينطبق على جميع المسارات. يتيح لك هذا التخطيط تعديل HTML الأولي المرسل من الخادم.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ar">
<body>{children}</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html lang="ar">
<body>{children}</body>
</html>
)
}
جيد أن تعرف:
- يجب أن يتضمن مجلد
app
تخطيط جذر.- يجب أن يحدد تخطيط الجذر وسم
<html>
و<body>
لأن Next.js لا ينشئها تلقائيًا.- يمكنك استخدام دعم SEO المدمج لإدارة عناصر HTML
<head>
، على سبيل المثال، وسم<title>
.- يمكنك استخدام مجموعات المسار (Route Groups) لإنشاء تخطيطات جذر متعددة. انظر مثال هنا.
- تخطيط الجذر هو مكون خادم (Server Component) افتراضيًا ولا يمكن تعيينه كمكون عميل (Client Component).
الانتقال من مجلد
pages
: يحل تخطيط الجذر محل ملفات_app.js
و_document.js
. راجع دليل الانتقال.
تداخل التخطيطات
تنطبق التخطيطات المعرفة داخل مجلد (مثل app/dashboard/layout.js
) على أجزاء مسار معينة (مثل acme.com/dashboard
) وتصدر عندما تكون هذه الأجزاء نشطة. افتراضيًا، التخطيطات في تسلسل الملفات متداخلة، مما يعني أنها تغلف التخطيطات الفرعية عبر خاصية children
.

export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
جيد أن تعرف:
- فقط تخطيط الجذر يمكن أن يحتوي على وسم
<html>
و<body>
.
إذا قمت بدمج التخطيطين أعلاه، فسيلف تخطيط الجذر (app/layout.js
) تخطيط لوحة التحكم (app/dashboard/layout.js
)، والذي بدوره سيلف أجزاء المسار داخل app/dashboard/*
.
سيتم تداخل التخطيطين كما يلي:

يمكنك استخدام مجموعات المسار (Route Groups) لاختيار أجزاء مسار معينة داخل أو خارج التخطيطات المشتركة.
القوالب
القوالب مشابهة للتخطيطات من حيث أنها تغلف كل تخطيط فرعي أو صفحة. على عكس التخطيطات التي تبقى عبر المسارات وتحافظ على الحالة، تنشئ القوالب نسخة جديدة لكل طفل لها عند التنقل. هذا يعني أنه عندما ينتقل المستخدم بين المسارات التي تشترك في قالب، يتم تحميل نسخة جديدة من المكون، يتم إعادة إنشاء عناصر DOM، لا يتم الحفاظ على الحالة، ويتم إعادة مزامنة التأثيرات.
قد تكون هناك حالات تحتاج فيها إلى هذه السلوكيات المحددة، وتكون القوالب خيارًا أكثر ملاءمة من التخطيطات. على سبيل المثال:
- ميزات تعتمد على
useEffect
(مثل تسجيل مشاهدات الصفحة) وuseState
(مثل نموذج تعليقات لكل صفحة). - لتغيير سلوك الإطار الافتراضي. على سبيل المثال، حدود Suspense داخل التخطيطات تظهر الحالة الاحتياطية فقط عند تحميل التخطيط لأول مرة وليس عند تبديل الصفحات. بالنسبة للقوالب، تظهر الحالة الاحتياطية في كل تنقل.
يمكن تعريف قالب عن طريق تصدير مكون React افتراضي من ملف template.js
. يجب أن يقبل المكون خاصية children
.

export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
export default function Template({ children }) {
return <div>{children}</div>
}
من حيث التداخل، يتم تصيير template.js
بين التخطيط وأطفاله. إليك ناتج مبسط:
<Layout>
{/* لاحظ أن القالب يحصل على مفتاح فريد. */}
<Template key={routeParam}>{children}</Template>
</Layout>
تعديل <head>
في مجلد app
، يمكنك تعديل عناصر HTML <head>
مثل title
و meta
باستخدام دعم SEO المدمج.
يمكن تعريف البيانات الوصفية عن طريق تصدير كائن metadata
أو دالة generateMetadata
في ملف layout.js
أو page.js
.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
export const metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
جيد أن تعرف: يجب ألا تضيف يدويًا وسوم
<head>
مثل<title>
و<meta>
إلى تخطيطات الجذر. بدلاً من ذلك، يجب استخدام واجهة برمجة تطبيقات البيانات الوصفية (Metadata API) التي تتعامل تلقائيًا مع المتطلبات المتقدمة مثل البث وإزالة التكرارات من عناصر<head>
.
تعرف على المزيد حول خيارات البيانات الوصفية المتاحة في مرجع API.