---
area: "Learn"
parent: "Links chapter"
url: "https://unpoly.com/learn/preloading"
---
<nav aria-label="Unpoly docs">[All docs](https://unpoly.com/index.md) · [Links chapter](https://unpoly.com/learn/links.md)</nav>

# Preloading links

Links can be preloaded before the user clicks them. When a preloaded link is clicked, the response is already [cached](https://unpoly.com/learn/caching.md) and the interaction feels instant.

[Eager preloading](#on-insert) can also populate the cache to keep links [accessible while offline](https://unpoly.com/learn/network-issues.md#offline-cache).

<nav aria-label="Contents">

#### Contents

- [Preloading on hover](#on-hover)
- [Eager preloading on insertion](#on-insert)
- [Preloading when a link scrolls into view](#on-reveal)
- [Custom preload conditions](#scripted)
- [Preloading a URL](#preloading-a-url)
- [Preload request behavior](#preload-request-behavior)
- [Events](#events)

</nav>

## Preloading on hover {#on-hover}

To preload a link when the user [hovers](https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseover_event) over it, set an [`[up-preload]`](https://unpoly.com/api/up-preload.md) attribute:

```html
<a href="/path" up-preload>Hover over me to preload my content</a>
```

By default Unpoly waits for 90 milliseconds of hovering before making the preload request. This prevents accidental preloading when the mouse moves over a link that the user doesn't intend to click.

To change the delay, set an [`[up-preload-delay]`](https://unpoly.com/api/up-preload.md#up-preload-delay) attribute or configure [`up.link.config.preloadDelay`](https://unpoly.com/api/up.link.config.md#config.preloadDelay). Increasing the delay will lower the load on your server, but will also make the interaction feel less instant.

On touch devices preloading begins when the user places their finger on the link.

To [preload all links on hover](https://unpoly.com/learn/handling-all-links.md#preloading-all-links), configure [`up.link.config.preloadSelectors`](https://unpoly.com/api/up.link.config.md#config.preloadSelectors).

## Eager preloading on insertion {#on-insert}

To preload a link as soon as it appears in the DOM, set an [`[up-preload="insert"]`](https://unpoly.com/api/up-preload.md#up-preload) attribute.

This is useful for links with a high probability of being clicked, like a navigation menu:

```html
<a href="/menu" up-layer="new drawer" up-preload="insert">≡ Menu</a>
```

When an eagerly preloading link is inserted multiple times, only a single request is made. All subsequent render passes will render from the [cache](https://unpoly.com/learn/caching.md).

## Preloading when a link scrolls into view {#on-reveal}

To "lazy preload" a link when it is scrolled into the [viewport](https://unpoly.com/api/up-viewport.md), set an [`[up-preload="reveal"]`](https://unpoly.com/api/up-preload.md#up-preload) attribute.

This is useful when a link is [below the fold](https://www.optimizely.com/optimization-glossary/below-the-fold/) and is unlikely to be clicked until the user scrolls:

```html
<a href="/stories/106" up-preload="reveal">Full story</a>
```

When a lazy preloading link enters and exits its viewport repeatedly, only a single request is made.

## Custom preload conditions {#scripted}

To programmatically preload any link element at a time of your choosing, use the [`up.link.preload()`](https://unpoly.com/api/up.link.preload.md) function.

The following [compiler](https://unpoly.com/learn/enhancing-elements.md) would preload a link with a `[rel=next]` attribute when the user hovers over a `<main>` element:

```js
up.compiler('link[rel=next]', (link) => {
  return up.on('mouseover', 'main', () => up.link.preload(link))
})
```

A link that is preloaded in that fashion does not require an [`[up-preload]`](https://unpoly.com/api/up-preload.md) attribute.

## Preloading a URL {#preloading-a-url}

To preload a given URL without a link element, make a [background](https://unpoly.com/learn/background-requests.md) request that [caches](https://unpoly.com/learn/caching.md):

```js
up.request('/menu', { cache: true, background: true })
```

The cached response will be used by any [followed](https://unpoly.com/api/up-follow.md) link to the same URL:

```html
<a href="/menu" up-follow>Menu</a>
```

## Preload request behavior {#preload-request-behavior}

Requests sent when preloading differ in some ways from requests sent when following a link directly:

- Preloading will not change elements ("render").
- Preloading a link will _not_ [abort](https://unpoly.com/learn/aborting-requests.md) pending requests [targeting](https://unpoly.com/learn/targeting-fragments.md) the same fragments. Only when the link is clicked later are conflicting requests aborted.
- Preload requests are considered [background requests](https://unpoly.com/learn/background-requests.md) and will not show the [progress bar](https://unpoly.com/learn/progress-bar.md).
- Preloaded content is placed into the [cache](https://unpoly.com/learn/caching.md) automatically.
- When a link destination is already cached, preloading will _not_ make another request, even if the cache entry is [expired](https://unpoly.com/learn/caching.md#expiration). When the link is clicked and the cached content is rendered into the page, the fragment will be [revalidated](https://unpoly.com/learn/caching.md#revalidation) if the cache entry is expired.

## Events {#events}

When a link is preloaded via the [`[up-preload]`](https://unpoly.com/api/up-preload.md) attribute or [`up.link.preload()`](https://unpoly.com/api/up.link.preload.md) function, an [`up:link:preload`](https://unpoly.com/api/up:link:preload.md) event is emitted.

The event can be prevented to stop the preload from taking place:

```js
function isSlowConnection() {
  // https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
  return navigator.connection && navigator.connection.effectiveType.includes('2g')
}

up.on('up:link:preload', function(event) {
  if (isSlowConnection()) {
    event.preventDefault()
  }
})
```

<nav aria-label="Reading order">

- [Previous: Handling all links](https://unpoly.com/learn/handling-all-links.md)
- [Next: Navigation bars](https://unpoly.com/learn/navigation-bars.md)

</nav>

