التنقل الديناميكي في Next.js: كيفية عرض عناصر شريط التنقل بشكل شرطي داخل تطبيق Next
مقدمة إلى التنقل الديناميكي في Next.js
في كثير من تطبيقات الويب المبنية باستخدام React وNext.js، نحتاج إلى إظهار بعض روابط التنقل لمستخدمين محددين أو داخل صفحات معيّنة فقط. هذا الأسلوب شائع عند التعامل مع الصفحات المحمية، أو عند وجود أقسام داخلية لا تظهر إلا في مسارات محددة، مثل رابط Contact Us الذي يقود إلى جزء داخل الصفحة الرئيسية.
في هذا الدليل، سنتعرف على طريقة عملية لبناء Dynamic Navigation في Next.js، بحيث يتم توليد عناصر شريط التنقل تلقائياً من مصفوفة بيانات، مع عرض بعض العناصر بشكل شرطي اعتماداً على المسار الحالي باستخدام useRouter.

المتطلبات الأساسية قبل البدء
حتى تستفيد من الشرح بشكل كامل، يُفضّل أن تكون لديك معرفة أساسية بالمفاهيم التالية:
- آلية عمل React.
- أساسيات Next.js بوصفه إطار عمل جاهزاً للإنتاج مبنياً على React.
- مفهوم Conditional Rendering في React.
- التحقق من الخصائص باستخدام PropTypes.
- أوامر import وexport في JavaScript.
بدء إنشاء مشروع Next.js
بما أن المقال يركز على Next.js، فالخطوة الأولى هي إنشاء مشروع جديد. نفّذ الأمر التالي داخل الطرفية:
npx create-next-app [name-of-your-webapp/website]
سيقوم هذا الأمر بتجهيز المشروع مع جميع الاعتمادات الأساسية اللازمة لتشغيل تطبيق Next.js بسرعة. ومن المهم الانتباه إلى أن بنية الملفات في Next.js تختلف عن البنية المعتادة في create-react-app.
هيكل الملفات المستخدم في المثال
فيما يلي نموذج مبسط للملفات التي سنعمل عليها:
|--pages
| |-- _app.js
| |-- index.js
| |-- about.js
| |-- blog.js
| |__ services.js
|--src
| |-- components
| | |-- Header.js
| | |__ NavItem.js
| |-- data.js
|__
هذا الهيكل يوضح فقط الأجزاء المهمة لفهم آلية إنشاء شريط تنقل ديناميكي داخل التطبيق.
فهم مكونات المشروع في Next.js
ملف _app.js: نقطة الانطلاق العامة للتطبيق
يُعد الملف _app.js الملف الجذري للتطبيق، وهو قريب في فكرته من index.js في مشاريع create-react-app. من خلاله يمكنك إضافة الأنماط العامة، أو تعريف الثيمات، أو تمرير Context إلى كامل التطبيق.
import Head from "next/head";
import React from "react";
function MyApp({ Component, pageProps }) {
return (
<React.Fragment>
<Head>
<meta name="theme-color" content="#3c1742" />
</Head>
<Component {...pageProps} />
</React.Fragment>
);
}
export default MyApp;
يسمح المكوّن Head المستورد من next/head بإضافة عناصر مهمة إلى الصفحة مثل title ووسوم meta، وهو أمر مفيد جداً لتحسين SEO.
ملف index.js: الصفحة الرئيسية في Next.js
في Next.js، لا تحتاج إلى استخدام BrowserRouter من مكتبة react-router-dom كما هو الحال في React التقليدي، لأن الإطار يتكفل بإنشاء المسارات تلقائياً. أي ملف داخل مجلد pages يتحول مباشرة إلى صفحة قابلة للوصول.
فعلى سبيل المثال، يصبح الملف index.js متاحاً على الرابط:
https://localhost:3000/
بعد تشغيل خادم التطوير باستخدام:
npm run dev
إليك مثالاً على محتوى الصفحة الرئيسية:
import Head from "next/head";
import Header from "../src/components/Header";
export default function Home() {
return (
<>
<Head>
<title>Caleb's article examples</title>
<link rel="icon" type="image/ico" href="/img/goals.ico" />
</Head>
<Header />
<section>
<h1>Home Page</h1>
<section id="contact">
<h3 className="section-title">Contact Us</h3>
<p className="section-body">
You can Contact us via our various social media handles
</p>
</section>
</HomeWrapper>
</>
);
}
أما الصفحات الأخرى مثل about.js وblog.js وservices.js فستكون متاحة عبر المسارات التالية:
- /about
- /blog
- /services
إنشاء عناصر شريط التنقل ديناميكياً باستخدام map()
بدلاً من كتابة عناصر شريط التنقل يدوياً داخل الواجهة، من الأفضل إنشاء مصفوفة بيانات ثم استخدام الدالة map() لعرض العناصر بشكل ديناميكي. هذه الطريقة تجعل الكود أكثر تنظيماً وأسهل في التوسع والصيانة.
سنبدأ بتعريف مصفوفة الروابط داخل الملف data.js:
export const navLinks = [
{ name: "Home", path: "/" },
{ name: "About Us", path: "/about" },
{ name: "Services", path: "/services" },
{ name: "Blog", path: "/blog" },
{ name: "Contact Us", path: "#contact" },
];
لاحظ أن العنصر الأخير يستخدم القيمة #contact بدلاً من /contact. والسبب هو أن قسم التواصل ليس صفحة مستقلة، بل جزء موجود داخل الصفحة الرئيسية نفسها.
بناء مكوّن Header
الآن يمكننا استيراد المصفوفة واستخدامها داخل مكوّن Header من أجل عرض الروابط:
import React from "react";
import { navLinks } from "../utils/data";
import Link from "next/link";
export default function Header() {
return (
<header>
<div className="brand">
<h3>Example</h3>
</div>
<nav>
{navLinks.map((link, index) => {
return (
<ul>
<Link href={link.path}>
<li key={index}>{link.name}</li>
</Link>
</ul>
);
})}
</nav>
</header>
);
}
بهذه الطريقة، سيتم إنشاء روابط شريط التنقل بناءً على البيانات الموجودة في المصفوفة. وعند النقر على الرابط Contact Us، سيتحول المسار إلى:
https://localhost:3000/#contact
وسيحاول المتصفح الانتقال إلى العنصر الذي يحمل المعرّف id=”contact”. وإذا لم يكن هذا القسم موجوداً في الصفحة الحالية، فلن يحدث أي تمرير داخل الصفحة. لذلك، من الأفضل عرض هذا الرابط فقط عندما يكون المستخدم داخل الصفحة الرئيسية.
عرض عنصر التنقل بشكل شرطي باستخدام useRouter في Next.js
حتى نتحكم في ظهور بعض عناصر القائمة حسب الصفحة النشطة، نحتاج إلى معرفة المسار الحالي داخل التطبيق. وهنا يأتي دور Hook مهم في Next.js وهو useRouter.
يمكننا إنشاء مكوّن مستقل مسؤول عن إظهار عنصر تنقل معيّن فقط عندما يتحقق شرط محدد:
import React from "react";
import { useRouter } from "next/router";
import propTypes from "prop-types";
const NavItem = ({ item }) => {
const router = useRouter();
return <>{router.pathname === "/" ? item : ""}</>;
};
export default NavItem;
// proptypes check
NavItem.propTypes = {
item: propTypes.string,
};
كيف يعمل هذا المكوّن؟
- يستقبل المكوّن خاصية item عبر props.
- يستدعي useRouter() للحصول على معلومات حول المسار الحالي.
- يتحقق من أن router.pathname يساوي “/”.
- إذا كان المستخدم في الصفحة الرئيسية، يتم عرض النص المُرسل.
- إذا كان في صفحة أخرى، يتم إرجاع قيمة فارغة، وبالتالي لا يظهر العنصر داخل الواجهة.
السطر التالي هو جوهر المنطق الشرطي:
router.pathname === "/" ? item : ""
هذا التعبير الشرطي يضمن أن رابط Contact Us لن يظهر إلا عندما يكون الزائر داخل الصفحة الرئيسية، وهي الصفحة الوحيدة التي تحتوي فعلياً على القسم الهدف.
تعديل مصفوفة navLinks لاستخدام المكوّن الشرطي
بعد إنشاء المكوّن NavItem، يمكننا استخدامه داخل مصفوفة الروابط لتغليف العنصر الذي نريد التحكم في ظهوره:
import NavLink from "./NavLink";
export const navLinks = [
{ name: "Home", path: "/" },
{ name: "About Us", path: "/about" },
{ name: "Services", path: "/services" },
{ name: "Blog", path: "/blog" },
{
name: <NavLink item="Contact Us" />,
path: "#contact",
},
];
بهذا الشكل، يصبح عنصر Contact Us ديناميكياً بالكامل، إذ يعتمد ظهوره على الصفحة الحالية، بدلاً من عرضه دائماً حتى عندما لا يكون له أي وظيفة فعلية.
لماذا يُعد هذا الأسلوب مهماً في تطوير الواجهات؟
استخدام Dynamic Navigation داخل تطبيقات Next.js ليس مجرد تحسين شكلي، بل يحقق فوائد عملية واضحة، منها:
- تحسين تجربة المستخدم عبر إظهار الروابط المفيدة فقط.
- تقليل التشويش داخل شريط التنقل.
- منع الروابط غير المناسبة من الظهور في صفحات لا تحتوي على أهدافها.
- تسهيل صيانة الكود عند توسعة المشروع أو إضافة صلاحيات مستخدمين مختلفة.
- إمكانية إعادة استخدام المكوّنات بصورة أفضل داخل التطبيق.
النتيجة النهائية المتوقعة
بعد تطبيق الخطوات السابقة، سيظهر رابط Contact Us داخل شريط التنقل عندما يكون المستخدم في الصفحة الرئيسية فقط. أما عند الانتقال إلى صفحات أخرى مثل About أو Blog أو Services، فسيختفي هذا الرابط تلقائياً لأن القسم المرتبط به غير موجود هناك.
هذا النوع من السلوك الديناميكي يجعل التنقل داخل الموقع أكثر منطقية وانسجاماً مع بنية المحتوى.

أفضل الممارسات عند بناء شريط تنقل ديناميكي في Next.js
- ضع بيانات الروابط في ملف مستقل لسهولة إدارتها.
- افصل منطق العرض الشرطي في مكوّن مستقل مثل NavItem.
- استخدم useRouter عند الحاجة لقراءة المسار الحالي بدقة.
- احرص على أن تكون الروابط المعروضة مرتبطة فعلياً بمحتوى موجود في الصفحة.
- اختبر سلوك التنقل على جميع الصفحات لتفادي الروابط الميتة أو غير الفعالة.
الخلاصة التقنية
يُعد إنشاء شريط تنقل ديناميكي في Next.js من الأساليب الذكية لتحسين بنية الواجهة وتجربة الاستخدام. الاعتماد على map() لتوليد الروابط من مصدر بيانات موحد، ثم استخدام useRouter للتحكم في الظهور الشرطي، يمنحك حلاً مرناً وقابلاً للتوسع. ومن الناحية التقنية، هذا النهج يساعد على إبقاء الواجهة متسقة مع المسار الحالي ويقلل من العناصر غير الضرورية، وهو ما ينعكس إيجابياً على جودة التطبيق وقابليته للصيانة.