الواجهة البرمجية للمكوّن next/link
في Next.js
ننصحك قبل قراءة المقال بالاطلاع على التوجيه في Next.js أولًا.
بإمكانك تفعيل التنقل بين الصفحات أو الوجهات في جانب العميل عبر المكوّن Link
الذي تصدّره المكتبة next/link
.
لنفترض وجود الملفات التالية في المجلد pages
:
pages/index.js
pages/about.js
pages/blog/[slug].js
يمكننا الحصول على رابط إلى كل صفحة من هذه الصفحات كالتالي:
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about">About Us</Link>
</li>
<li>
<Link href="/blog/hello-world">Blog Post</Link>
</li>
</ul>
)
}
export default Home
يقبل المكوّن Link
الخاصيات التالية:
href
: المسار أو عنوان URL الذي سننتقل إليه. وهذه الخاصية هي الوحيدة التي نحتاجها، كما يمكن أن تكون كائنًا (كائن URL).as
: منسّق اختياري للمسار الذي سيُعرض في شريط عناوين المتصفح. استُخدم هذا المعامل سابقًا للتوجه الديناميكي ما قبل الإصدار 9.5.3. ملاحظة: إن اختلف المسار هذا المعطى عن المسار المعطى في href فإن سلوكhref
/as
القديم المستخدم في ذلك الإصدار هو الذي سيُستخدم، فارجع إلى التوثيق القديم.- legacyBehavior: يغير السلوك ويعود للسلوك القديم الذي يتطلب وجود عنصر
<a>
ابن، ويأخذ القيمة الافتراضيةfalse
. passHref
: يجبر المكوّنLink
على إرسال الخاصيةhref
إلى أبناءه، ويأخذ القيمة الافتراضيةfalse
.prefetch
: يحضر الصفحة مسبقًا وراء الستار، ويأخذ القيمة الافتراضيةtrue
. كما سيُعاد تحميل أي مكوّن</ Link>
ظاهر في نافذة العرض (في البداية أو عند التمرير). يمكن تعطيل هذه الخاصية بتمرير القيمةprefetch={false}
. وعندما تأخذ الخاصيةprefetch
القيمةfalse
، ستستمر عملية الإحضار المسبق عند مرور مؤشر الفأرة فوق العنصر hovering. ستعيد الصفحات التي تستخدم التوليد الساكن توليد ملفاتJSON
مع البيانات لتسريع عملية الانتقال بين الصفحات. تُفعّل الخاصيةprefetch
في مرحلة الإنتاج فقط.replace
: يستبدل حالة سجل العناوين history بدلًا من إضافة عنوان url جديد إلى المكدّس، ويأخذ القيمة الافتراضيةfalse
.scroll
: يتحكم بالتمرير إلى أعلى الصفحة بعد الانتقال، وقيمته الافتراضيةtrue
.shallow
: يُحدّث مسار الصفحة الحالية دون تنفيذ الدوالgetStaticProps
أوgetServerSideProps
أوgetInitialProps
، وقيمته الافتراضيةfalse
.locale
: يُستخدم الإعداد المحلي المُفعَّل تلقائيًا. كما يمكنك استخدامها لتغيير هذا الإعداد. عندما تأخذ الخاصية القيمةfalse
يجب أن تحدد الخاصيةhref
الإعداد المحلي بما أن السلوك الافتراضي قد تعطل آنذاك.
حالة وجود أجزاء ديناميكية في الوجهة
لا ينبغي عليك تنفيذ أي عملية محددة عندما ترتبط إلى الوجهات الديناميكية بما في ذلك التقاط جميع الوجهات، وذلك اعتبارًا من النسخة 9.5.3. لكن قد يكون مفيدًا في بعض الأحيان استخدام الاستدلال interpolation أو كائن URL لتوليد الرابط.
ستطابق الوجهة الديناميكية pages/blog/[slug].js
مثلًا الرابط التالي:
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${encodeURIComponent(post.slug)}`}>
{post.title}
</Link>
</li>
))}
</ul>
)
}
export default Posts
حالة وجود مكون <a>
ابن مخصص للمكون link
إليك المثال التالي الذي يمثل هذه الحالة:
import Link from 'next/link'
function Legacy() {
return (
<Link href="/about" legacyBehavior>
<a>About Us</a>
</Link>
)
}
export default Legacy
حالة وجود مكون ابن مخصص للمكون link
مغلف بالعنصر <a>
لا بد في هذه الحالة من إضافة الخاصية passHref
إلى المكوّن link
، وهذا ضروري إن كنت تستخدم مكتبات مثل styled-components. لن يمتلك العنصر <a>
دون أن تفعل ذلك السمة href
، الأمر الذي يسيء إلى سهولة وصول موقعك وقد يؤثر على نتيجة البحث SEO. وفي حال استخدمت المدقق ESLint، تأكد من استخدام القاعدة next/link-passhref
للتأكد من الاستخدام الصحيح للخاصية passHref
:
import Link from 'next/link'
import styled from 'styled-components'
// <a> يُنشئ ذلك مكوّن مخصص يغلف العنصر
const RedLink = styled.a`
color: red;
`
function NavLink({ href, name }) {
//Link إلى الرابط href لا بد من إضافة
return (
<Link href={href} passHref legacyBehavior>
<RedLink>{name}</RedLink>
</Link>
)
}
export default NavLink
- لا بد أيضًا من استخدام الخاصية
passHref
إن كنت ستعمل مع الميزةjsx jsx@
العائدة لمكتبة التنسيق emotion حتى لو استخدمت<a>
مباشرة. - يجب أن يدعم المكوّن الخاصية
onClick
كي يقع حدث التنقل بالطريقة الصحيحة.
الحالة التي يكون فيها ابن المكون link
مكون دالة
لا بد في هذه الحالة من تغليف المكوّن ضمن React.forwardRef
إضافةً إلى استخدام الخاصية passHref
والخاصية legacyBehavior
:
import Link from 'next/link'
//DOM عبر شجرة `onClick`و `href`و `ref` لا بد من تمرير
// ليجري التعامل معها بالشكل الصحيح
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})
function Home() {
return (
<Link href="/about" passHref legacyBehavior>
<MyButton />
</Link>
)
}
export default Home
حالة استقبال كائن URL
يستقبل المكوّن Link
كائن URL وينسقه تلقائيًا لإنشاء عنوان URL نصي. إليك الطريقة:
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About us
</Link>
</li>
<li>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: 'my-post' },
}}
>
Blog Post
</Link>
</li>
</ul>
)
}
export default Home
يحتوي المثال السابق روابط إلى:
about?name=test/
: وجهة محددة مسبقًا.blog/my-post/
: وجهة ديناميكية.
بإمكانك استعمال أية خاصية كما عُرّفت في توثيق Node.js لوحدة URL.
استبدال العنوان في سجل العناوين بدلًا من دفعه
يدفع push
المكوّن Link
افتراضيًا عنوان URL الجديد في مكدس سجل العناوين history
. لكن بإمكانك استخدام الخاصية replace
لمنع إضافة مُدخل جديد إلى السجل كالتالي:
<Link href="/about" replace>
About us
</Link>
إلغاء التمرير إلى أعلى الصفحة
يقتضي السلوك الافتراضي للمكوّن link
بالانتقال إلى أعلى الصفحة. لكن عند وجود إشارة العنوان الفرعي (#) سينتقل بالصفحة إلى هذا العنوان المحدد كما يفعل أي رابط نمطي <a>
. لهذا إن أردت إلغاء السلوك الافتراضي بالانتقال إلى أعلى الصفحة، استخدم الصيغة التالية:
<Link href="/#hashid" scroll={false}>
Disables scrolling to the top
</Link>
البرمجيات الوسيطة Middleware
يشيع استعمال البرمجيات الوسيطة Middleware في عمليات الاستيثاق authentication أو غيرها من الحالات التي تتطلب إعادة توجيه المستخدم إلى صفحة أخرى غير التي يريد الانتقال إليها، فإن أردت أن يجلب المكون <Link>
المكون المشار إليه في المسار مسبقًا بشكل صحيح مع حالة إعادة التوجيه التي قد تجريها إحدى البرمجيات الوسيطة، تحتاج إلى إخبار Next.js صراحةً أي عنوان URL يُعرض وأي عنوان يُجلب مسبقًا، وهذا ضروري لتجنب إجراء عمليات جلب غير ضرورية للبرمجيات الوسيطة لمعرفة الوجهة الصحيحة المراد جلبها مسبقًا.
إليك مثال، إن أردت تخديم وجهة /dashboard
تتطلب من المستخدم إجراء الاستيثاق قبل رؤيتها، فعليك إضافة شيفرة مشابهة للشيفرة التالية في ملف البرمجيات الوسيطة middleware.js لإعادة توجيه المستخدم للصفحة الصحيحة:
// middleware.js
export function middleware(req) {
const nextUrl = req.nextUrl
if (nextUrl.pathname === '/dashboard') {
if (req.cookies.authToken) {
return NextResponse.rewrite('/auth/dashboard')
} else {
return NextResponse.rewrite('/public/dashboard')
}
}
}
في هذه الحالة يجب أن تستخدم الرابط <Link> بالشكل التالي (داخل مجلد الصفحات /pages):
// pages/index.js
import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'
export default function Page() {
const isAuthed = useIsAuthed()
const path = isAuthed ? '/auth/dashboard' : '/dashboard'
return (
<Link as="/dashboard" href={path}>
Dashboard
</Link>
)
}
ملاحظة: إن تستخدم الوجهات الديناميكية، فستحتاج إلى إلى ضبط الخاصية as
والخاصية href
، مثلًا إن كان لديك الوجهة الديناميكية /dashboard/[user]
التي تريد عرضها بشكل مختلف عبر البرمجيات الوسيطة، فيجب أن يكون <Link>
بالشكل التالي:
<Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>
أمثلة
المصادر
- الصفحة Next/Link من توثيق Next.js الرسمي.