Next.js Link vs Sitecore JSS Link

Learn the difference between the Sitecore JSS Link and the Next.js Link components, as well as the importance of correctly configuring link preloading

April 9, 2024

By Tyler Holmes

Sitecore JSS Link IS Next.js Link.

Sitecore JSS Link is an expansion of the Next.js Link. The main difference is that the JSS Component checks if the link is internal/external and renders using the Next.js Link component (next/link) or a normal link component (<a>).

Next.js Links benefits are for Internal linking, and is mainly used for preloading data. That said, the Next.js link also handles external links without any issues.

Page preloading happens when the next <Link /> component enters the user's viewport (similar to how animations work, think intersection observer). Next.js will automatically prefetch the data from the internal link and load the linked page. This is done in the background with the goal of improving client-side navigation performance.

Note: Prefetching is only enabled in production.

JSS Next.js SDK Link component: In normal mode returns a next/Link component. You control prefetch like on the next/Link component. In edit mode returns a JSS React SDK Link component.

JSS React SDK Link component: In edit mode returns an editable <span> with or without a simple <a> inside. This does not have prefetch functionality.

Conclusion: Prefetching cannot be the cause of performance issues in Experience Editor or Pages when using SSR.

Next <Link> is a stock React component built by Next.js that builds upon the standard HTML <a> element to provide native prefetching for client-side navigation. Hence, it closely resembles the native <a> element but provides extra advantages such as customizable navigation behavior via props, enhanced performance, and SEO benefits.

PropExampleTypeDescription
hrefhref="/dashboard"String / ObjectString or object that points to the desired location. The object can be used to pass query string data (URL)
prefetchprefetch={false}BooleanShould the link be preloaded when entering the user's viewport. False = preload on link hover.
replacereplace={false}BooleanUsed to replace the browsers current history state instead of adding a new URL to the browser's history.
scrollscroll={false}BooleanUsed to scroll the user to the top of the page on a new page route, and maintain scroll position on forwards/backwards navigation
passHrefpassHref={true}BooleanForces Link to send the href property to its child. Defaults to false
shallowshallow={true}BooleanUpdate the path of the current page without rerunning getStaticProps, getServerSideProps or getInitialProps. Defaults to false
localelocale=”en”StringThe active locale is automatically prepended. locale allows for providing a different locale. When false href has to include the locale as the default behavior is disabled.

Legacy Link: Next.js 12.X and Under

The legacy link required an <a> tag to be nested inside the <Link> tag. You could then apply all properties (ex: onClick, ClassName) to the <a> tag directly.

Using passHref was also a requirement for legacy links, otherwise the href wouldn't be passed to the <a> tag, and it would be a JS only route change.

Example of Legacy Code you might see in older projects

<Link href="/posts/[post]" scroll={false} passHref prefetch={false}>
  <a className="bg-primary p-8 rounded" onClick={()=> alert("Click")}>
    Lorem ipsum dolor sit, amet consectetur adipisicing elit. Odit deleniti qui nobis
    minima eaque, hic praesentium tempora optio perspiciatis perferendis soluta labore
    esse mollitia ipsam reprehenderit tenetur? Molestiae, laboriosam assumenda.
  </a>
</Link>

New Next.js Link: Next.js 13.X and Up

This is the currently used Link tag by Next.js and Sitecore JSS. The main difference is the removal of the nested <a> tags and passHref no longer being required.

<Link
  href="/posts/[post]"
  scroll={false}
  prefetch={false}
  className="bg-primary p-8 rounded"
  onClick={() => alert('Click')}
  >
    Lorem ipsum dolor sit, amet consectetur adipisicing elit. Odit deleniti qui nobis
    minima eaque, hic praesentium tempora optio perspiciatis perferendis soluta labore
    esse mollitia ipsam reprehenderit tenetur? Molestiae, laboriosam assumenda.
</Link>

When To Enable Next Preloading/Prefetching

Link preloading/prefetching is one of the reasons Next.js feels so fast as a user. However, Next.js will try to immediately preload all links that are in the user's viewport. This can slow down initial page loads, subsequent dynamically imported components and lazy loaded images.

You can't actually disable prefetching. You can only toggle between two modes:

  • Prefetch upon entering Viewport
  • Prefetch upon user hovering over the link (prefetch={false})

