-
Hi there, I was "surprised" to learn that next/link will prefetch any Link that is in the viewport. For two reasons: I just want to open the discussion and see if you ever thought/discussed on implementing a prefetch that is based on mouse over/touch instead? Just like https://instant.page/ is doing. cc @dieulot maybe since you're the author of instant.page you might have some ideas here! |
Beta Was this translation helpful? Give feedback.
Replies: 16 suggested answers 12 replies
-
Assuming they don’t get a lot of complaints from their viewport prefetching, I recommend them to switch to prefetching on hover on desktop and keep viewport prefetching on mobile. It would make a lot less requests and be nearly as fast as using the viewport on all form factors. If Next got complaints about being a server hog, also switch to touchstart prefetching on mobile. |
Beta Was this translation helpful? Give feedback.
-
Hi everyone! |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
I had realized this when I setup my first project in NextJS a few days ago. I exported my project to my website as static files and realized in the network tab that it's pre-fetching my pages when I hover my navigation links and fixed it by creating my own Link component like this import Link from 'next/link';
export default (props) => (
<Link
href={props.href}
as={props.as}
passHref={props.href}
prefetch={props.prefetch || false}
replace={props.replace}
scroll={props.scroll}
>
<a {...props}>{props.children}</a>
</Link>
); This also makes it easier to add any attributes you want to add to the |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
@vvo I assume you haven't found a solution yet? I have a similar problem, where I show around 20-30 links at the same time in the viewport, each of them pointing to a page themselves. It fires 20-30 requests immediately, and every network traffic freezes. I would like to create a Link whose prefetch behavior could be controlled by hover. What I have so far, is the following hook: import * as React from "react"
/**
* @note Treat `true` as `undefined`. See explanation:
* @see https://github.com/vercel/next.js/blob/master/errors/prefetch-true-deprecated.md
*/
export default function usePrefetchOnHover(prefetch?: boolean | "onHover") {
const [shouldPrefetch, setShouldPrefetch] = React.useState<false | undefined>(false)
if (prefetch === "onHover") {
return {
prefetch: shouldPrefetch,
onMouseOver: () => setShouldPrefetch(undefined),
onFocus: () => setShouldPrefetch(undefined),
}
}
return { prefetch: prefetch ? undefined : prefetch }
} This, if given
Some page
</NextLink>">
const Link = ({prefetch, children, ...props}) => { return ( <NextLink {...usePrefetchOnHover(prefetch)}/> <a>{children}</a> </NextLink> ) } <NextLink prefetch="onHover" href="/some/page"> Some page </NextLink> |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
This is working out of the box from NextJS v10.0.3. <Link prefetch={false}> PR that fixed the issue: #18859 |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
prefetch={false} should not prefetch anything on any event, be it mounting or hovering. I suggest something like this: prefetch=always | hover | none or false or undefined. |
Beta Was this translation helpful? Give feedback.
-
Update: you can prefetch on hover with prefetch={false} (good or bad). |
Beta Was this translation helpful? Give feedback.
-
I too need to completely disable prefetching, as it clogs the server for larger e-commerce sites. |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
To force prefetching on mouseOver even if the flag is set to false is terrible practice. Only way to rationalize this is looking at the business model of Vercel, they provide hosting services and charge based on data transferred... |
Beta Was this translation helpful? Give feedback.
-
but on lighthouse prefetch will still request when i set prefetch to false and it's reduce the performance score how can i disable prefetch? |
Beta Was this translation helpful? Give feedback.
-
We see a lot of 404 with this feature. Our use case is a language selector, where you can switch to the corresponding page in another language. In our case |
Beta Was this translation helpful? Give feedback.
-
IMO, prefetch={false} should disable prefetching at all. Users may hang up your server by simply hovering the mouse all over the page that contains a lot of links. Please, at least consider caching the prefetch response, but the best solution would be avoid prefetching when not needed. |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
I'd like to also vote for where this would give devs full control alternative naming options: |
Beta Was this translation helpful? Give feedback.
-
I also vote on @NawarA's way of implementation. Whether to |
Beta Was this translation helpful? Give feedback.
-
Can someone please implement this? It's absolute madness to apply prefetch on hover as the default when prefetch is set to false. Just think about it for a second, when you scroll down a page the cursor passes over a lot of links. I used up my entire budget of serverless functions within ten days because of this default behavior. |
Beta Was this translation helpful? Give feedback.
{{editor}}'s edit
{{editor}}'s edit
-
I wanted a my links to never prefetch, even on hover. So, I created a custom link to use for my needs. I use it like:
Click Me
</MainLink>
)">
const MyLink = () => ( <MainLink href="/path/to/page"> Click Me </MainLink> ) Below is a reference of my implementation (with a few changes): import { useRouter } from 'next/router';
import type { HTMLAttributeAnchorTarget } from 'react';
import React from 'react';
export interface MainLinkProps {
href?: string;
target?: HTMLAttributeAnchorTarget | undefined;
className?: string;
children: React.ReactNode;
}
const MainLink: React.FC<MainLinkProps> = React.forwardRef(
(
{ href, target, className, children }: MainLinkProps,
ref: React.Ref<HTMLAnchorElement> | undefined,
) => {
const router = useRouter();
const handleClick = React.useCallback(
async (e: React.SyntheticEvent) => {
if (href) {
e.preventDefault();
return await router.push(href);
}
},
[router, href],
);
return (
<a
ref={ref}
className={className}
target={target}
href={href || '/'}
onClick={handleClick}
>
{children}
</a>
);
},
);
export default MainLink; |
Beta Was this translation helpful? Give feedback.
Update: you can prefetch on hover with prefetch={false} (good or bad).
See here: https://nextjs.org/docs/api-reference/next/link