mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Fix NextLink prefetch side effect on unsigned claims persistance (#4325)
This commit is contained in:
@@ -157,9 +157,14 @@ export function Link(props: LinkProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// Not sure why yet, but it seems necessary to force prefetch to true
|
||||
// default behavior doesn't seem to properly use the client router cache.
|
||||
const _prefetch = prefetch === null || prefetch === undefined ? true : prefetch;
|
||||
// Not sure why yet, but forcing prefetch to true seems necessary for the
|
||||
// client router cache to be used properly.
|
||||
//
|
||||
// However, we need to disable prefetch for links with query params that
|
||||
// can trigger server-side side effects, such as persisting visitor claims in a
|
||||
// cookie or starting the assistant. Automatic RSC prefetch requests can otherwise
|
||||
// trigger those effects without user intent.
|
||||
const _prefetch = hasSideEffectQueryParams(href) ? false : (prefetch ?? true);
|
||||
|
||||
return (
|
||||
<NextLink
|
||||
@@ -175,6 +180,31 @@ export function Link(props: LinkProps) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given href carries query params that have a server-side side effect when fetched:
|
||||
* - `visitor.*` params persist unsigned visitor claims into the `gitbook-visitor-public` cookie.
|
||||
* - `ask` triggers the assistant & `q` the search.
|
||||
*
|
||||
* NextLink automatically prefetches links (RSC requests) on hover/viewport, which would fire those
|
||||
* side effects without any user intent, so such links should not be prefetched.
|
||||
*/
|
||||
function hasSideEffectQueryParams(href: string): boolean {
|
||||
const baseURL = typeof window !== 'undefined' ? window.location.origin : 'http://localhost';
|
||||
const linkURL = URL.canParse(href) ? new URL(href) : new URL(href, baseURL);
|
||||
|
||||
if (linkURL.searchParams.get('ask') !== null || linkURL.searchParams.get('q') !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const key of linkURL.searchParams.keys()) {
|
||||
if (key.startsWith('visitor.')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A box used to contain a link overlay.
|
||||
* It is used to create a clickable area that can contain other elements.
|
||||
|
||||
Reference in New Issue
Block a user