مكون <Link>
<Link>
هو مكون React يمتد عنصر HTML <a>
لتوفير الجلب المسبق (Prefetching) والتنقل من جانب العميل بين المسارات. وهو الطريقة الأساسية للتنقل بين المسارات في Next.js.
على سبيل المثال، ضع في الاعتبار دليل 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
الخصائص (Props)
فيما يلي ملخص للخصائص المتاحة لمكون Link:
الخاصية | مثال | النوع | مطلوب |
---|---|---|---|
href | href="/dashboard" | String أو Object | نعم |
replace | replace={false} | Boolean | - |
scroll | scroll={false} | Boolean | - |
prefetch | prefetch={false} | Boolean | - |
معلومة مفيدة: يمكن إضافة سمات عنصر
<a>
مثلclassName
أوtarget="_blank"
إلى<Link>
كخصائص وسيتم تمريرها إلى عنصر<a>
الأساسي.
href
(مطلوب)
المسار أو URL للانتقال إليه.
<Link href="/dashboard">Dashboard</Link>
يمكن أن يقبل href
أيضًا كائنًا، على سبيل المثال:
// الانتقال إلى /about?name=test
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
replace
القيمة الافتراضية false
. عندما تكون true
، سيستبدل next/link
حالة التاريخ الحالية بدلاً من إضافة URL جديد إلى سجل المتصفح (History API).
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" replace>
Dashboard
</Link>
)
}
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" replace>
Dashboard
</Link>
)
}
scroll
القيمة الافتراضية true
. السلوك الافتراضي لـ <Link>
هو التمرير إلى أعلى المسار الجديد أو الحفاظ على موضع التمرير للتنقل للخلف وللأمام. عندما تكون false
، لن يقوم next/link
بالتمرير إلى أعلى الصفحة بعد التنقل.
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" scroll={false}>
Dashboard
</Link>
)
}
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" scroll={false}>
Dashboard
</Link>
)
}
معلومة مفيدة:
- سيؤدي Next.js إلى التمرير إلى الصفحة إذا لم تكن مرئية في نافذة العرض عند التنقل.
prefetch
يحدث الجلب المسبق (Prefetching) عندما يدخل مكون <Link />
نافذة عرض المستخدم (مبدئيًا أو عبر التمرير). يقوم Next.js بجلب وتحميل المسار المرتبط (المشار إليه بـ href
) وبياناته في الخلفية لتحسين أداء التنقل من جانب العميل. يتم تمكين الجلب المسبق فقط في بيئة الإنتاج.
true
(افتراضي): سيتم جلب المسار بالكامل وبياناته.false
: لن يحدث الجلب المسبق عند الدخول إلى نافذة العرض، ولكن سيحدث عند التمرير. إذا كنت ترغب في إزالة الجلب تمامًا عند التمرير أيضًا، ففكر في استخدام علامة<a>
أو التبديل التدريجي إلى App Router، والذي يتيح تعطيل الجلب المسبق عند التمرير أيضًا.
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" prefetch={false}>
Dashboard
</Link>
)
}
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" prefetch={false}>
Dashboard
</Link>
)
}
خصائص أخرى
legacyBehavior
لم يعد عنصر <a>
مطلوبًا كطفل لـ <Link>
. أضف خاصية legacyBehavior
لاستخدام السلوك القديم أو قم بإزالة <a>
للترقية. يتوفر أداة تحويل تلقائي (codemod) لترقية الكود تلقائيًا.
معلومة مفيدة: عندما لا يتم تعيين
legacyBehavior
إلىtrue
، يمكن تمرير جميع خصائص علامةanchor
إلىnext/link
أيضًا مثلclassName
،onClick
، إلخ.
passHref
يجبر Link
على إرسال خاصية href
إلى الطفل. القيمة الافتراضية false
.
scroll
التمرير إلى أعلى الصفحة بعد التنقل. القيمة الافتراضية true
.
shallow
تحديث مسار الصفحة الحالية دون إعادة تشغيل getStaticProps
، getServerSideProps
أو getInitialProps
. القيمة الافتراضية false
.
locale
يتم إضافة اللغة النشطة تلقائيًا. تسمح locale
بتوفير لغة مختلفة. عندما تكون false
يجب أن يتضمن href
اللغة حيث يتم تعطيل السلوك الافتراضي.
أمثلة
الربط مع المسارات الديناميكية
بالنسبة للمسارات الديناميكية، يمكن أن يكون استخدام القوالب النصية (template literals) مفيدًا لإنشاء مسار الرابط.
على سبيل المثال، يمكنك إنشاء قائمة من الروابط للمسار الديناميكي pages/blog/[slug].js
.
import Link from 'next/link'
function Posts({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
export default Posts
إذا كان الطفل مكونًا مخصصًا يلف علامة <a>
إذا كان طفل 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 }) {
return (
<Link href={href} passHref legacyBehavior>
<RedLink>{name}</RedLink>
</Link>
)
}
export default NavLink
- إذا كنت تستخدم ميزة JSX pragma في emotion (
@jsx jsx
)، فيجب عليك استخدامpassHref
حتى إذا كنت تستخدم علامة<a>
مباشرة. - يجب أن يدعم المكون خاصية
onClick
لتنشيط التنقل بشكل صحيح.
إذا كان الطفل مكونًا وظيفيًا
إذا كان طفل Link
مكونًا وظيفيًا، بالإضافة إلى استخدام passHref
و legacyBehavior
، يجب عليك تغليف المكون في React.forwardRef
:
import Link from 'next/link'
// يجب تمرير `onClick`، `href`، و `ref` إلى عنصر DOM
// للمعالجة الصحيحة
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.
استبدال URL بدلاً من الإضافة
السلوك الافتراضي لمكون Link
هو إضافة (push
) URL جديد إلى سجل history
. يمكنك استخدام خاصية replace
لمنع إضافة إدخال جديد، كما في المثال التالي:
<Link href="/about" replace>
About us
</Link>
تعطيل التمرير إلى أعلى الصفحة
السلوك الافتراضي لـ Link
هو التمرير إلى أعلى الصفحة. عندما يكون هناك hash محدد، سوف ينتقل إلى id المحدد، مثل علامة <a>
العادية. لمنع التمرير إلى الأعلى / hash، يمكن إضافة scroll={false}
إلى Link
:
<Link href="/#hashid" scroll={false}>
تعطيل التمرير إلى الأعلى
</Link>
Middleware
من الشائع استخدام Middleware للمصادقة أو لأغراض أخرى تتضمن إعادة كتابة المستخدم إلى صفحة مختلفة. لكي يعمل مكون <Link />
بشكل صحيح في جلب الروابط مسبقًا مع إعادة الكتابة عبر Middleware، تحتاج إلى إخبار Next.js بكل من URL المعروض وURL المطلوب جلبها مسبقًا. هذا مطلوب لتجنب عمليات الجلب غير الضرورية إلى middleware لمعرفة المسار الصحيح للجلب المسبق.
على سبيل المثال، إذا كنت تريد تقديم مسار /dashboard
الذي يحتوي على مشاهدات للمستخدمين المصادق عليهم والزوار، يمكنك إضافة شيء مشابه لما يلي في Middleware الخاص بك لإعادة توجيه المستخدم إلى الصفحة الصحيحة:
export function middleware(req) {
const nextUrl = req.nextUrl
if (nextUrl.pathname === '/dashboard') {
if (req.cookies.authToken) {
return NextResponse.rewrite(new URL('/auth/dashboard', req.url))
} else {
return NextResponse.rewrite(new URL('/public/dashboard', req.url))
}
}
}
في هذه الحالة، سترغب في استخدام الكود التالي في مكون <Link />
الخاص بك:
import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'
export default function Page() {
const isAuthed = useIsAuthed()
const path = isAuthed ? '/auth/dashboard' : '/public/dashboard'
return (
<Link as="/dashboard" href={path}>
Dashboard
</Link>
)
}
معلومة مفيدة: إذا كنت تستخدم المسارات الديناميكية، فستحتاج إلى تكييف خصائص
as
وhref
. على سبيل المثال، إذا كان لديك مسار ديناميكي مثل/dashboard/authed/[user]
تريد عرضه بشكل مختلف عبر middleware، فستكتب:<Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>
.
سجل الإصدارات
الإصدار | التغييرات |
---|---|
v13.0.0 | لم يعد يتطلب وسم <a> فرعي. تم توفير أداة تحويل الشفرات لتحديث قاعدة الشفرة تلقائيًا. |
v10.0.0 | خاصية href التي تشير إلى مسار ديناميكي يتم حلها تلقائيًا ولم تعد تتطلب خاصية as . |
v8.0.0 | تحسين أداء الجلب المسبق (Prefetching). |
v1.0.0 | تم تقديم next/link . |