summaryrefslogtreecommitdiff
path: root/packages/integrations/prefetch/src/client.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/prefetch/src/client.ts')
-rw-r--r--packages/integrations/prefetch/src/client.ts36
1 files changed, 35 insertions, 1 deletions
diff --git a/packages/integrations/prefetch/src/client.ts b/packages/integrations/prefetch/src/client.ts
index a8b88d85c..dc05cb84b 100644
--- a/packages/integrations/prefetch/src/client.ts
+++ b/packages/integrations/prefetch/src/client.ts
@@ -77,11 +77,18 @@ export interface PrefetchOptions {
* @default 1
*/
throttle?: number;
+ /**
+ * Element selector used to find all links on the page that should be prefetched on user interaction.
+ *
+ * @default 'a[href][rel~="prefetch-intent"]'
+ */
+ intentSelector?: string | string[];
}
export default function prefetch({
selector = 'a[href][rel~="prefetch"]',
throttle = 1,
+ intentSelector = 'a[href][rel~="prefetch-intent"]',
}: PrefetchOptions) {
// If the navigator is offline, it is very unlikely that a request can be made successfully
if (!navigator.onLine) {
@@ -109,7 +116,21 @@ export default function prefetch({
new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.target instanceof HTMLAnchorElement) {
- toAdd(() => preloadHref(entry.target as HTMLAnchorElement).finally(isDone));
+ const relAttributeValue = entry.target.getAttribute('rel') || '';
+ let matchesIntentSelector = false;
+ // Check if intentSelector is an array
+ if (Array.isArray(intentSelector)) {
+ // If intentSelector is an array, use .some() to check for matches
+ matchesIntentSelector = intentSelector.some((intent) =>
+ relAttributeValue.includes(intent)
+ );
+ } else {
+ // If intentSelector is a string, use .includes() to check for a match
+ matchesIntentSelector = relAttributeValue.includes(intentSelector);
+ }
+ if (!matchesIntentSelector) {
+ toAdd(() => preloadHref(entry.target as HTMLAnchorElement).finally(isDone));
+ }
}
});
});
@@ -117,5 +138,18 @@ export default function prefetch({
requestIdleCallback(() => {
const links = [...document.querySelectorAll<HTMLAnchorElement>(selector)].filter(shouldPreload);
links.forEach(observe);
+
+ const intentSelectorFinal = Array.isArray(intentSelector)
+ ? intentSelector.join(',')
+ : intentSelector;
+ // Observe links with prefetch-intent
+ const intentLinks = [
+ ...document.querySelectorAll<HTMLAnchorElement>(intentSelectorFinal),
+ ].filter(shouldPreload);
+ intentLinks.forEach((link) => {
+ events.map((event) =>
+ link.addEventListener(event, onLinkEvent, { passive: true, once: true })
+ );
+ });
});
}