Using NextAuth for GraphQL authentication with Apollo client in Next.js encounter the error
Hooks can only be called inside of the body of a function.
import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';
import { useMutation, useApolloClient } from '@apollo/client';
import { LOGIN_MUTATION } from '../../../graphql/mutations';
import { getErrorMessage } from '../../../lib';
export default (req, res) =>
NextAuth(req, res, {
providers: [
Providers.Credentials({
name: 'Credentials',
credentials: {
identifier: { label: "Email", type: "text" },
password: { label: "Password", type: "password" }
},
authorize: async (credentials) => {
const client = useApolloClient();
const [errorMsg, setErrorMsg] = useState();
const [login] = useMutation(LOGIN_MUTATION);
try {
await client.resetStore();
const { data: { login: { user, jwt } } } = await login({
variables: {
identifier: credentials.identifier,
password: credentials.password
}
});
if (user) {
return user;
}
} catch (error) {
setErrorMsg(getErrorMessage(error));
}
}
})
],
site: process.env.NEXTAUTH_URL || "http://localhost:3000",
session: {
jwt: true,
maxAge: 1 * 3 * 60 * 60,
updateAge: 24 * 60 * 60,
},
callbacks: {},
pages: {
signIn: '/auth/signin'
},
debug: process.env.NODE_ENV === "development",
secret: process.env.NEXT_PUBLIC_AUTH_SECRET,
jwt: {
secret: process.env.NEXT_PUBLIC_JWT_SECRET,
}
});
I am wondering is there anyway to make this work with apollo? Thank you for the helps.
As in the comments rightfully pointed out, you can't use hooks in server-side code. You would have to create a new ApolloClient
like this:
const client = new ApolloClient()
Then you can do queries like this for example:
const { data } = await client.query({
query: "Your query",
variables: { someVariable: true }
});
Best would be the to move the creation of the client to a separate external file as a function and import it in your server-side code whenever needed. Like done here for example.
const { data } = await client.mutate({
mutation: "Your query",
variables: { someVariable: true }
});