Skip to content

Commit

Permalink
Add prefetch docs (#5271)
Browse files Browse the repository at this point in the history
Co-authored-by: Sarah Rainsberger <[email protected]>
Co-authored-by: Yan Thomas <[email protected]>
  • Loading branch information
3 people authored Nov 9, 2023
1 parent 63f1b9a commit 30f6033
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
185 changes: 185 additions & 0 deletions src/content/docs/en/guides/prefetch.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
title: Prefetch
description: Prefetch links for snappier navigation between pages.
i18nReady: true
---

Page load times play a big role in the usability and overall enjoyment of a site. Astro's **opt-in prefetching** brings the benefits of near-instant page navigations to your multi-page application (MPA) as your visitors interact with the site.

## Enable prefetching

You can enable prefetching with the `prefetch` config:

```js title="astro.config.js" ins={4}
import { defineConfig } from 'astro/config';

export default defineConfig({
prefetch: true
})
```

A prefetch script will be added to all pages of your site. You can then add the `data-astro-prefetch` attribute to any `<a />` links on your site to opt-in to prefetching. When you hover over the link, the script will fetch the page in the background.

```html
<a href="/about" data-astro-prefetch>
```

Note that prefetching only works for links within your site, and not external links.

## Prefetch configuration

The `prefetch` config also accepts an option object to further customize prefetching.

### Prefetch strategies

Astro supports 3 prefetch strategies for various use cases:

- `hover` (default): Prefetch when you hover over or focus on the link.
- `tap`: Prefetch just before you click on the link.
- `viewport`: Prefetch as the links enter the viewport.

You can specify a strategy for an individual link by passing it to the `data-astro-prefetch` attribute:

```html
<a href="/about" data-astro-prefetch="tap">About</a>
```

Each strategy is fine-tuned to only prefetch when needed and save your users' bandwidth. For example:

- If a visitor is using [data saver mode](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData) or has a [slow connection](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType), prefetching will be turned off.
- Quickly hovering or scrolling over links will not prefetch them.
- Links that use the `viewport` strategy are prefetched with a lower priority to avoid clogging up the network.

### Default prefetch strategy

The default prefetch strategy when adding the `data-astro-prefetch` attribute is `hover`. To change it, you can configure [`prefetch.defaultStrategy`](/en/reference/configuration-reference/#prefetchdefaultstrategy) in your `astro.config.js` file:

```js title="astro.config.js" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
prefetch: {
defaultStrategy: 'viewport'
}
})
```

### Prefetch all links by default

If you want to prefetch all links, including those without the `data-astro-prefetch` attribute, you can set [`prefetch.prefetchAll`](/en/reference/configuration-reference/#prefetchprefetchall) to `true`:

```js title="astro.config.js" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
prefetch: {
prefetchAll: true
}
})
```

You can then opt-out of prefetching for individual links by setting `data-astro-prefetch="false"`:

```html
<a href="/about" data-astro-prefetch="false">About</a>
```

The default prefetch strategy for all links can be changed with `prefetch.defaultStrategy` as shown in the [Default prefetch strategy section](#default-prefetch-strategy).

## Prefetch programmatically

As some navigation might not always appear as `<a />` links, you can also prefetch programmatically with the `prefetch()` API from the `astro:prefetch` module:

```astro
<button id="btn">Click me</button>
<script>
import { prefetch } from 'astro:prefetch';
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
prefetch('/about');
});
</script>
```

You can additionally configure the priority of prefetching by passing the `with` option:

```js
// Prefetch with `fetch()`, which has a higher priority.
prefetch('/about', { with: 'fetch' });

// Prefetch with `<link rel="prefetch">`, which has a lower priority
// and manually scheduled by the browser. (default)
prefetch('/about', { with: 'link' });
```

The `prefetch()` API includes the same [data saver mode](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData) and [slow connection](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType) detection, so that it only prefetches when needed.

Make sure to only import `prefetch()` in client-side scripts as it relies on browser APIs.

## Using with View Transitions

When you use [View Transitions](/en/guides/view-transitions/) on a page, prefetching will also be enabled by default. It sets a default configuration of `{ prefetchAll: true }` which enables [prefetching for all links](#prefetch-all-links-by-default) on the page.

You can customize the prefetch configuration in `astro.config.js` to override the default. For example:

```js title="astro.config.js"
import { defineConfig } from 'astro/config';

export default defineConfig({
// Disable prefetch completely
prefetch: false
})
```

```js title="astro.config.js"
import { defineConfig } from 'astro/config';

export default defineConfig({
// Keep prefetch, but only prefetch for links with `data-astro-prefetch`
prefetch: {
prefetchAll: false
}
})
```

## Migrating from `@astrojs/prefetch`

The `@astrojs/prefetch` integration was deprecated in v3.5.0 and will eventually be removed entirely. Use the following instructions to migrate to Astro's built-in prefetching which replaces this integration.

1. Remove the `@astrojs/prefetch` integration and enable the `prefetch` config in `astro.config.js`:

```js title="astro.config.js" ins={6} del={2,5}
import { defineConfig } from 'astro/config';
import prefetch from '@astrojs/prefetch';

export default defineConfig({
integrations: [prefetch()],
prefetch: true
})
```

2. Convert from `@astrojs/prefetch`'s configuration options:

- The deprecated integration used the `selector` config option to specify which links should be prefetched upon entering the viewport.

Add `data-astro-prefetch="viewport"` to these individual links instead.

```html
<a href="/about" data-astro-prefetch="viewport">
```

- The deprecated integration used the `intentSelector` config option to specify which links should be prefetched when they were hovered over or focused.

Add `data-astro-prefetch` or `data-astro-prefetch="hover"` to these individual links instead:

```html
<!-- You can omit the value if `defaultStrategy` is set to `hover` (default) -->
<a href="/about" data-astro-prefetch>

<!-- Otherwise, you can explicitly define the prefetch strategy -->
<a href="/about" data-astro-prefetch="hover">
```

- The `throttles` option from `@astrojs/prefetch` is no longer needed as the new prefetch feature will automatically schedule and prefetch optimally.
5 changes: 5 additions & 0 deletions src/i18n/en/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export default [
slug: 'guides/view-transitions',
key: 'guides/view-transitions',
},
{
text: 'Prefetch',
slug: 'guides/prefetch',
key: 'guides/prefetch',
},

{ text: 'Add-ons', header: true, type: 'learn', key: 'addons' },
{ text: 'Add integrations', slug: 'guides/integrations-guide', key: 'guides/integrations-guide' },
Expand Down

0 comments on commit 30f6033

Please sign in to comment.