Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Composables and utils

A composable is a function that hides repeating logic with reactive data, for example a likes counter. Its name usually starts with use. In Vue you import such functions by hand, while Nuxt makes them available automatically from the app/composables/ folder. For plain functions without reactivity there is a sibling folder, app/utils/.

Your own composable

npx nuxi add composable useLikes

The command creates app/composables/useLikes.ts. Replace its content:

// app/composables/useLikes.ts
export function useLikes() {
  const likes = ref(0)
 
  function like() {
    likes.value++
  }
 
  return { likes, like }
}

ref is not imported either: Nuxt provides Vue functions (ref, computed, watch, onMounted and others) itself.

Using it

Add a like button to the card app/components/PostCard.vue:

<!-- app/components/PostCard.vue -->
<script setup lang="ts">
defineProps<{
  post: { id: number; title: string; text: string }
}>()
 
const { likes, like } = useLikes()
</script>
 
<template>
  <article class="post-card">
    <h3>
      <NuxtLink :to="`/posts/${post.id}`">{{ post.title }}</NuxtLink>
    </h3>
    <button @click="like">Likes: {{ likes }}</button>
  </article>
</template>

Each card on /posts has its own counter: the function runs again for every component and creates a new ref.

Utils

Functions without reactivity go into app/utils/. Create app/utils/formatDate.ts:

// app/utils/formatDate.ts
export function formatDate(date: string) {
  return new Date(date).toLocaleDateString('en-US', {
    day: 'numeric',
    month: 'long',
    year: 'numeric'
  })
}

Now any component can write {{ formatDate('2025-03-14') }} and get "March 14, 2025" without an import.

What is imported automatically

FromWhat
Vueref, computed, watch, onMounted and others
NuxtuseRoute, navigateTo, useFetch, useState and others
app/composables/Exports of top-level files
app/utils/Exports of top-level files
app/components/Components

An explicit import also works if it reads better: import { useLikes } from '~/composables/useLikes'.

Where to call composables

Nuxt composables (useRoute, useFetch, useState) and your own ones that use them are called in <script setup>, in another composable, in middleware or in a plugin. Calling them inside setTimeout or after an await in a regular function can fail with "A composable that requires access to the Nuxt instance was called outside of a plugin".

Common mistake

Nuxt scans only the top-level files of app/composables/. A file in a subfolder, such as app/composables/posts/usePosts.ts, is not imported automatically, and the template fails with usePosts is not defined. Keep composables directly in the folder or import a subfolder file explicitly.

Thanks for reading!

Donate to the site — we work hard for you.