[{"_path":"/getting-started/composables","_draft":false,"_partial":false,"_empty":false,"title":"Composables","description":"Nuxt Apollo provides and Auto Imports key composables for seamless usage throughout your application.","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt Apollo provides and "},{"type":"element","tag":"a","props":{"href":"https://v3.nuxtjs.org/guide/concepts/auto-imports","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Auto Imports"}]},{"type":"text","value":" key composables for seamless usage throughout your application."}]},{"type":"element","tag":"h2","props":{"id":"useapollo"},"children":[{"type":"text","value":"useApollo"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useApollo"}]},{"type":"text","value":" allows you to utilize "},{"type":"element","tag":"a","props":{"href":"/getting-started/auth-helpers"},"children":[{"type":"text","value":"Nuxt Apollo's authentication helpers"}]},{"type":"text","value":" as well as easily access the configured Apollo clients."}]},{"type":"element","tag":"code","props":{"code":"const { clients, getToken, onLogin, onLogout } = useApollo()\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const { clients, getToken, onLogin, onLogout } = useApollo()\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"useasyncquery"},"children":[{"type":"text","value":"useAsyncQuery"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is a convenience wrapper around Nuxt's "},{"type":"element","tag":"a","props":{"href":"https://v3.nuxtjs.org/api/composables/use-async-data/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"useAsyncData"}]},{"type":"text","value":" that allows you to easily query the Apollo client. The returned result is the extracted data property from the GraphQL query."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useAsyncQuery"}]},{"type":"text","value":" is primarily used for querying data when a page or component is initially loaded. Have a look at "},{"type":"element","tag":"a","props":{"href":"#usequery"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useQuery"}]}]},{"type":"text","value":" for fetching data upon user interaction."}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\nquery getShips($limit: Int!) {\n ships(limit: $limit) {\n id\n }\n}`\n\nconst { data } = await useAsyncQuery(query, { limit: 2 })\n\nif (data.value?.ships) {\n // log response\n console.log(data.value.ships)\n}\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const query = gql`\nquery getShips($limit: Int!) {\n ships(limit: $limit) {\n id\n }\n}`\n\nconst { data } = await useAsyncQuery(query, { limit: 2 })\n\nif (data.value?.ships) {\n // log response\n console.log(data.value.ships)\n}\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"uselazyasyncquery"},"children":[{"type":"text","value":"useLazyAsyncQuery"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useLazyAsyncQuery"}]},{"type":"text","value":" composable provides a wrapper around "},{"type":"element","tag":"a","props":{"href":"#useasyncquery"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useAsyncQuery"}]}]},{"type":"text","value":" that lazily loads the specified query."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Unlike it's counterpart "},{"type":"element","tag":"a","props":{"href":"#useasyncquery"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useAsyncQuery"}]}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useLazyAsyncQuery"}]},{"type":"text","value":" is non-blocking, hence the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"null"}]},{"type":"text","value":" state of your result must be manually handled."}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\n query currentUser { \n whoAmI { \n id \n }\n }\n`\n\nconst { data } = await useAsyncQuery(query)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const query = gql`\n query currentUser { \n whoAmI { \n id \n }\n }\n`\n\nconst { data } = await useAsyncQuery(query)\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"usequery"},"children":[{"type":"text","value":"useQuery"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is the primary method of querying your GraphQL server, unlike "},{"type":"element","tag":"a","props":{"href":"#useasyncquery"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useAsyncQuery"}]}]},{"type":"text","value":" which is best used for initially fetching data in SSR applications, "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" can comfortably be used in any scenario."}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\n query getShips($limit: Int!) {\n ships(limit: $limit) {\n id\n }\n }\n`\n\nconst variables = { limit: 5 }\n\nconst { result } = useQuery(query, variables)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const query = gql`\n query getShips($limit: Int!) {\n ships(limit: $limit) {\n id\n }\n }\n`\n\nconst variables = { limit: 5 }\n\nconst { result } = useQuery(query, variables)\n"}]}]}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"More Information on "},{"type":"element","tag":"a","props":{"href":"https://v4.apollo.vuejs.org/api/use-query.html#usequery","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Vue Apollo's "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useQuery"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"usemutation"},"children":[{"type":"text","value":"useMutation"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" composable allows you to modify server-side data"}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\n mutation addUser ($input: UserInput!) {\n addUser (input: $input) {\n id\n }\n }\n`\n\nconst variables = {\n name: 'John Doe',\n email: 'jd@example.com'\n}\n\nconst { mutate } = useMutation(query, { variables })\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const query = gql`\n mutation addUser ($input: UserInput!) {\n addUser (input: $input) {\n id\n }\n }\n`\n\nconst variables = {\n name: 'John Doe',\n email: 'jd@example.com'\n}\n\nconst { mutate } = useMutation(query, { variables })\n"}]}]}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"More Information on "},{"type":"element","tag":"a","props":{"href":"https://v4.apollo.vuejs.org/api/use-mutation.html#usemutation","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Vue Apollo's "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useMutation"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"usesubscription"},"children":[{"type":"text","value":"useSubscription"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useSubscription"}]},{"type":"text","value":" composable allows you to interface with WebSocket compliant GraphQL servers to listen for realtime updates."}]},{"type":"element","tag":"alert","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt Apollo currently only supports subscriptions over WebSockets."}]}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\n subscription onMessageAdded($channelId: ID!) {\n messageAdded(channelId: $channelId) {\n id\n text\n }\n }\n`\n\nconst variables = { channelId: 'abc' }\n\nconst { result } = useSubscription(query, variables)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const query = gql`\n subscription onMessageAdded($channelId: ID!) {\n messageAdded(channelId: $channelId) {\n id\n text\n }\n }\n`\n\nconst variables = { channelId: 'abc' }\n\nconst { result } = useSubscription(query, variables)\n"}]}]}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"More Information on "},{"type":"element","tag":"a","props":{"href":"https://v4.apollo.vuejs.org/api/use-subscription.html#usesubscription","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Vue Apollo's "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useSubscription"}]}]}]}]}]},"_type":"markdown","_id":"content:1.getting-started:3.composables.md","_source":"content","_file":"1.getting-started/3.composables.md","_extension":"md"},{"_path":"/recipes/authentication","_draft":false,"_partial":false,"_empty":false,"title":"Authentication","description":"Configure Nuxt Apollo via the `apollo` property.","excerpt":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"token-storage"},"children":[{"type":"text","value":"Token Storage"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are two (2) token storage modes supported by Nuxt Apollo, These include "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"localStorage"}]}]},{"type":"text","value":" and "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"cookie"}]}]},{"type":"text","value":", with the latter being the default and recommended option."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"tokenStorage"}]},{"type":"text","value":" is set to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"cookie"}]},{"type":"text","value":" by default. This can be changed to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"localStorage"}]},{"type":"text","value":" by modifying the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"tokenStorage"}]},{"type":"text","value":" property in the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"apollo"}]},{"type":"text","value":" section of nuxt config, or on a per client basis."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt Apollo's authentication helper functions work closely with the token storage mode, and ultimately determines where the token is stored and retrieved from when these functions are triggered."}]},{"type":"element","tag":"h3","props":{"id":"local-storage"},"children":[{"type":"text","value":"Local Storage"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"localStorage"}]},{"type":"text","value":" mode can be enabled by setting the "},{"type":"element","tag":"a","props":{"href":"/getting-started/configuration#tokenstorage"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"tokenStorage"}]}]},{"type":"text","value":" property to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"localStorage"}]},{"type":"text","value":". This can be applied globally to all Apollo clients by passing the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"tokenStorage"}]},{"type":"text","value":" property to the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"apollo"}]},{"type":"text","value":" section in your nuxt config, or per client."}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtConfig({\n modules: ['@nuxtjs/apollo'],\n\n apollo: {\n clients: {\n default: {\n tokenStorage: 'localStorage',\n }\n }\n }\n})\n","filename":"nuxt.config.ts","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export default defineNuxtConfig({\n modules: ['@nuxtjs/apollo'],\n\n apollo: {\n clients: {\n default: {\n tokenStorage: 'localStorage',\n }\n }\n }\n})\n"}]}]}]},{"type":"element","tag":"alert","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Doesn't support server-side rendering (SSR)."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Due to "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"localStorage"}]}]},{"type":"text","value":" being a browser-only feature, it is not possible to use this mode for server-side rendering (SSR)."}]},{"type":"element","tag":"h2","props":{"id":"cookie-storage"},"children":[{"type":"text","value":"Cookie Storage"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Cookie storage is the recommended approach and is also required for server-side rendering (SSR)."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This module provides a "},{"type":"element","tag":"a","props":{"href":"/getting-started/configuration#proxycookies"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"proxyCookies"}]}]},{"type":"text","value":" option ("},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"enabled by default"}]},{"type":"text","value":") which when enabled, will proxy all cookies from the client to the server. This is particularly useful for server-side rendering (SSR)."}]},{"type":"element","tag":"h3","props":{"id":"credentials"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"credentials"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Request credentials"}]},{"type":"text","value":" determine whether or not the browser should send cookies to the server."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Options:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"same-origin"}]},{"type":"text","value":" ("},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"default"}]},{"type":"text","value":"): Instruct the browser to send cookies to the server if the request is made from the same domain."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"include"}]},{"type":"text","value":": Required if the backend server lives on a different domain that the client. Instructs the browser to send cookies to 3rd party domains."}]}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtConfig({\n modules: ['@nuxtjs/apollo'],\n\n apollo: {\n clients: {\n default: {\n httpLinkOptions: {\n credentials: 'include'\n }\n }\n }\n }\n})\n","filename":"nuxt.config.ts","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export default defineNuxtConfig({\n modules: ['@nuxtjs/apollo'],\n\n apollo: {\n clients: {\n default: {\n httpLinkOptions: {\n credentials: 'include'\n }\n }\n }\n }\n})\n"}]}]}]},{"type":"element","tag":"alert","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The backend server must be configured to allows credentials from the desired origins."}]}]},{"type":"element","tag":"h3","props":{"id":"httponly"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"httpOnly"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt Apollo is designed to support the "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"httpOnly"}]}]},{"type":"text","value":" cookie option with minimal effort on your part. This option prevents cookies from being accessed by JavaScript, hence it renders the authentication helpers trivial."}]},{"type":"element","tag":"h2","props":{"id":"auth-hook"},"children":[{"type":"text","value":"Auth Hook"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt Apollo provides a SSR friendly auth token retrieval logic which meet the needs of most applications. This is based on the configured client's "},{"type":"element","tag":"a","props":{"href":"#tokenstorage"},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"tokenStorage"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"apollo:auth"}]},{"type":"text","value":" hook allows you to override the aforementioned behavior of Nuxt Apollo, and provide custom logic for manually retrieving and applying the authentication token accordingly. This should account for client and server modes."}]},{"type":"element","tag":"alert","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"apollo:auth"}]},{"type":"text","value":" hook is implemented, The "},{"type":"element","tag":"a","props":{"href":"getting-started/auth-helpers#gettoken"},"children":[{"type":"text","value":"getToken auth helper"}]},{"type":"text","value":" adheres to the custom logic provided to the hook."}]}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtPlugin((nuxtApp) => {\n // access cookie for auth\n const cookie = useCookie('')\n\n nuxtApp.hook('apollo:auth', ({ client, token }) => {\n // `client` can be used to differentiate logic on a per client basis.\n\n // apply apollo client token\n token.value = ''\n })\n})\n","filename":"plugins/apollo.ts","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export default defineNuxtPlugin((nuxtApp) => {\n // access cookie for auth\n const cookie = useCookie('')\n\n nuxtApp.hook('apollo:auth', ({ client, token }) => {\n // `client` can be used to differentiate logic on a per client basis.\n\n // apply apollo client token\n token.value = ''\n })\n})\n"}]}]}]},{"type":"element","tag":"alert","props":{"type":"warning"},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt composables such as useState, useCookie, useRequestHeaders and more, should not be called directly in the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"apollo:auth"}]},{"type":"text","value":" hook. This would result in a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"nuxt instance unavailable"}]},{"type":"text","value":" error on the server-side."}]}]}]},"_type":"markdown","_id":"content:2.recipes:1.authentication.md","_source":"content","_file":"2.recipes/1.authentication.md","_extension":"md"}]