diff --git a/packages/gitbook/next.config.mjs b/packages/gitbook/next.config.mjs index 992281a11..0a4fc9d78 100644 --- a/packages/gitbook/next.config.mjs +++ b/packages/gitbook/next.config.mjs @@ -37,6 +37,16 @@ const nextConfig = { optimisticClientCache: false, // Disable splitting the RSC in like 5 chunks prefetchInlining: true, + + // Tree-shake barrel imports from these packages so only the used entrypoints ship + // in the client bundle (notably `motion`, which is otherwise pulled in wholesale). + optimizePackageImports: [ + 'motion', + '@gitbook/icons', + 'react-aria', + 'react-aria-components', + 'react-stately', + ], }, env: { diff --git a/packages/gitbook/package.json b/packages/gitbook/package.json index 8afd96e79..7cbc03ff7 100644 --- a/packages/gitbook/package.json +++ b/packages/gitbook/package.json @@ -138,9 +138,7 @@ "e2e-browserless": "bun test ./tests/", "typecheck": "tsc --noEmit" }, - "browserslist": [ - ">0.3%, chrome >= 64, edge >= 79, firefox >= 67, opera >= 51, safari >= 12 and not dead" - ], + "browserslist": ["chrome >= 93, edge >= 93, firefox >= 92, safari >= 15.4, not dead"], "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" diff --git a/packages/gitbook/src/components/TableOfContents/PageLinkItem.tsx b/packages/gitbook/src/components/TableOfContents/PageLinkItem.tsx index 5b7e18347..8e8db7f20 100644 --- a/packages/gitbook/src/components/TableOfContents/PageLinkItem.tsx +++ b/packages/gitbook/src/components/TableOfContents/PageLinkItem.tsx @@ -19,8 +19,6 @@ export function PageLinkItem(props: { page: ClientTOCPageLink }) { ; }; -export type LinkProps = Omit & +export type LinkProps = Omit & LinkInsightsProps & { ref?: React.Ref; /** Enforce href is passed as a string (not a URL). */ href: string; /** This is a temporary solution designed to reduce the number of tailwind class passed to the client */ classNames?: DesignTokenName[]; - /** - * `'hover'` defers prefetching until the link is hovered/focused instead of eagerly on - * viewport — for large link lists (e.g. the sidebar) where prefetching every entry at load - * floods the router. Navigation stays instant since hover fires before the click. - */ - prefetch?: NextLinkProps['prefetch'] | 'hover'; }; type LinkTarget = '_blank' | '_self'; @@ -90,7 +84,6 @@ function defaultIsExternalClient(href: string) { */ export function Link(props: LinkProps) { const { ref, href, prefetch, children, insights, classNames, className, ...domProps } = props; - const [hoverPrefetch, setHoverPrefetch] = React.useState(false); const { externalTarget, isExternalClient = defaultIsExternalClient, @@ -164,32 +157,14 @@ export function Link(props: LinkProps) { ); } - // Forcing prefetch to true seems necessary for the client router cache to be used properly. - // `'hover'` gates that same full prefetch behind hover/focus intent so large link lists (the - // sidebar) don't prefetch every entry at load — see `hoverPrefetch` above. + // Not sure why yet, but forcing prefetch to true seems necessary for the + // client router cache to be used properly. // - // We also disable prefetch for links with query params that can trigger server-side side - // effects (persisting visitor claims in a cookie, starting the assistant); automatic RSC - // prefetch requests would otherwise fire those without user intent. - const _prefetch = hasSideEffectQueryParams(href) - ? false - : prefetch === 'hover' - ? hoverPrefetch - : (prefetch ?? true); - - const hoverPrefetchProps = - prefetch === 'hover' - ? { - onMouseEnter: (event: React.MouseEvent) => { - setHoverPrefetch(true); - domProps.onMouseEnter?.(event); - }, - onFocus: (event: React.FocusEvent) => { - setHoverPrefetch(true); - domProps.onFocus?.(event); - }, - } - : undefined; + // 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 ( {children}