Skip to content

Commit

Permalink
Docs: Add CORS examples (vercel#62439)
Browse files Browse the repository at this point in the history
  • Loading branch information
delbaoliveira authored Feb 23, 2024
1 parent ae524fb commit 01c1bfa
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ Since `formData` data are all strings, you may want to use [`zod-form-data`](htt

### CORS

You can set CORS headers on a `Response` using the standard Web API methods:
You can set CORS headers for a specific Route Handler using the standard Web API methods:

```ts filename="app/api/route.ts" switcher
export const dynamic = 'force-dynamic' // defaults to auto
Expand Down Expand Up @@ -604,6 +604,11 @@ export async function GET(request) {
}
```

> **Good to know**:
>
> - To add CORS headers to multiple Route Handlers, you can use [Middleware](/docs/app/building-your-application/routing/middleware#cors) or the [`next.config.js` file](/docs/app/api-reference/next-config-js/headers#cors).
> - Alternatively, see our [CORS example](https://github.com/vercel/examples/blob/main/edge-functions/cors/lib/cors.ts) package.
### Webhooks

You can use a Route Handler to receive webhooks from third-party services:
Expand Down
100 changes: 100 additions & 0 deletions docs/02-app/01-building-your-application/01-routing/13-middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,106 @@ export function middleware(request) {

> **Good to know**: Avoid setting large headers as it might cause [431 Request Header Fields Too Large](https://developer.mozilla.org/docs/Web/HTTP/Status/431) error depending on your backend web server configuration.
### CORS

You can set CORS headers in Middleware to allow cross-origin requests, including [simple](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) and [preflighted](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) requests.

```tsx filename="middleware.ts" switcher
import { NextRequest, NextResponse } from 'next/server'

const allowedOrigins = ['https://acme.com', 'https://my-app.org']

const corsOptions = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}

export function middleware(request: NextRequest) {
// Check the origin from the request
const origin = request.headers.get('origin') ?? ''
const isAllowedOrigin = allowedOrigins.includes(origin)

// Handle preflighted requests
const isPreflight = request.method === 'OPTIONS'

if (isPreflight) {
const preflightHeaders = {
...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
...corsOptions,
}
return NextResponse.json({}, { headers: preflightHeaders })
}

// Handle simple requests
const response = NextResponse.next()

if (isAllowedOrigin) {
response.headers.set('Access-Control-Allow-Origin', origin)
}

Object.entries(corsOptions).forEach(([key, value]) => {
response.headers.set(key, value)
})

return response
}

export const config = {
matcher: '/api/:path*',
}
```

```jsx filename="middleware.js" switcher
import { NextResponse } from 'next/server'

const allowedOrigins = ['https://acme.com', 'https://my-app.org']

const corsOptions = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}

export function middleware(request) {
// Check the origin from the request
const origin = request.headers.get('origin') ?? ''
const isAllowedOrigin = allowedOrigins.includes(origin)

// Handle preflighted requests
const isPreflight = request.method === 'OPTIONS'

if (isPreflight) {
const preflightHeaders = {
...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
...corsOptions,
}
return NextResponse.json({}, { headers: preflightHeaders })
}

// Handle simple requests
const response = NextResponse.next()

if (isAllowedOrigin) {
response.headers.set('Access-Control-Allow-Origin', origin)
}

Object.entries(corsOptions).forEach(([key, value]) => {
response.headers.set(key, value)
})

return response
}

export const config = {
matcher: '/api/:path*',
}
```
<AppOnly>
> **Good to know:** You can configure CORS headers for individual routes in [Route Handlers](/docs/app/building-your-application/routing/route-handlers#cors).
</AppOnly>
## Producing a Response
You can respond from Middleware directly by returning a `Response` or `NextResponse` instance. (This is available since [Next.js v13.1.0](https://nextjs.org/blog/next-13-1#nextjs-advanced-middleware))
Expand Down
28 changes: 28 additions & 0 deletions docs/02-app/02-api-reference/05-next-config-js/headers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,34 @@ export default function handler(req, res) {

## Options

### CORS

[Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) is a security feature that allows you to control which sites can access your resources. You can set the `Access-Control-Allow-Origin` header to allow a specific origin to access your <PagesOnly>API Endpoints</PagesOnly><AppOnly>Route Handlers</AppOnly>.

```js
async headers() {
return [
{
source: "/api/:path*",
headers: [
{
key: "Access-Control-Allow-Origin",
value: "*", // Set your origin
},
{
key: "Access-Control-Allow-Methods",
value: "GET, POST, PUT, DELETE, OPTIONS",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
],
},
];
},
```

### X-DNS-Prefetch-Control

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control) controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the [DNS](https://developer.mozilla.org/docs/Glossary/DNS) is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
Expand Down

0 comments on commit 01c1bfa

Please sign in to comment.