I have two NextJS applications under separate repositories and different domains.
I want the second NextJS application to fetch the first NextJS application’s backend code. Backend is graphql + apollo. But I am reaching a “Access-Control-Allow-Origin” problem since they have mismatching domains.
Here is a diagram to illustrate my setup. What are the best practices to tackle this issue? Two UIs, two domains, one backend.
On localhost, it works well.
Application A: localhost:3000
Application B: localhost:4000
For application B, NEXT_PUBLIC_APOLLO_BASE_URL is “localhost:3000”. But when it switches to the hosted domain, CORS issues arise
import {
ApolloClient,
ApolloClientOptions,
InMemoryCache,
NormalizedCacheObject,
createHttpLink,
} from '@apollo/client'
import { auth } from 'app/firebase/clientApp'
import { setContext } from '@apollo/client/link/context'
//import { offsetLimitPagination } from "@apollo/client/utilities";
//
//
const apolloCache = new InMemoryCache({
typePolicies: {
SearchConfigOption: {
keyFields: ['pathName'],
},
Query: {
fields: {
/* filterItems: {
keyArgs: ['user'],
merge(existing, incoming) {
if (!incoming) return existing
if (!existing) return incoming // existing will be empty the first time
const { items, ...rest } = incoming
let result = rest
result.items = [...existing.items, ...items] // Merge existing items with the items from incoming
return result
},
},*/
},
},
},
})
const httpLink = createHttpLink({
uri: `${process.env.NEXT_PUBLIC_APOLLO_BASE_URL}api/graphql`,
credentials: 'include',
})
const authLink = setContext(async (_, { headers }) => {
const user = auth.currentUser
const token = user && (await user.getIdToken())
const modifiedHeader = {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : 'Bearer null',
},
}
return modifiedHeader
})
const client = new ApolloClient({
ssrMode: typeof window === 'undefined',
link: authLink.concat(httpLink),
cache: apolloCache,
connectToDevTools: process.env.NODE_ENV !== 'production',
credentials: 'include',
})
export default client
The Issue here is that you have to configure the domain of application B in the backend CORS middleware, if you’re using an express server for your backend, this is how you would configure it
const express = require('express');
const cors = require('cors');
const { ApolloServer } = require('apollo-server-express');
const app = express();
const corsOptions = {
origin: ['https://merchant-domain.com', "https://application-2-domain.com"],
credentials: true,
};
app.use(cors(corsOptions));
const server = new ApolloServer({
// Apollo server configuration
});
server.applyMiddleware({ app, path: '/api/graphql', cors: false });
app.listen({ port: 3000 }, () =>
console.log(`Server ready at http://localhost:3000${server.graphqlPath}`)
);