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
Build the Interface
  • Routing
  • Layouts
  • Middlewares
  • Error Handling
Load and Render
  • Data Fetching
  • SSR and CSR
  • Head and SEO
Extend Runable
  • Auto-imports
  • Plugins
  • Modules
Configure and Ship
  • Runtime Configuration
  • CSS and Assets
  • Production Build
CLI
  • Overview
  • Create
  • Prepare
  • Build
  • MCP
  • AI Skills
  • Inspector

Data Fetching

Load data with caching, deduplication, cancellation, and SSR hydration.

Use useAsyncData() to load a resource required to render a page. Runable waits during SSR, serializes the cache into the HTML, then restores it before hydration.

Load a resource

<script setup lang="ts">
type Project = { id: number; name: string };

const { data: projects, pending, error, refresh } = await useAsyncData(
  "projects",
  async (signal) => {
    return $fetch<Project[]>("/api/projects", { signal });
  },
);
</script>

<template>
  <p v-if="pending">Loading…</p>
  <p v-else-if="error">{{ error.message }}</p>
  <ul v-else>
    <li v-for="project in projects" :key="project.id">{{ project.name }}</li>
  </ul>
  <button type="button" @click="refresh">Refresh</button>
</template>

Choose a stable key

The key identifies the cache entry and deduplicates simultaneous requests. Include parameters that change the result:

const route = useRoute();
const id = computed(() => String(route.params.id));

const project = await useAsyncData(
  `project:${id.value}`,
  (signal) => $fetch(`/api/projects/${id.value}`, { signal }),
  { watch: [id] },
);

Adjust execution

const result = await useAsyncData("stats", loadStats, {
  server: true,
  lazy: false,
  immediate: true,
  ttl: 60_000,
  default: () => [],
  transform: (items) => items.slice(0, 10),
});
OptionUse it to
server: falseRun the call only in the browser
lazy: trueAvoid blocking SSR
immediate: falseTrigger the call with execute()
ttlSet the cache duration
defaultProvide an initial value
transformTransform before caching
watchReload after a reactive change

refresh() forces a new call. execute() uses the same execution engine.

URLs during SSR

A relative URL is not always resolved as it is in the browser when the fetcher runs on the server. Use an origin from runtime configuration if your HTTP backend requires one.

Report an issue Edit this page
Error Handling

Capture Vue, Router, and browser errors in a consistent interface.

SSR and CSR

Choose the application's rendering mode and isolate browser-only code.

On this page

  • 1Load a resource
  • 2Choose a stable key
  • 3Adjust execution
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