---
title: "Link prefetching"
slug: "link-prefetching"
abstract: "Learn how Content SDK for Angular prefetches loader data for links before the user navigates to them."
---
# Link prefetching

Angular Router runs route `resolve` functions sequentially, and each [loader](https://doc.sitecore.com/sai/en/developers/content-sdk/angular/1x/loaders.html) resolver normally fetches its data on demand when the resolver runs. Link prefetching closes that gap. When a Sitecore link field is rendered through `scRouterLink` or `scRichText`, the SDK can start the destination route's loader requests before the user navigates there, either as soon as the link renders or once the user hovers over it. By the time Angular Router activates the target route and runs its resolvers, the loader data is already fetched or in flight, so the resolvers consume a staged response instead of starting a fresh request. This makes the navigation feel instant.

Prefetching applies only to internal navigation links rendered through the SDK's two link-aware directives:

- `ScRouterLinkDirective` (`*scRouterLink`) renders a Sitecore `LinkField` onto an `<a>` element and routes clicks through `Router.navigateByUrl`.
- `ScRichTextDirective` (`*scRichText`) renders rich text HTML and intercepts internal `<a href>` links inside it the same way.

Links are only ever prefetched in the browser, and never while the page is in Sitecore editing or preview mode.

## Prefetch modes

The `LinkPrefetchMode` type, exported from `@sitecore-content-sdk/angular`, defines three modes:

| Mode | Behavior |
| --- | --- |
| `'eager'` (default) | Prefetch fires as soon as the link is rendered to the DOM. |
| `'hover'` | Prefetch is deferred until the pointer dwells on the link for a configurable delay (default 100 ms). Moving the pointer away before the delay elapses cancels that attempt. Hovering again re-arms the timer and can fire another prefetch; each hover is a fresh signal of intent, not a one-time trigger. |
| `'off'` | Never prefetch this link. |

Regardless of mode, a link is never prefetched when:

- It renders outside the browser, for example during server-side rendering (SSR).
- The page is in Sitecore editing or preview mode.
- The `href` is empty or missing.
- `target="_blank"` is set.
- The `href` is external. External hrefs start with `http://`, `https://`, `mailto:`, `tel:`, `sms:`, `javascript:`, `data:`, `ftp:`, or a protocol-relative `//`.
- The URL doesn't resolve to any configured Angular route, or the matched route or routes have no loader resolvers attached.

## Configuration

### Global configuration

Set the default prefetch behavior under `angular.linkPrefetch` in `sitecore.config.ts`, alongside `angular.loadersCache` and `angular.locales`:

```ts
// sitecore.config.ts
import { defineConfig } from '@sitecore-content-sdk/angular/config';

export default defineConfig({
  // ...other config
  angular: {
    linkPrefetch: {
      mode: 'hover', // 'eager' | 'hover' | 'off' — default 'eager'
      delayMs: 150, // hover dwell time in ms before prefetch fires — default 100, only used when mode is 'hover'
    },
  },
});
```

Both fields are optional. When you omit `angular.linkPrefetch` entirely, it defaults to `{ mode: 'eager', delayMs: 100 }`.

### Per-link override

Each directive exposes its own `prefetch` input, which overrides the global configuration for that link or field. Use this to de-prioritize large flyout or footer link lists by setting them to `'hover'` or `'off'`, while keeping primary navigation `'eager'`.

`ScRouterLinkDirective` exposes the override as `scRouterLinkPrefetch`. Because `scRouterLink` is a structural directive, pass the override through the structural microsyntax rather than as a separate property binding. A separate `[scRouterLinkPrefetch]` binding would target the inner `<a>` element instead of the directive:

```html
<!-- Uses the global/default mode -->
<a *scRouterLink="fields.Link"></a>

<!-- Overrides to hover-prefetch for this link only -->
<a *scRouterLink="fields.Link; prefetch: 'hover'"></a>
```

`ScRichTextDirective` exposes the override as `scRichTextPrefetch`, applied to every internal link found inside that rich text field's rendered HTML:

```html
<div *scRichText="fields.Body; prefetch: 'off'"></div>
```
