# Server Queries and Preloading

> Resolve query data on the server and hand it to the browser so hydration does not refetch what you already have.

Source: [https://askrjs.com/docs/data/server-queries](https://askrjs.com/docs/data/server-queries)

Status: stable. Packages: @askrjs/askr.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Example

Register the server handler against the same query definition used by components, then prefetch into the request data runtime.

```tsx
import { defineServerQueries, serveQuery } from '@askrjs/askr/data';

export const queries = defineServerQueries(
  serveQuery(projectQuery, ({ input, signal }) =>
    projects.get(input.id, { signal })
  )
);
```

## Define server queries

serveQuery(query, handler) pairs a QueryDefinition with a ServerQueryHandler that knows how to actually fetch that query's data server-side, returning a ServerQueryEntry. defineServerQueries(...entries) collects a set of those pairings into a ServerQueryRegistry, which is what a server-side prefetch context looks handlers up against.

## Register handlers

A ServerQueryHandler receives { input, request, signal } and returns the query's result, giving it access to the incoming Request when the handler needs headers, cookies, or other request context that a client-side fetch wouldn't have. The registry's get(query) method looks up the handler for a given QueryDefinition, so the same query object used on the client is the lookup key on the server.

## Prefetch

createQueryPrefetchContext({ runtime, registry, request, signal, mode }) sets up a context for running queries ahead of render, with mode distinguishing 'ssr' from 'spa' prefetching. prefetchQuery(context, query, input) populates the runtime's cache, returning a boolean promise indicating whether the prefetch succeeded — but which fetch path it runs depends on mode: only 'ssr' mode looks up and calls the registered ServerQueryHandler (and skips the prefetch with a console warning if none is registered for that query); 'spa' mode never consults the registry at all and calls the query's own client-side fetch() instead.

## Dehydrate and hydrate

dehydrateDataRuntime(runtime) serializes a DataRuntime's cached query data into a plain Record&lt;string, unknown&gt; that can be embedded in the server-rendered HTML. hydrateDataRuntime(runtime, data) does the reverse on the client, seeding a fresh runtime with that serialized data so components mounting from createQuery() find their data already cached instead of refetching on first render.

## Documentation navigation

[Previous](https://askrjs.com/docs/data/mutations-and-invalidation/index.md) | [Next](https://askrjs.com/docs/data/actions-and-forms/index.md)
