مرحباً أيها المبرمجون الطموحون! اليوم، سنستكشف هيكل المشاريع الجديدة في Next.js App Router، ونفهم كيفية بناء صفحات وتوجيهات فعالة.
سنتعلم إعداد مشروع، فهم layout.tsx و page.tsx، وبناء توجيهات متداخلة، مع التمييز بين مكونات الخادم والعميل.
الخطوة 1: إعداد المجلد الأساسي (App Router)
في Next.js 13 وما بعده، أصبح مجلد app هو القلب النابض للتوجيهات الجديدة. لنبدأ بإنشاء ملفين أساسيين فيه: layout.tsx و page.tsx.
ملاحظة تقنية: ملف
layout.tsxيحدد واجهة المستخدم المشتركة لفرع من شجرة التوجيه، بينماpage.tsxيعرض المحتوى الفريد لطريق معين.
app/layout.tsx
import './globals.css'; // استيراد ملف الأنماط العام
import { Inter } from 'next/font/google'; // استيراد خط Inter من Google Fonts
const inter = Inter({ subsets: ['latin'] }); // تهيئة خط Inter
export const metadata = {
title: 'مشروعي الجديد', // عنوان الصفحة الافتراضي
description: 'استكشاف App Router في Next.js', // وصف الصفحة
};
export default function RootLayout({
children, // المكونات الفرعية التي سيتم عرضها ضمن هذا التخطيط
}: {
children: React.ReactNode; // تحديد نوع children كـ React Node
}) {
return (
<html lang="ar"> {/* تحديد لغة المستند كالعربية */}
<body className={inter.className}> {/* تطبيق فئة الخط على جسم الصفحة */}
{children} {/* هنا يتم عرض محتوى الصفحات الأخرى (page.tsx) */}
</body>
</html>
);
}
app/page.tsx
export default function HomePage() {
return (
<main style={{ padding: '2rem', textAlign: 'center' }}> {/* تنسيق بسيط للمحتوى الرئيسي */}
<h1>مرحباً بكم في App Router!</h1> {/* عنوان رئيسي للصفحة */}
<p>هذه هي الصفحة الرئيسية لمشروعنا الجديد.</p>
<p>استكشف المزيد من التوجيهات.</p>
</main>
);
}
الخطوة 2: بناء توجيهات متداخلة (Nested Routes)
يسمح لك App Router بإنشاء توجيهات متداخلة ببساطة عن طريق إنشاء مجلدات فرعية داخل مجلد app. لننشئ صفحة "حول" (About) ومجلد "لوحة التحكم" (Dashboard).
ملاحظة تقنية: كل مجلد فرعي داخل
appيمثل جزءاً من مسار URL. ملفpage.tsxداخل هذا المجلد يحدد المحتوى الذي سيتم عرضه لهذا المسار.
app/about/page.tsx
export default function AboutPage() {
return (
<main style={{ padding: '2rem', textAlign: 'center' }}>
<h1>صفحة حول</h1> {/* عنوان صفحة حول */}
<p>نحن نستكشف قوة Next.js App Router!</p>
<p>هذا مثال على توجيه متداخل.</p>
</main>
);
}
app/dashboard/page.tsx
يمكنك أيضاً إضافة layout.tsx خاص بـ dashboard إذا أردت تخطيطاً مختلفاً لهذا القسم.
export default function DashboardPage() {
return (
<main style={{ padding: '2rem', textAlign: 'center', backgroundColor: '#f0f0f0' }}> {/* خلفية مختلفة لصفحة لوحة التحكم */}
<h1>لوحة التحكم</h1> {/* عنوان صفحة لوحة التحكم */}
<p>أهلاً بك في لوحة التحكم الخاصة بك.</p>
<p>هنا تظهر بياناتك وإحصائياتك.</p>
</main>
);
}
الخطوة 3: التمييز بين مكونات الخادم والعميل (Server vs. Client Components)
أحد الميزات الأساسية لـ App Router هو مفهوم مكونات الخادم (Server Components) ومكونات العميل (Client Components). افتراضياً، جميع المكونات في مجلد app هي مكونات خادم.
ملاحظة تقنية: مكونات الخادم تُقدم على الخادم ولا تُرسل إلى المتصفح، مما يقلل من حجم JavaScript ويحسن الأداء. مكونات العميل تُقدم في المتصفح وتسمح بالتفاعل (مثل أحداث
onClickأوuseState).
لتحويل مكون إلى مكون عميل، أضف السطر 'use client'; في أعلى الملف.
app/components/Counter.tsx (مكون عميل)
'use client'; // هذا السطر يحول المكون إلى مكون عميل
import { useState } from 'react'; // استيراد hook useState للتفاعل
export default function Counter() {
const [count, setCount] = useState(0); // تعريف حالة العداد بقيمة ابتدائية 0
return (
<div style={{ marginTop: '1rem', border: '1px solid #ccc', padding: '1rem' }}>
<h3>عداد تفاعلي (مكون عميل)</h3>
<p>العدد الحالي: {count}</p>
<button onClick={() => setCount(count + 1)}>زيادة العدد</button> {/* زر لزيادة العدد */}
</div>
);
}
الآن، لنستخدم هذا المكون التفاعلي في صفحتنا الرئيسية.
تحديث app/page.tsx لاستخدام Counter
import Counter from './components/Counter'; // استيراد مكون العداد
export default function HomePage() {
return (
<main style={{ padding: '2rem', textAlign: 'center' }}>
<h1>مرحباً بكم في App Router!</h1>
<p>هذه هي الصفحة الرئيسية لمشروعنا الجديد.</p>
<p>استكشف المزيد من التوجيهات.</p>
<Counter /> {/* استخدام مكون العداد التفاعلي هنا */}
</main>
);
}
الكود النهائي الكامل
لإنشاء هذا المشروع، يمكنك البدء بـ npx create-next-app@latest واختيار "نعم" لاستخدام App Router و TypeScript. ثم استبدل الملفات بالآتي:
app/layout.tsx
import './globals.css';
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export const metadata = {
title: 'مشروعي الجديد',
description: 'استكشاف App Router في Next.js',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ar">
<body className={inter.className}>
{children}
</body>
</html>
);
}
app/page.tsx
import Counter from './components/Counter';
export default function HomePage() {
return (
<main style={{ padding: '2rem', textAlign: 'center' }}>
<h1>مرحباً بكم في App Router!</h1>
<p>هذه هي الصفحة الرئيسية لمشروعنا الجديد.</p>
<p>استكشف المزيد من التوجيهات.</p>
<Counter />
</main>
);
}
app/about/page.tsx
export default function AboutPage() {
return (
<main style={{ padding: '2rem', textAlign: 'center' }}>
<h1>صفحة حول</h1>
<p>نحن نستكشف قوة Next.js App Router!</p>
<p>هذا مثال على توجيه متداخل.</p>
</main>
);
}
app/dashboard/page.tsx
export default function DashboardPage() {
return (
<main style={{ padding: '2rem', textAlign: 'center', backgroundColor: '#f0f0f0' }}>
<h1>لوحة التحكم</h1>
<p>أهلاً بك في لوحة التحكم الخاصة بك.</p>
<p>هنا تظهر بياناتك وإحصائياتك.</p>
</main>
);
}
app/components/Counter.tsx
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div style={{ marginTop: '1rem', border: '1px solid #ccc', padding: '1rem' }}>
<h3>عداد تفاعلي (مكون عميل)</h3>
<p>العدد الحالي: {count}</p>
<button onClick={() => setCount(count + 1)}>زيادة العدد</button>
</div>
);
}
app/globals.css (للتنسيق الأساسي)
body {
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
background-color: #f8f8f8;
color: #333;
}
h1, h3 {
color: #0070f3;
}
button {
background-color: #0070f3;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
transition: background-color 0.2s;
}
button:hover {
background-color: #005bb5;
}
النتيجة المتوقعة
بعد تشغيل المشروع باستخدام npm run dev:
- عند زيارة
http://localhost:3000/، سترى الصفحة الرئيسية مع عنوان "مرحباً بكم في App Router!"، ونص وصفي، وعداد تفاعلي يمكنك زيادته بالنقر على الزر. - عند زيارة
http://localhost:3000/about، سترى صفحة "حول" بتصميمها الخاص. - عند زيارة
http://localhost:3000/dashboard، سترى صفحة "لوحة التحكم" بخلفية مختلفة، مما يوضح كيفية تطبيق تخطيطات أو أنماط خاصة بمسارات معينة.
هذا يوضح كيف يمكنك بناء هيكل مشروع Next.js باستخدام App Router بشكل منظم وفعال، مع الاستفادة من قوة مكونات الخادم والعميل.