[{"_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"},{"_path":"/recipes/typescript-support","_draft":false,"_partial":false,"_empty":false,"title":"Typescript Support","description":"","excerpt":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"type-casting"},"children":[{"type":"text","value":"Type Casting"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When using TypeScript, It's greatly beneficial to utilize the correct types of your data. This can be done by casting a custom type as demonstrated below."}]},{"type":"element","tag":"code","props":{"code":"const query = gql`\n query getShips($limit: Int!) {\n ships(limit: $limit) {\n id\n name\n }\n }\n`\n\nconst variables = { limit: 5 }\n\ntype ShipsResult = {\n ships: {\n id?: string;\n name: string;\n }[]\n}\n\nuseQuery(query, variables)\nuseAsyncQuery(query, variables)\n","filename":"app.vue","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 name\n }\n }\n`\n\nconst variables = { limit: 5 }\n\ntype ShipsResult = {\n ships: {\n id?: string;\n name: string;\n }[]\n}\n\nuseQuery(query, variables)\nuseAsyncQuery(query, variables)\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"graphql-documents"},"children":[{"type":"text","value":"GraphQL documents"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When importing "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":".gql"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":".graphql"}]},{"type":"text","value":" files in TypeScript, A common error you may encounter is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"\"Cannot find module '*.gql' or its corresponding type declarations\""}]},{"type":"text","value":". This can be resolved by creating a type declaration file as seen below."}]},{"type":"element","tag":"code","props":{"code":"declare module '*.gql' {\n import { DocumentNode } from 'graphql'\n const Schema: DocumentNode\n export = Schema\n}\n\ndeclare module '*.graphql' {\n import { DocumentNode } from 'graphql'\n const Schema: DocumentNode\n export = Schema\n}\n","filename":"globals.d.ts","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"declare module '*.gql' {\n import { DocumentNode } from 'graphql'\n const Schema: DocumentNode\n export = Schema\n}\n\ndeclare module '*.graphql' {\n import { DocumentNode } from 'graphql'\n const Schema: DocumentNode\n export = Schema\n}\n"}]}]}]}]},"_type":"markdown","_id":"content:2.recipes:3.typescript-support.md","_source":"content","_file":"2.recipes/3.typescript-support.md","_extension":"md"}]