التوجيه الأساسي (Routing): إنشاء الصفحات والتنقل بينها بدون إعادة تحميل


سنتعلم اليوم كيفية بناء تطبيق ويب متعدد الصفحات باستخدام Next.js App Router، مع التركيز على التوجيه (Routing) الفعال والتنقل السلس بين الصفحات دون الحاجة لإعادة تحميل الصفحة بالكامل.

الخطوة 1: إعداد المشروع وتصميم التخطيط الأساسي (Layout)

في هذه الخطوة، سنقوم بإنشاء بنية مجلدات Next.js App Router الأساسية وتحديد التخطيط العام لتطبيقنا، والذي سيحتوي على شريط التنقل والمحتوى المتغير.

ملاحظة تقنية: في Next.js App Router، يتم تعريف المسارات عن طريق المجلدات. أي ملف 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: 'تعلم التوجيه في Next.js App Router', // وصف التطبيق
};

export default function RootLayout({
  children, // خاصية children تمثل المحتوى الخاص بكل صفحة
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ar" dir="rtl"> {/* تحديد اللغة واتجاه النص من اليمين لليسار */}
      <body className={inter.className}>
        <header style={{ padding: '20px', backgroundColor: '#f0f0f0', borderBottom: '1px solid #ccc' }}>
          <h1>تطبيق التوجيه (Routing)</h1>
        </header>
        <main style={{ padding: '20px' }}>
          {children} {/* هنا سيتم عرض محتوى الصفحة الحالية */}
        </main>
      </body>
    </html>
  );
}

app/page.tsx

هذا هو ملف الصفحة الرئيسية لتطبيقنا.

export default function HomePage() {
  return (
    <div>
      <h2>مرحباً بك في الصفحة الرئيسية!</h2>
      <p>هذه هي الصفحة الرئيسية لتطبيقنا التعليمي حول التوجيه في Next.js.</p>
    </div>
  );
}

الخطوة 2: إنشاء صفحات جديدة

الآن، لنقم بإنشاء صفحتين إضافيتين: صفحة "عنّا" وصفحة "اتصل بنا". كل صفحة ستحصل على مجلد خاص بها وملف page.tsx.

app/about/page.tsx

export default function AboutPage() {
  return (
    <div>
      <h2>عنّا</h2>
      <p>نحن فريق متخصص في تعليم تطوير الويب بأحدث التقنيات.</p>
    </div>
  );
}

app/contact/page.tsx

export default function ContactPage() {
  return (
    <div>
      <h2>اتصل بنا</h2>
      <p>يمكنك التواصل معنا عبر البريد الإلكتروني: example@example.com</p>
    </div>
  );
}

الخطوة 3: تطبيق التنقل بين الصفحات

لتمكين المستخدمين من التنقل بين هذه الصفحات، سنضيف روابط التنقل باستخدام مكون Link من Next.js في ملف layout.tsx. هذا المكون يوفر تنقلاً سلساً من جانب العميل (client-side navigation) دون الحاجة لإعادة تحميل الصفحة بالكامل.

ملاحظة تقنية: مكون <Link> من next/link هو أساس التنقل السريع في Next.js. بدلاً من إجراء طلب HTTP جديد للخادم عند كل نقرة، يقوم بتحديث DOM جزئياً، مما يوفر تجربة مستخدم أسرع وأكثر سلاسة.

تحديث app/layout.tsx لإضافة شريط التنقل

import './globals.css';
import { Inter } from 'next/font/google';
import Link from 'next/link'; // استيراد مكون Link للتنقل

const inter = Inter({ subsets: ['latin'] });

