الواجهة البرمجية للمكوّن next/link في Next.js

من موسوعة حسوب

ننصحك قبل قراءة المقال بالاطلاع على التوجّه في Next.js أولًا

بإمكانك تفعيل التنقل بين الصفحات أو الوجهات في جانب العميل عبر المكوّن Link الذي تصدّره المكتبة next/link.

لنفترض وجود الملفات التالية في المجلد pages:

  • pages/index.js
  • pages/about.js
  • pages/blog/[slug].js

يمكننا الحصول على رابط إلى كل صفحة من هذه الصفحات كالتالي:

يقبل المكوّن Link الخاصيات التالية:

  • href: المسار أو عنوان URL الذي سننتقل إليه. وهذه الخاصية هي الوحيدة التي نحتاجها، كما يمكن أن تكون كائنًا (كائن URL).
  • as: منسّق اختياري للمسار الذي سيُعرض في شريط عناوين المتصفح. استُخدم هذا المعامل سابقًا للتوجه الديناميكي ما قبل الإصدار 9.5.3.
  • 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)}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

حالة وجود مكوّن ابن مخصص للمكون 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>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink
  • لا بد أيضًا من استخدام الخاصية passHref إن كنت ستعمل مع الميزة jsx jsx@ العائدة لمكتبة التنسيق emotion حتى لو استخدمت <a> مباشرة.
  • يجب أن يدعم المكوّن الخاصية onClick كي يقع حدث التنقل بالطريقة الصحيحة.

الحالة التي يكون فيها ابن المكوّن link مكوّن دالة

لا بد في هذه الحالة من تغليف المكوّن ضمن React.forwardRef إضافةً إلى استخدام الخاصية passHref:

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>
      <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' },
          }}
        >
          <a>About us</a>
        </Link>
      </li>
      <li>
        <Link
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

يحتوي المثال السابق روابط إلى:

  • /about?name=test: وجهة محددة مسبقًا.
  • /blog/my-post: وجهة ديناميكية.

بإمكانك استعمال أية خاصية كما عُرّفت في توثيق Node.js لوحدة URL.

استبدال العنوان في سجل العناوين بدلًا من دفعه

يدفع push المكوّن Link افتراضيًا عنوان URL الجديد في مكدس سجل العناوين history. لكن بإمكانك استخدام الخاصية replace لمنع إضافة مُدخل جديد إلى السجل كالتالي:

<Link href="/about" replace>
  <a>About us</a>
</Link>

إلغاء التمرير إلى أعلى الصفحة

يقتضي السلوك الافتراضي للمكوّن link بالانتقال إلى أعلى الصفحة. لكن عند وجود إشارة العنوان الفرعي (#) سينتقل بالصفحة إلى هذا العنوان المحدد كما يفعل أي رابط نمطي <a>. لهذا إن أردت إلغاء السلوك الافتراضي بالانتقال إلى أعلى الصفحة، استخدم الصيغة التالية:

<Link href="/#hashid" scroll={false}>
  <a>Disables scrolling to the top</a>
</Link>

المصادر

  • الصفحة Next/Link من توثيق Next.js الرسمي.