Learn Pinia - Async Server State & Advanced Integration
Episode 14 of 23

Learn Pinia - Async Server State & Advanced Integration

Server state has different characteristics than local state. This episode covers Pinia Colada for fetching, caching, and deduplication, then integrating stores with Vue Router for reading route params and guards, and using external composables alongside Pinia.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Introduction

Since episode 7, our async actions have stored fetch results in state. That pattern works, but server state — data that comes from APIs — has special needs: caching, deduplication, retry, and invalidation. Handling all of that manually is a path to bugs.

Episode 14 covers the official solution in the Pinia ecosystem for this problem: Pinia Colada for async server state, integrating stores with Vue Router, and how to combine external composables with stores.

Pinia Colada: Async Server State

Pinia Colada is an official library in the Pinia ecosystem for server state. It handles fetching, caching, and deduplication with clear keys:

JSQuery server state with Colada
import { defineQuery } from '@pinia/colada'
 
export const useUserQuery = defineQuery({
  key: ['user', 'profile'],
  query: () => fetch('/api/profile').then((res) => res.json()),
})

defineQuery({ key, query }) defines a query that's cached based on key. In a component, the result can be read through the data and status states and the refetch method:

JSUse a query in a component
<script setup lang="ts">
const { data, status, refetch } = useUserQuery()
</script>
 
<template>
  <div v-if="status === 'loading'">Loading...</div>
  <div v-else>{{ data?.name }}</div>
</template>

Compared to manual actions, the advantage is this: two components using the same query share one cache and won't do a double fetch — that's deduplication, which is hard to reproduce manually.

When to Use Colada vs a Store

A simple guideline used by production teams:

  • Server state (data from APIs): Colada or Vue Query — they have caching and invalidation.
  • Client state (UI, sessions, local forms): regular Pinia stores.
JSTwo layers of state
useUserQuery()          // server state: cache and dedup
useCartStore()          // client state: user interaction

Mixing both is common: a store action calls refetch from a query to sync after a mutation, or a query reads store state as a parameter.

Store + Vue Router

Stores often need route information. Inside setup, use useRoute; outside setup, import the router instance:

JSAccess the route inside a store
import router from '@/router'
 
export const useDetailStore = defineStore('detail', {
  actions: {
    async loadCurrent() {
      const id = router.currentRoute.value.params.id
      this.current = await fetch(`/api/item/${id}`).then((r) => r.json())
    },
  },
})

router.currentRoute.value.params.id reads the route parameter directly from the router instance. A more idiomatic alternative: read id via useRoute() in the component, then pass it as an action argument.

Integration with External Composables

Stores and composables aren't rivals — the two can complement each other:

JSComposable called from a store
import { useLocalStorage } from '@vueuse/core'
 
export const usePrefsStore = defineStore('prefs', () => {
  const fontSize = useLocalStorage('font-size', 16)
 
  function setSize(size: number) {
    fontSize.value = size
  }
 
  return { fontSize, setSize }
})

useLocalStorage('font-size', 16) inside a Setup store combines a VueUse composable with global state. This pattern can only be done with a Setup store, as discussed in episode 4.

Info

An important decision: don't store all server state into Pinia. Use Colada or Vue Query for that layer, and Pinia for client state — this split keeps the architecture healthy at scale.

Closing

Episode 14 extends Pinia into modern architecture. You now understand Pinia Colada for async server state with caching and dedup, how to combine stores with Vue Router, and how to integrate external composables inside a Setup store.

Key takeaways:

  • Colada handles fetching, caching, and deduplication of server state.
  • Server state for API data; stores for client state.
  • Route params are accessed via useRoute() or the router instance.
  • Composables like VueUse can be used inside a Setup store.
  • Colada shares a cache across components without double fetching.
  • Separate the server state and client state layers clearly.

In the next episode, episode 15, we'll discuss security and best practices — avoiding the persistence of tokens and secrets, choosing secure storage, sanitizing API data before it enters a store, and best practices for state classification, single responsibility, and role-based access control.

Learn Pinia - Async Server State & Advanced Integration | Learning Pinia