Should you use next/link (prefetched client side transitions) for pages with any dynamic content?

1.4k views Asked by At

From: next/link

enter image description here

enter image description here

You can see that the <Link> component from next/link enables client-side transitions and link prefetching, which are great features, but maybe not for all cases.

Please see the caveat I've run into. Let's say I have the following pages:

  • Home - Some landing page with a nav bar
  • Latest - Here I can see my latest posts
  • Admin - Here I can add more posts

The Latest page from the example above uses getStaticProps with revalidate. Something like:

export const getStaticProps : GetStaticProps<HomeRoute> = async () => {
  const preloadedState = await getPreloadedState();
  return({
    revalidate: 1,
    props: {
      preloadedState
    }
  });
};

In theory, after 1 second, it should send the last stale response for the next request and trigger a new static regeneration to be served for the subsequent requests. After 1 second, the process repeats and you get fresh data at least after every second, which is pretty much immediately.

Now, see the caveat I've run into with next/link:

    1. User lands on the Home page. There is a Link on the nav bar pointing to Latest. That link will be prefetched by next/link.
    1. In some other browser, an admin goes to the Admin page and adds one more post (which should appear on the Latest page at some point).
    1. Now user clicks on the Latest page link. The new post is not there.
    1. Clicks on Home again. And clicks again on Latest. New post is still not there and never will be.

The transitions in this case are blazing fast, which is nice. But from my experience so far, I think that that user is locked inside a version of my website where the new post will never be available, because that 1st prefetch happened during a time where the new post didn't exist.

The only way that user will ever see the new post is if he/she presses F5 to do a full website reload. And it might be necessary to refresh twice, because the 1st one might return the previous stale version while triggering the regeneration for the next one.

I mean, what is the workaround to this issue? Should I not use next/link for pages that contain any dynamic data? Should I just use normal <a> tags?


UPDATE

From: https://nextjs.org/docs/basic-features/data-fetching#statically-generates-both-html-and-json

enter image description here

From the excerpt above, we can see that indeed, client-side transitions will not trigger a page regeneration, because they'll not call getStaticProps. They only fetch the pre-built JSON object for the page to use as props.

AFAIK, it means that you'll be locked to the version of the page that existed when you first visited the website. You can go back and forth and nothing in the pages would change, because the JSON data is probably cached on client anyway.

PS: I've tested this (like I've mentioned in the question above) and this is exactly what happens.

So how to workaround that? I would like for users that keep an open tab of my website to be able to get updates for the pages when they navigate from one page to the other.

A POSSIBLE SOLUTION

Set some kind of idle time counter, and if the user gets like 10 minutes of idle time (it means that they left the tab open). Whenever he comes back and do some action, I could refresh the whole website to make sure they get the new version of the pages.

Has anyone faced that problem before?

1

There are 1 answers

0
cbdeveloper On BEST ANSWER

I've posted this very same question in several forums and this is the response I've got:

It seems what you described is true. next/link caches results in the client-side and your visitor will not fetch a revalidated result out of the box unless there is a full-page reload.

Depending on the likelihood of content changes, you might want to use <a> instead or you can look at some client-side content reload strategy that kicks in after mount and query data source for updated content.

Given that fact, I'll stick to using next/link and client-side transitions. But I'll also use something like a setInterval() to do a full website reload from time to time, so I'm sure my users will keep getting revalidated pages eventually.