The Vercel platform allows developers to specify response headers when a request comes in. It is a common pattern to allow CORS requests for Serverless Function invocations and for static assets.
Before enabling this feature for your website, it is important to understand what "Cross-Origin Resource Sharing" is. It is particularly important to be aware of the security implications when allowing your API to be fetched from all origins. We recommend that you take a look at the following articles before proceeding:
CORS relies on the target/endpoint to be configured to accept requests from the origin domain. If you are getting requests blocked/rejected by the target, then it is up to the target to enable your domain or request type and cannot be resolved by the requesting site.
If you are getting the 'Access to <site> has been blocked by CORS policy
' error and you do not own to the endpoint, you will need to rely on the no-cors option or reach out to the target directly to amend this for you.
Once you understand what CORS is and the potential risks of enabling it, you can do so by configuring a few headers in the response object.
const allowCors = fn => async (req, res) => { res.setHeader('Access-Control-Allow-Credentials', true) res.setHeader('Access-Control-Allow-Origin', '*') // another common pattern // res.setHeader('Access-Control-Allow-Origin', req.headers.origin); res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS,PATCH,DELETE,POST,PUT') res.setHeader( 'Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' ) if (req.method === 'OPTIONS') { res.status(200).end() return } return await fn(req, res)}
const handler = (req, res) => { const d = new Date() res.end(d.toString())}
module.exports = allowCors(handler)
The allowCors
function acts as a wrapper, enabling CORS for the Serverless Function passed to it. This is a common pattern when using middleware in Serverless Functions and can be applied to multiple scenarios.
In the next.config.js
file, a "headers" function can be created:
module.exports = { async headers() { return [ { // matching all API routes source: "/api/:path*", headers: [ { key: "Access-Control-Allow-Credentials", value: "true" }, { key: "Access-Control-Allow-Origin", value: "*" }, { key: "Access-Control-Allow-Methods", value: "GET,OPTIONS,PATCH,DELETE,POST,PUT" }, { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }, ] } ] }};
The headers()
function allows you to define paths associated with a set of headers. It can be useful to allow CORS in multiple routes.
If you are not using Next.js, you can still enable headers in multiple paths by using the Vercel configuration file.
Create a new vercel.json
with a new "headers" key:
{ "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Credentials", "value": "true" }, { "key": "Access-Control-Allow-Origin", "value": "*" }, { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" }, { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" } ] } ]}