Usage

Server Loaders

Use server loaders to load data in your pages and components.

Server Loaders are a convenient way to load data from the server in your pages components. They can be used as an alternative to useFetch and useAsyncData, and other data fetching mechanisms. Under the hood, server loaders will create regular Nitro server handlers, meaning that they will always run on the server. The returned data will be serialized and sent to the client, which means that while hydrating, they will run only once.

Basic Usage

Server loaders must be defined in the /server/actions directory. Let's start by creating a server loader in /server/actions/books.ts :

/server/actions/books.ts
export const loader = defineServerLoader(async () => {
  // This composable accepts an h3 event handler, you can use any logic that you
  // want here, including database calls, etc.
  return { books: ["title"], manybooks: [] }
})
The file name is very important and will be used for the name of the loader (relative to /server/actions).
Your file must use a loader named export.

Your loader is now ready to use in pages and components.

Let's create a Book component to illustrate the usage.

components/Books.vue
<script setup lang="ts">
const { result } = await useLoader("books")
</script>

<template>
  <div>
    <h1>Books</h1>
    {{ result }} <!-- result will be typed like this : { books: string[]; manybooks: never[];} | null -->
  </div>
</template>

Note: This is very similar to useFetch and API routes. In fact, this module uses useFetch under the hood.

Using dynamic routes and parameters

You can use route parameters in your server loaders. Let's update our book loader to accept parameters and return them.

/server/actions/books.ts
export const loader = defineServerLoader(async (event) => {
  // Use H3 helpers to grab the requests params
  const params = getQuery(event)
  return { books: ["title"], manybooks: [], params }
})

Now we can use this loader in a dynamic route like pages/books/[id].vue :

pages/books/(id).vue
<script setup lang="ts">
const { result } = await useLoader("books")
</script>

<template>
  <div>
    <h1>Params</h1>
    {{ result.params }} <!-- params will be typed like this : { id: string } -->
  </div>
</template>

Using loader options

You can pass options to your loader using the useLoader 2nd argument. A subset of the useFetch options are supported.

You can specify watch sources to automatically reload your loader. This is useful if you want to reload your loader when a specific store value changes. You can also specify custom query parameters :

<script setup lang="ts">
const { result } = await useLoader("books", { params: { id: "1" } })
</script>

Note: useLoader 2nd argument and useFormAction({ loaderOptions }) can both be used to pass loader options to the underlying useFetch call.

Here's the typescript signature of the accepted options :

interface LoaderOptions {
  watch?: MultiWatchSources
  params?: SearchParameters
}