Custom Apollo Integration for Nuxt
A compact guide for setting up and extending Apollo Client in Nuxt, focusing on module limitations, plugin customization, and best practices.
Overview
Nuxt modules simplify setup but run only at build time, meaning they can’t access runtime APIs like useRuntimeConfig or useApolloClient.
For dynamic logic (auth, caching, token refresh), use plugins, which run after app startup with full Nuxt context.
Why Use Plugins
1. Serialization
During build, Nuxt serializes module options into JSON.
Complex objects like ApolloClient or custom Links lose references and can’t be reused at runtime.
2. Context Isolation
Modules execute in a separate build context, isolated from Nuxt’s runtime environment.
Plugins, on the other hand, run inside the live app, where you can modify the Apollo client safely.
✅ Modules: define static config & generate runtime code
✅ Plugins: handle runtime logic & modify live instances
Basic Setup
Configure the Apollo client in nuxt.config.ts:
export default defineNuxtConfig({
graphql: {
clients: {
default: {
httpEndpoint: ''
}
}
}
})Plugin Customization
Create a plugin at app/plugins/apollo.ts to adjust the client at runtime:
export default defineNuxtPlugin(() => {
const { client } = useApolloClient()
const runtimeConfig = useRuntimeConfig()
const access = useCookie('accessToken')
const httpLink = new HttpLink({
uri: runtimeConfig.public.apiBase
})
const authLink = new SetContextLink((prevContext) => {
return {
headers: {
Authorization: `Bearer ${accessToken.value}`
}
}
})
const retryLink = new RetryLink()
const errorLink = new ErrorLink(({ error, forward, operation }) => {
console.log(error)
})
const cache = client.cache as InMemoryCache
cache.policies.addPossibleTypes(possibleTypes.possibleTypes)
const typePolicies: StrictTypedTypePolicies = {}
cache.policies.addTypePolicies(typePolicies)
client.setLink(ApolloLink.from([authLink, errorLink, retryLink, httpLink]))
})Plugin Execution Order
Nuxt runs plugins in registration order, based on file name sorting.
When customizing Apollo, ensure your plugin runs before any other plugin that uses Apollo Client.
You can control this by prefixing the file name (e.g., 00.apollo.ts) or following Nuxt’s plugin registration order.
Best Practices
- Use
runtimeConfigfor environment-dependent URLs and secrets. - Manage
possibleTypesandtypePolicieswithin plugins. - Avoid storing tokens globally on the server.
- Test on both SSR and CSR modes for consistent behavior.