Runable v1.0.0-alpha.20
Why Runable? Docs Modules Work with AI Blog About Changelog
  • 01Why Runable?
  • 02Docs
  • 03Modules
  • 04Work with AI
  • 05Blog
  • 06About
  • 07Changelog
Vue without a fixed server runtime.
Getting Started Structure Integrations Guide MCP API
  • Getting Started Structure Integrations Guide MCP API
Components
  • RunablePage
  • RunableLink
  • RunableLayout
  • ClientOnly
Composables
  • useAsyncData
  • useFetch
  • useConfig
  • useRuntime
  • useApp
  • useAppError
  • useRouter
  • useRoute
  • navigateTo
  • onBeforeRouteUpdate
  • injectHead
  • useHead
  • useSeoMeta
  • useHeadSafe
  • useSchemaOrg
Globals
  • $fetch
  • definePageMeta
  • defineVueMiddleware
  • defineVuePlugin
  • Vue APIs

useFetch

Fetch data with reactive options, SSR hydration, caching, and request deduplication.

useFetch is an SSR-friendly wrapper around $fetch. It combines Runable's HTTP client with useAsyncData, so a request made during server rendering can be reused during hydration instead of being sent again in the browser.

const {
  data,
  pending,
  error,
  status,
  refresh,
  execute,
  clear,
} = await useFetch<Data>(request, options);

The request and supported fetch options may be refs or computed getters. When one of them changes, useFetch automatically sends a new request.

<script setup lang="ts">
const page = ref(1);

const { data: projects, status, error } = await useFetch<Project[]>(
  "/api/projects",
  {
    query: { page },
  },
);
</script>

Parameters

request

The URL or request accepted by $fetch. It can also be a ref or a getter.

const projectId = ref("runable");

const { data: project } = await useFetch<Project>(
  () => `/api/projects/${projectId.value}`,
);

options

useFetch accepts $fetch options together with the following async-data options:

OptionDefaultPurpose
keyGeneratedOverrides the cache and deduplication key
servertrueAllows the request to run during SSR
lazyfalseDoes not wait for the request before completing navigation or rendering
immediatetrueStarts the request when the composable is created
default() => undefinedProvides the value used before the request resolves
transform—Transforms the response before storing it
pick—Keeps only the selected keys from an object response
watchAutomaticAdds reactive sources to watch; use false to disable automatic refetching
deepfalseReturns deeply reactive data instead of a shallow ref
dedupe"cancel"Uses "cancel" or "defer" when another request with the same key is pending

All regular ofetch options are also supported, including method, baseURL, query/params, body, headers, credentials, retry, and request or response interceptors.

const token = ref<string>();

const { data } = await useFetch<User>("/api/me", {
  method: "GET",
  headers: () => ({
    authorization: `Bearer ${token.value}`,
  }),
  timeout: 5_000,
});
Reactive requests

The request, method, baseURL, query, params, body, and headers can be refs or getters. They are resolved immediately before each request. Set watch: false when you want to update them without automatically refetching.

Return value

useFetch returns a thenable reactive object. It can be awaited in <script setup>, or used immediately when lazy or immediate: false is appropriate.

PropertyTypePurpose
dataRef<Data | undefined>The resolved and optionally transformed response
pendingRef<boolean>Whether a request is currently running
errorRef<Error | undefined>The most recent request error
statusRef<"idle" | "pending" | "success" | "error">Current request state
refresh(options?)Promise<void>Sends the request again
execute(options?)Promise<void>Alias for refresh
clear()voidCancels the request and resets data, error, status, and cache
const { data, execute, clear } = useFetch<Project[]>("/api/projects", {
  immediate: false,
});

await execute();

// Restore the default value and remove the cached response.
clear();

refresh and execute accept per-execution dedupe, timeout, and signal options.

await refresh({
  dedupe: "defer",
  timeout: 2_000,
});

Transforming and selecting data

Use transform to change the response, or pick to keep selected properties.

const { data: project } = await useFetch<ProjectResponse, Error, Project>(
  "/api/project",
  {
    transform: response => response.project,
  },
);
const { data: user } = await useFetch<User>("/api/user", {
  pick: ["id", "name"],
});

Custom fetch client

Pass $fetch when an API needs its own base URL, headers, or interceptors.

const api = $fetch.create({
  baseURL: "https://api.example.com",
});

const { data } = await useFetch<Project[]>("/projects", {
  $fetch: api,
});

useLazyFetch

useLazyFetch has the same API and options as useFetch, with lazy: true applied automatically.

const { data, pending } = useLazyFetch<Project[]>("/api/projects");

Use $fetch directly when you only need an HTTP request and do not need reactive state, SSR hydration, caching, or deduplication.

Report an issue Edit this page
useAsyncData

Load, cache, and hydrate asynchronous data during SSR.

useConfig

Read the public part of the Runable configuration in the Vue application.

On this page

  • 1Parameters
  • 1.1request
  • 1.2options
  • 2Return value
  • 3Transforming and selecting data
  • 4Custom fetch client
  • 5useLazyFetch
Runable

The Vue framework that brings productive conventions to any backend.

Product

  • Why Runable
  • Documentation
  • Installation
  • Integrations

Project

  • About
  • Blog
  • Changelog
  • Sponsor

Community

  • GitHub
  • Issues
  • Discussions
  • Bluesky

© 2026 Runable. Released under the MIT License.

Open source Built with Vue and Runable