Skip to content

Global Callbacks

Global callbacks let you define callback logic once in a Nuxt plugin and automatically apply it to all API requests in your application.

Why Global Callbacks?

Instead of repeating the same callbacks in every composable:

typescript
// ❌ Repetitive - same auth logic everywhere
useFetchGetPets({}, {
  onRequest: ({ headers }) => {
    return { headers: { ...headers, 'Authorization': `Bearer ${getToken()}` } }
  }
})

useFetchGetOwners({}, {
  onRequest: ({ headers }) => {
    return { headers: { ...headers, 'Authorization': `Bearer ${getToken()}` } }
  }
})

Define once in a plugin, apply to every request automatically:

typescript
// ✅ plugins/api-callbacks.ts — runs for all matching requests
export default defineNuxtPlugin(() => {
  const globalCallbacks = {
    onRequest: ({ headers }) => {
      const token = useCookie('auth-token').value
      if (token) {
        return { headers: { ...headers, Authorization: `Bearer ${token}` } }
      }
    },
  }

  return {
    provide: {
      getGlobalApiCallbacks: () => globalCallbacks,
    },
  }
})

The Plugin File

Global callbacks live in a Nuxt plugin you create manually at plugins/api-callbacks.ts:

typescript
// plugins/api-callbacks.ts
export default defineNuxtPlugin(() => {
  const globalCallbacks = {
    onRequest: ({ headers }) => {
      const token = useCookie('auth-token').value
      if (token) {
        return { headers: { ...headers, 'Authorization': `Bearer ${token}` } }
      }
    },
    onError: (error) => {
      if (error.status === 401) {
        navigateTo('/login')
      }
    }
  }

  return {
    provide: {
      getGlobalApiCallbacks: () => globalCallbacks
    }
  }
})

TIP

The provide: { getGlobalApiCallbacks: () => globalCallbacks } block is required — it connects the plugin to the composables runtime. Don't remove it.

Full setup guide →

All Four Callbacks

The globalCallbacks object supports the same four lifecycle callbacks as local callbacks:

typescript
const globalCallbacks = {
  onRequest: ({ url, headers, body, query }) => {
    // Before every request
    // Return { headers, body, query } to modify the request
    return { headers: { ...headers, 'X-Request-ID': crypto.randomUUID() } }
  },
  onSuccess: (data, context) => {
    // After every successful request
  },
  onError: (error, context) => {
    // After every failed request
    // Return false to prevent the local onError from running
  },
  onFinish: ({ success, data, error }) => {
    // After every request regardless of success or failure
  }
}

Global callbacks may be provided as a single rule object or as an array of rules.

Multiple Rules

Pass an array of rules instead of a single object to apply different logic to different endpoints. Each rule runs independently — they are not mutually exclusive.

typescript
// plugins/api-callbacks.ts
export default defineNuxtPlugin(() => {
  return {
    provide: {
      getGlobalApiCallbacks: () => [
        // Rule 1: add auth header to all requests
        {
          onRequest: ({ headers }) => {
            const token = useCookie('auth-token').value
            if (token) return { headers: { ...headers, Authorization: `Bearer ${token}` } }
          },
        },
        // Rule 2: show a toast on every DELETE success
        {
          methods: ['DELETE'],
          onSuccess: () => useToast().success('Deleted successfully'),
        },
        // Rule 3: handle 401 globally, only on private routes
        {
          patterns: ['/api/private/**'],
          onError: (error) => {
            if (error.status === 401) {
              navigateTo('/login')
              return false // suppress local onError
            }
          },
        },
      ],
    },
  }
})

All rules are evaluated in order. For onRequest, headers and query are merged and later local modifications still take priority.

Rule Filters

Each rule can be scoped with patterns (URL globs) and methods (HTTP verbs). A rule only runs when all its filters match.

typescript
[
  // Only runs for GET and POST on /api/v2/**
  {
    patterns: ['/api/v2/**'],
    methods: ['GET', 'POST'],
    onRequest: ({ headers }) => ({ headers: { ...headers, 'X-Version': '2' } }),
  },
]

A rule with no filters runs for every request.

Execution Order

Global callbacks always run before local callbacks:

    Request


  Global onRequest  →  Local onRequest


                        HTTP Request

                    ┌─────────┴─────────┐
                    │                   │
               2xx Success         4xx/5xx Error
                    │                   │
                    ▼                   ▼
          Global onSuccess       Global onError
                    │                   │
                    ▼                   ▼
           Local onSuccess        Local onError
                    │                   │
                    └──────────┬────────┘


                      Global onFinish


                       Local onFinish

Control Options

Skip global callbacks for specific requests directly from the composable:

typescript
// Skip ALL global callbacks
useFetchGetPublicPets({}, {
  skipGlobalCallbacks: true
})

// Skip only specific callbacks
useFetchGetPets({}, {
  skipGlobalCallbacks: ['onSuccess', 'onFinish']
})

Learn more about control options →

Next Steps

Released under the Apache-2.0 License.