I had the same issue recently when I migrated my app to the Remix template. The solution in this post helped point me in the right direction.
First, I installed the remix-utils package.
Then in the API route, I use the CORS function to return the loader function response:
import { json } from "@remix-run/node";
import { cors } from 'remix-utils/cors';
export const loader = async ({ request }) => {
const response = json({ body: 'data' });
return await cors(request, response);
};
In the action function I also return the data using the CORS function, for example:
export const action = async ({ request }) => {
const body = await request.json();
const query = {
'simple-example': true
};
const queryString = new URLSearchParams(query).toString();
const response = await fetch("https://simple-example.com?" + queryString, {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
return await cors(request, json(data));
};
And finally, the only way I could get around the “…OPTIONS request method not allowed” errors after integrating the CORS function in the API route was to return CORS headers at the very beginning of the handleRequest function in entry.server.jsx, for example:
// Return CORS headers on OPTIONS request
try {
if (request.method === `OPTIONS`) {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept, Authorization, X-Requested-With, Application, ip'
},
});
}
} catch (e) {
console.error(e);
}
I hope this helps you or someone else!