export const metadata = {
  title: 'تطبيق التوجيه الأساسي',
  description: 'تعلم التوجيه في Next.js App Router',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ar" dir="rtl">
      <body className={inter.className}>
        <header style={{ padding: '20px', backgroundColor: '#f0f0f0', borderBottom: '1px solid #ccc' }}>
          <h1>تطبيق التوجيه (Routing)</h1>
          <nav style={{ marginTop: '10px' }}> {/* شريط التنقل */}
            <Link href="/" style={{ marginRight: '15px', textDecoration: 'none', color: 'blue' }}>
              الرئيسية {/* رابط الصفحة الرئيسية */}
            </Link>
            <Link href="/about" style={{ marginRight: '15px', textDecoration: 'none', color: 'blue' }}>
              عنّا {/* رابط صفحة عنّا */}
            </Link>
            <Link href="/contact" style={{ textDecoration: 'none', color: 'blue' }}>
              اتصل بنا {/* رابط صفحة اتصل بنا */}
            </Link>
          </nav>
        </header>
        <main style={{ padding: '20px' }}>
          {children}
        </main>
      </body>
    </html>
  );
}

الكود النهائي الكامل

هنا تجد الكود الكامل لجميع الملفات التي قمنا بإنشائها أو تعديلها.

app/layout.tsx

import './globals.css';
import { Inter } from 'next/font/google';
import Link from 'next/link';

const inter = Inter({ subsets: ['latin'] });

export const metadata = {
  title: 'تطبيق التوجيه الأساسي',
  description: 'تعلم التوجيه في Next.js App Router',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ar" dir="rtl">
      <body className={inter.className}>
        <header style={{ padding: '20px', backgroundColor: '#f0f0f0', borderBottom: '1px solid #ccc' }}>
          <h1>تطبيق التوجيه (Routing)</h1>
          <nav style={{ marginTop: '10px' }}>
            <Link href="/" style={{ marginRight: '15px', textDecoration: 'none', color: 'blue' }}>
              الرئيسية
            </Link>
            <Link href="/about" style={{ marginRight: '15px', textDecoration: 'none', color: 'blue' }}>
              عنّا
            </Link>
            <Link href="/contact" style={{ textDecoration: 'none', color: 'blue' }}>
              اتصل بنا
            </Link>
          </nav>
        </header>
        <main style={{ padding: '20px' }}>
          {children}
        </main>
      </body>
    </html>
  );
}

app/page.tsx

export default function HomePage() {
  return (
    <div>
      <h2>مرحباً بك في الصفحة الرئيسية!</h2>
      <p>هذه هي الصفحة الرئيسية لتطبيقنا التعليمي حول التوجيه في Next.js.</p>
    </div>
  );
}

app/about/page.tsx

export default function AboutPage() {
  return (
    <div>
      <h2>عنّا</h2>
      <p>نحن فريق متخصص في تعليم تطوير الويب بأحدث التقنيات.</p>
    </div>
  );
}

app/contact/page.tsx

export default function ContactPage() {
  return (
    <div>
      <h2>اتصل بنا</h2>
      <p>يمكنك التواصل معنا عبر البريد الإلكتروني: example@example.com</p>
    </div>
  );
}

app/globals.css (للتشغيل الصحيح، فقط كمرجع)

للتشغيل السليم للمشروع، تأكد أن لديك ملف globals.css أساسي، والذي يتم إنشاؤه تلقائياً مع مشروع Next.js جديد. يمكن أن يكون محتواه بسيطاً جداً:

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: inherit;
  text-decoration: none;
}

النتيجة المتوقعة

عند تشغيل التطبيق (باستخدام الأمر npm run dev أو yarn dev أو pnpm dev بعد تهيئة مشروع Next.js جديد)، سيتم عرض صفحة ويب تحتوي على عنوان "تطبيق التوجيه (Routing)" وشريط تنقل يضم الروابط "الرئيسية"، "عنّا"، و"اتصل بنا".

عند النقر على أي من هذه الروابط، سيتم تحديث محتوى الصفحة الرئيسية (المنطقة التي يمثلها {children} في layout.tsx) لعرض محتوى الصفحة المختارة (مثل "مرحباً بك في الصفحة الرئيسية!" أو "عنّا" أو "اتصل بنا")، ولكن دون أن يقوم المتصفح بإعادة تحميل الصفحة بالكامل. هذا يوضح فعالية التوجيه من جانب العميل الذي يوفره Next.js، مما يوفر تجربة مستخدم سريعة وسلسة.