Spoosh
Plugins

Prefetch

Preload data before it's needed

The prefetch plugin lets you load data ahead of time, so it's ready when the user navigates.

Installation

npm install @spoosh/plugin-prefetch

Usage

import { Spoosh } from "@spoosh/core";
import { prefetchPlugin } from "@spoosh/plugin-prefetch";
import { cachePlugin } from "@spoosh/plugin-cache";

const client = new Spoosh<ApiSchema, Error>("/api").use([
  prefetchPlugin(),
  cachePlugin({ staleTime: 5000 }),
]);

const { injectRead, injectWrite, prefetch } = createAngularSpoosh(client);

Basic Prefetch

// Prefetch data
await prefetch((api) => api("posts").GET());

// Prefetch with query parameters
await prefetch((api) => api("posts").GET({ query: { page: 1, limit: 10 } }));

Prefetch with Options

Pass plugin options as the second argument:

await prefetch((api) => api("users/:id").GET({ params: { id: userId } }), {
  staleTime: 60000,
  retries: 3,
});

Prefetch on Hover

A common pattern is prefetching when the user hovers over a link:

@Component({
  selector: "app-post-link",
  template: `
    <a [routerLink]="['/posts', 1]" (mouseenter)="onHover()"> View Post </a>
  `,
})
export class PostLinkComponent {
  onHover() {
    prefetch((api) => api("posts/:id").GET({ params: { id: 1 } }));
  }
}

Prefetch on Route Change

Prefetch data before navigating:

@Component({
  selector: "app-nav",
  template: ` <button (click)="handleNavigation(postId)">View Post</button> `,
})
export class NavComponent {
  constructor(private router: Router) {}

  async handleNavigation(postId: number) {
    await prefetch((api) => api("posts/:id").GET({ params: { id: postId } }));
    this.router.navigate(["/posts", postId]);
  }
}

In-Flight Deduplication

Multiple calls to prefetch the same data will return the same promise, avoiding duplicate network requests. This is built into the prefetch plugin - no deduplication plugin required.

// These will only make ONE network request
prefetch((api) => api("posts").GET());
prefetch((api) => api("posts").GET());
prefetch((api) => api("posts").GET());

Tag Modes

// Mode only - 'all' generates full hierarchy
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: "all", // ['users', 'users/123', 'users/123/posts']
});

// Mode only - 'self' generates only exact path
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: "self", // ['users/123/posts']
});

// Mode only - 'none' generates no tags
await prefetch((api) => api("posts").GET(), { tags: "none" }); // []

// Custom tags only - replaces auto-generated tags
await prefetch((api) => api("posts").GET(), {
  tags: ["custom", "dashboard"], // ['custom', 'dashboard']
});

// Mode + custom tags - 'all' mode combined with custom tags
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: ["all", "dashboard"], // ['users', 'users/123', 'users/123/posts', 'dashboard']
});

// Mode + custom tags - 'self' mode combined with custom tags
await prefetch((api) => api("users/:id/posts").GET({ params: { id: "123" } }), {
  tags: ["self", "dashboard"], // ['users/123/posts', 'dashboard']
});

Options

Plugin Config

OptionTypeDefaultDescription
staleTimenumber-Default stale time for prefetched data (ms)
timeoutnumber30000Timeout to auto-clear stale promises (ms). Prevents memory leaks from requests that never settle.

Prefetch Options

The second argument accepts any plugin options plus:

OptionTypeDescription
tags'all' | 'self' | 'none' | string[]Tag mode or custom tags

On this page