Recipes

Preload & navigate

Seed a route's named query from its loader so navigation is local-first: present rows enter immediately, the server subscription revalidates in the background, and extra queries ride into the SSR first paint without blocking.

View as Markdown

A route declares its data intent with rindle.loader({ query, ssr, until }). query is preloaded and retained, so a locally-present view enters immediately on navigation and its server-authority subscription revalidates in the background. ssr names extra queries that belong in the server-rendered first paint but must not block a client-side navigation. until: "present" commits the navigation as soon as usable rows exist rather than waiting for the authoritative read.

In the wild — tantaman.github.io

The article route preloads the post for instant navigation and folds its comments into the first paint only:

// src/routes/_shell.$slug.tsx
export const Route = createFileRoute("/_shell/$slug")({
  loader: rindle.loader({
    // TanStack intent-preload and click navigation share this retain. A locally present article can
    // enter immediately; Rindle keeps its server-authority revalidation alive in the background.
    query: ({ params }) => postQuery(params.slug),
    // Comments belong in the server-rendered first paint, but do not block client navigation.
    ssr: ({ params }) => [
      postCommentsQuery({ postId: params.slug, limit: POST_COMMENTS_PAGE_SIZE }),
    ],
    until: "present",
  }),
  component: PostView,
});

rindle-site/src/routes/_shell.$slug.tsx L25–37 · tantaman.github.io

A loader can seed several named queries at once — the blog index primes both the page and the featured list:

// src/routes/_shell.index.tsx
export const Route = createFileRoute("/_shell/")({
  loader: rindle.loader({
    query: () => [postsQuery({ limit: POSTS_PAGE_SIZE }), featuredPostsQuery({})],
  }),
  component: Home,
});

rindle-site/src/routes/_shell.index.tsx L16–21 · tantaman.github.io

See also