If you want to avoid preloading all together, you would use a native <a> tag, although this would only be relevant in very niche use cases, and is not recommended. A plain <a> will do a full page refresh and reload the entire Next.js/React app. A next/link with prefetch={false} will do an XHR to load the target page JSON file and update the DOM using React's Shadow DOM and will be significantly faster!

<Link
    prefetch={false}
    ... >

Generally, we only want viewport preloading for high traffic links, and large real estate links.

Examples:

  • High traffic pages in the nav bar
  • Hero banner links (CTA’s)
  • Featured article links

Preloading/Prefetching Case Study

Tech news portal featuring articles on cryptocurrency analysis, AI voice clone tech, and business software updates.

For example: The above the fold on this website’s homepage has ~41 total links:

  • 11 Links in the nav
    • 4 Link Dropdowns in the Nav (each containing more links)
  • 9 Sub nav links
  • 7 Articles presented to the user (Each one is a link)
    • 14 sub link, inside the article links (Topics & Authors)

We want to optimize this for the user to prevent their browser from immediately loading ~41 different links! We want to “Preload on Hover” for almost all the links on this page. There are only a few potential candidates for preloading in the view port. You want to preload the links that have large real estate (massive featured article) and URLs with a high click-through rate (~25%+).

In the below image, I suggest the few links that I think could be candidates for “Preload in Viewport”.

Image Key:

  • Potential candidates for Preload in Viewport = Red
  • Preload on Hover = Yellow & Green

Screenshot of a technology news website's homepage with headlines about cryptocurrency, AI developments, and emerging tech with highlights  showing candidates for preload

In the above image I am assuming that one of the two navigation links (Artificial Intelligence, Cryptocurrency) have a high click-through rate, and I'm recommending that they preload them for the user. However, it is very realistic that the only “Preload in Viewport” item on the page would be the massive-featured article.

You should use “Preload in Viewport” sparingly, as it will put more load on both your servers and the user's computer. It's more efficient to default to only preloading on hover for most of your links.

You should only use the native Next.js link if you don't have all the LinkField data. A good example of this is linking to social media sites.

Example:

<div>
  <NextLink
    href={`https://twitter.com/intent/tweet?text=${socialPageTitle}+-+${currentUrl}`}
    target="_blank">
    <SvgTwitter />
  </NextLink>
</div>

Sometimes you will have 2 different links, one that is a full LinkField, and another that is only a URL. You can't naturally import both at the same time, since they both have the same component name. You can use a simple alias import to import the default Next.js link under a different name.

import { default as NextLink } from 'next/link';
import { Link } from '@sitecore-jss/sitecore-jss-nextjs';

...

<NextLink href={</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">https:</span></span></span><span class="hljs-tag">//</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">twitter.com</span></span></span><span class="hljs-tag">/</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">intent</span></span></span><span class="hljs-tag">/</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">tweet</span></span></span><span class="hljs-tag">?</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">text</span></span></span><span class="hljs-tag">=</span></span></span><span class="hljs-subst"><span class="hljs-string"><span class="hljs-subst"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">${socialPageTitle}</span></span></span></span></span></span></span><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">+-+</span></span></span></span></span><span class="hljs-subst"><span class="hljs-string"><span class="hljs-subst"><span class="hljs-tag"><span class="hljs-string"><span class="hljs-tag"><span class="hljs-string">${currentUrl}</span></span></span></span></span></span></span><span class="hljs-string"><span class="hljs-tag">} target="_blank"> <SvgTwitter /> </NextLink>

<Link field={props.fields?.link} className="font-semibold text-primary underline text-2xl px-sm py-xs border rounded" />



Tyler Holmes

Full Stack Developer

Tyler is an experienced Full Stack Developer who has worked on a plethora of unique projects. He possesses a deep understanding of Technical SEO, C#, and React/Next.js.

Second CTA Ogilvy's Legacy

Today, David Ogilvy's influence can still be felt in the world of advertising.

Ogilvy's Influence Example
Emphasis on research Market research is a crucial part of any successful advertising campaign
Focus on headlines A strong headline can make the difference between an ad that is noticed and one that is ignored
Use of visuals Compelling images and graphics are essential for capturing audience attention