(pathname: string, priority: RequestPriority = 'low')
| 8 | const prefetchPromises = new Map<string, Promise<ReactElement>>(); |
| 9 | |
| 10 | export function prefetchRoute(pathname: string, priority: RequestPriority = 'low') { |
| 11 | let url = getRSCUrl(pathname); |
| 12 | |
| 13 | // Skip if already prefetched |
| 14 | if (prefetchPromises.has(url)) { |
| 15 | return; |
| 16 | } |
| 17 | |
| 18 | if (priority === 'low' && 'connection' in navigator) { |
| 19 | let conn: any = navigator.connection; |
| 20 | if (conn.saveData || /2g/.test(conn.effectiveType)) { |
| 21 | return; |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | // Start prefetch and cache the promise |
| 26 | const prefetchPromise = fetchRSC<ReactElement>(url, {priority}); |
| 27 | |
| 28 | prefetchPromise |
| 29 | .then(res => { |
| 30 | // Remove from cache after 30 seconds (rely on browser cache for subsequent requests) |
| 31 | // This is required so we can reuse the same promise on click. |
| 32 | setTimeout(() => { |
| 33 | prefetchPromises.delete(url); |
| 34 | }, 30_000); |
| 35 | return res; |
| 36 | }) |
| 37 | .catch(() => { |
| 38 | prefetchPromises.delete(url); |
| 39 | }); |
| 40 | |
| 41 | prefetchPromises.set(url, prefetchPromise); |
| 42 | } |
| 43 | |
| 44 | export function getPrefetchedPromise(rscPath: string): Promise<ReactElement> | undefined { |
| 45 | return prefetchPromises.get(rscPath); |
no test coverage detected