我有一个“使用客户端”Apollo 上下文包装组件,它需要访问 graphql url 和我的 .env 文件中的访问令牌。然而,由于这是在客户端渲染的,我无法访问我的 .env 变量。
next js v13 有没有方法可以做到这一点?
我的代码
'use client';
// ^ this file needs the "use client" pragma
import { ApolloLink, HttpLink } from '@apollo/client';
import {
ApolloNextAppProvider,
NextSSRInMemoryCache,
NextSSRApolloClient,
SSRMultipartLink,
} from '@apollo/experimental-nextjs-app-support/ssr';
const { GRAPHQL_ENDPOINT, CONTENTFUL_ACCESS_TOKEN } = process.env;
// have a function to create a client for you
export function makeClient() {
const httpLink = new HttpLink({
uri: GRAPHQL_ENDPOINT,
headers: {
authorization: CONTENTFUL_ACCESS_TOKEN ? `Bearer ${CONTENTFUL_ACCESS_TOKEN}` : '',
},
fetchOptions: { cache: 'no-store' },
});
return new NextSSRApolloClient({
// use the `NextSSRInMemoryCache`, not the normal `InMemoryCache`
cache: new NextSSRInMemoryCache(),
link:
typeof window === 'undefined'
? ApolloLink.from([
// in a SSR environment, if you use multipart features like
// @defer, you need to decide how to handle these.
// This strips all interfaces with a `@defer` directive from your queries.
new SSRMultipartLink({
stripDefer: true,
}),
httpLink,
])
: httpLink,
});
}
// you need to create a component to wrap your app in
export function ApolloWrapper({ children }: React.PropsWithChildren) {
// @ts-ignore
return <ApolloNextAppProvider makeClient={makeClient}>{children}</ApolloNextAppProvider>;
}
我在下一个文档中阅读了更多内容,您需要在环境变量名称上使用 NEXT_PUBLIC_ 前缀,这样构建就不会安全地作为客户端组件的一部分进行编译。
更新代码
'use client';
// ^ this file needs the "use client" pragma
import { ApolloLink, HttpLink } from '@apollo/client';
import {
ApolloNextAppProvider,
NextSSRInMemoryCache,
NextSSRApolloClient,
SSRMultipartLink,
} from '@apollo/experimental-nextjs-app-support/ssr';
// eslint-disable-next-line
const uri = process.env['NEXT_PUBLIC_GRAPHQL_ENDPOINT'];
// eslint-disable-next-line
const authorization = process.env['NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN'];
// have a function to create a client for you
export function makeClient() {
const httpLink = new HttpLink({
uri,
headers: {
authorization: authorization ? `Bearer ${authorization}` : '',
},
fetchOptions: { cache: 'no-store' },
});
return new NextSSRApolloClient({
// use the `NextSSRInMemoryCache`, not the normal `InMemoryCache`
cache: new NextSSRInMemoryCache(),
link:
typeof window === 'undefined'
? ApolloLink.from([
// in a SSR environment, if you use multipart features like
// @defer, you need to decide how to handle these.
// This strips all interfaces with a `@defer` directive from your queries.
new SSRMultipartLink({
stripDefer: true,
}),
httpLink,
])
: httpLink,
});
}
// you need to create a component to wrap your app in
export function ApolloWrapper({ children }: React.PropsWithChildren) {
// @ts-ignore
return <ApolloNextAppProvider makeClient={makeClient}>{children}</ApolloNextAppProvider>;
}