diff --git a/docs/content/1.getting-started/4.configuration.md b/docs/content/1.getting-started/4.configuration.md index 1bb667a..2309b4f 100644 --- a/docs/content/1.getting-started/4.configuration.md +++ b/docs/content/1.getting-started/4.configuration.md @@ -195,6 +195,10 @@ Pass cookies from the browser to the GraphQL API in SSR mode. Enabled by default. :: +### `proxyHeaders` + +Headers to be passed from the browser to the GraphQL API in SSR mode. + ### `corsOptions` Specify CORS options to be used for client-side requests. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38a5539..f6456c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2148,6 +2148,7 @@ packages: - '@types/node' - eslint - less + - lightningcss - meow - optionator - rollup @@ -7151,6 +7152,7 @@ packages: - debug - eslint - less + - lightningcss - meow - optionator - rollup @@ -9186,10 +9188,11 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.3.9(@types/node@20.4.2) + vite: 4.4.4(@types/node@20.4.2) transitivePeerDependencies: - '@types/node' - less + - lightningcss - sass - stylus - sugarss diff --git a/src/runtime/plugin.ts b/src/runtime/plugin.ts index 69874e7..0855b4c 100644 --- a/src/runtime/plugin.ts +++ b/src/runtime/plugin.ts @@ -15,12 +15,15 @@ export default defineNuxtPlugin((nuxtApp) => { const { clients }: GqlConfig = defu(config?.['graphql-client'], config?.public?.['graphql-client']) - const cookie = (process.server && useRequestHeaders(['cookie'])?.cookie) || undefined + const proxyHeaders = Object.values(clients || {}).flatMap(v => v?.proxyHeaders).filter((v, i, a) => Boolean(v) && a.indexOf(v) === i) as string[] + if (!proxyHeaders.includes('cookie')) { proxyHeaders.push('cookie') } + + const requestHeaders = ((process.server && useRequestHeaders(proxyHeaders)) as Record) || undefined for (const [name, v] of Object.entries(clients || {})) { const host = (process.client && v?.clientHost) || v.host - const proxyCookie = v?.proxyCookies && !!cookie + const proxyCookie = v?.proxyCookies && !!requestHeaders?.cookie let headers = v?.headers as Record | undefined const serverHeaders = (process.server && (typeof headers?.serverOnly === 'object' && headers?.serverOnly)) || {} @@ -30,13 +33,18 @@ export default defineNuxtPlugin((nuxtApp) => { delete headers.serverOnly } + for (const header of (v?.proxyHeaders || [])) { + if (!requestHeaders?.[header]) { continue } + + headers = { ...headers, [header]: requestHeaders?.[header as keyof typeof requestHeaders] } + } + const opts = { - ...((proxyCookie || v?.token?.value || v?.headers) && { - headers: { - ...(headers && { ...headers, ...serverHeaders }), - ...(proxyCookie && { cookie }) - } - }), + headers: { + ...headers, + ...serverHeaders, + ...(proxyCookie && { cookie: requestHeaders?.cookie }) + }, ...v?.corsOptions } @@ -59,9 +67,9 @@ export default defineNuxtPlugin((nuxtApp) => { if (v.tokenStorage?.mode === 'cookie') { if (process.client) { token.value = useCookie(v.tokenStorage.name!).value - } else if (cookie) { + } else if (requestHeaders?.cookie) { const cookieName = `${v.tokenStorage.name}=` - token.value = cookie.split(';').find(c => c.trim().startsWith(cookieName))?.split('=')?.[1] + token.value = requestHeaders?.cookie.split(';').find(c => c.trim().startsWith(cookieName))?.split('=')?.[1] } } else if (process.client && v.tokenStorage?.mode === 'localStorage') { const storedToken = localStorage.getItem(v.tokenStorage.name!) diff --git a/src/types.d.ts b/src/types.d.ts index 59ecadf..4a25d4b 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -88,6 +88,14 @@ export interface GqlClient { * */ proxyCookies?: boolean + + /** + * Headers to be passed from the browser to the GraphQL API in SSR mode. + * + * @type {string[]} + */ + proxyHeaders?: string[] + /** * Specify CORS options to be used for client-side requests. * @type {object}