Repository: withastro/astro
File: packages/astro/src/prefetch/index.ts (TypeScript)

Code before:
	 * or otherwise fall back to `'fetch'`. `'link'` works better if the URL doesn't set an appropriate cache header,
	 * as the browser will continue to cache it as long as it's used subsequently.
	 */
	with?: 'link' | 'fetch';
	/**
	 * Should prefetch even on data saver mode or slow connection. (default `false`)
	 */
	ignoreSlowConnection?: boolean;
	/**
	 * A string providing a hint to the browser as to how eagerly it should prefetch/prerender link targets in order to balance performance advantages against resource overheads. (default `immediate`)
	 * Only works if `clientPrerender` is enabled and supported.
	 * Possible values are:
	 *
	 * - `"immediate"`
	 *   : The author thinks the link is very likely to be followed, and/or the document may take significant time to fetch. Prefetch/prerender should start as soon as possible, subject only to considerations such as user preferences and resource limits.
	 * - `"eager"`
	 *   : The author wants to prefetch/prerender a large number of navigations, as early as possible. Prefetch/prerender should start on any slight suggestion that a link may be followed. For example, the user could move their mouse cursor towards the link, hover/focus it for a moment, or pause scrolling with the link in a prominent place.
	 * - `"moderate"`
	 *   : The author is looking for a balance between `eager` and `conservative`. Prefetch/prerender should start when there is a reasonable suggestion that the user will follow a link in the near future. For example, the user could scroll a link into the viewport and hover/focus it for some time.
	 * - `"conservative"`
	 *   : The author wishes to get some benefit from speculative loading with a fairly small tradeoff of resources. Prefetch/prerender should start only when the user is starting to click on the link, for example on `"mousedown"` or `"pointerdown"`.
	 *
	 * If `"eagerness"` is not explicitly specified, it rules default to `immediate`. The browser takes this hint into consideration along with its own heuristics, so it may select a link that the author has hinted as less eager than another, if the less eager candidate is considered a better choice.
	 *
	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/speculationrules#eagerness
	 */
	eagerness?: 'immediate' | 'eager' | 'moderate' | 'conservative';
}

/**
 * Prefetch a URL so it's cached when the user navigates to it.
 *
 * @param url A full or partial URL string based on the current `location.href`. They are only fetched if:
 *   - The user is online
 *   - The user is not in data saver mode
 *   - The URL is within the same origin
 *   - The URL is not the current page
 *   - The URL has not already been prefetched
 * @param opts Additional options for prefetching.
 */
export function prefetch(url: string, opts?: PrefetchOptions) {
	// Remove url hash to avoid prefetching the same URL multiple times
	url = url.replace(/#.*/, '');

	const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false;
	if (!canPrefetchUrl(url, ignoreSlowConnection)) return;
	prefetchedUrls.add(url);

	// Prefetch with speculationrules if `clientPrerender` is enabled and supported
	// NOTE: This condition is tree-shaken if `clientPrerender` is false as its a static value
	if (clientPrerender && HTMLScriptElement.supports?.('speculationrules')) {

Review comment (suggestion):
A couple of suggestions:
- There's no need to quote the entire text from MDN, the link is enough
- Instead of quoting the docs from MDN, we should explain how this new options works. For example, we should explain that this option is applied **only if the browser supports the new speculation rules**. This is a very important information.

Code after:
	 * or otherwise fall back to `'fetch'`. `'link'` works better if the URL doesn't set an appropriate cache header,
	 * as the browser will continue to cache it as long as it's used subsequently.
	 */
	with?: 'link' | 'fetch';
	/**
	 * Should prefetch even on data saver mode or slow connection. (default `false`)
	 */
	ignoreSlowConnection?: boolean;
	/**
	 * A string providing a hint to the browser as to how eagerly it should prefetch/prerender link targets in order to balance performance advantages against resource overheads. (default `immediate`)
	 * Only works if `clientPrerender` is enabled and browser supports Speculation Rules API.
	 * The browser takes this hint into consideration along with its own heuristics, so it may select a link that the author has hinted as less eager than another, if the less eager candidate is considered a better choice.
	 *
	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/speculationrules#eagerness
	 */
	eagerness?: 'immediate' | 'eager' | 'moderate' | 'conservative';
}

/**
 * Prefetch a URL so it's cached when the user navigates to it.
 *
 * @param url A full or partial URL string based on the current `location.href`. They are only fetched if:
 *   - The user is online
 *   - The user is not in data saver mode
 *   - The URL is within the same origin
 *   - The URL is not the current page
 *   - The URL has not already been prefetched
 * @param opts Additional options for prefetching.
 */
export function prefetch(url: string, opts?: PrefetchOptions) {
	// Remove url hash to avoid prefetching the same URL multiple times
	url = url.replace(/#.*/, '');

	const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false;
	if (!canPrefetchUrl(url, ignoreSlowConnection)) return;
	prefetchedUrls.add(url);

	// Prefetch with speculationrules if `clientPrerender` is enabled and supported
	// NOTE: This condition is tree-shaken if `clientPrerender` is false as its a static value
	if (clientPrerender && HTMLScriptElement.supports?.('speculationrules')) {
		debug?.(`[astro] Prefetching ${url} with <script type="speculationrules">`);
		appendSpeculationRules(url, opts?.eagerness ?? 'immediate');
	}
	// Prefetch with link if supported
	else if (
		document.createElement('link').relList?.supports?.('prefetch') &&
		opts?.with !== 'fetch'
	) {
		debug?.(`[astro] Prefetching ${url} with <link rel="prefetch">`);
		const link = document.createElement('link');
		link.rel = 'prefetch';