diff --git a/docs/01-app/04-api-reference/05-config/01-next-config-js/allowedDevOrigins.mdx b/docs/01-app/04-api-reference/05-config/01-next-config-js/allowedDevOrigins.mdx
new file mode 100644
index 0000000000000..01d9dd71d4dc9
--- /dev/null
+++ b/docs/01-app/04-api-reference/05-config/01-next-config-js/allowedDevOrigins.mdx
@@ -0,0 +1,18 @@
+---
+title: allowedDevOrigins
+description: Use `allowedDevOrigins` to configure additional origins that can request the dev server.
+---
+
+{/* The content of this doc is shared between the app and pages router. You can use the `Content` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+
+To configure a Next.js application to allow requests from origins other than the hostname the server was initialized with (`localhost` by default) you can use the `allowedDevOrigins` config option.
+
+`allowedDevOrigins` allows you to set additional origins that can be used in development mode. For example, to use `local-origin.dev` instead of only `localhost`, open `next.config.js` and add the `allowedDevOrigins` config:
+
+```js filename="next.config.js"
+module.exports = {
+ allowedDevOrigins: ['local-origin.dev'],
+}
+```
+
+Cross-origin requests are blocked by default to prevent unauthorized requesting of internal assets/endpoints which are available in development mode. This behavior is similar to other dev servers like `webpack-dev-middleware` to ensure the same protection.
diff --git a/docs/02-pages/03-api-reference/04-config/01-next-config-js/allowedDevOrigins.mdx b/docs/02-pages/03-api-reference/04-config/01-next-config-js/allowedDevOrigins.mdx
new file mode 100644
index 0000000000000..065a34a7f16b3
--- /dev/null
+++ b/docs/02-pages/03-api-reference/04-config/01-next-config-js/allowedDevOrigins.mdx
@@ -0,0 +1,7 @@
+---
+title: allowedDevOrigins
+description: Use `allowedDevOrigins` to configure additional origins that can request the dev server.
+source: app/api-reference/config/next-config-js/allowedDevOrigins
+---
+
+{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `Content` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts
index 4f7eb222568e1..1c7a519c49d06 100644
--- a/packages/next/src/server/config-schema.ts
+++ b/packages/next/src/server/config-schema.ts
@@ -128,6 +128,7 @@ const zTurboRuleConfigItemOrShortcut: zod.ZodType
export const configSchema: zod.ZodType = z.lazy(() =>
z.strictObject({
+ allowedDevOrigins: z.array(z.string()).optional(),
amp: z
.object({
canonicalBase: z.string().optional(),
@@ -262,7 +263,6 @@ export const configSchema: zod.ZodType = z.lazy(() =>
experimental: z
.strictObject({
generateOnlyEnv: z.boolean().optional(),
- allowedDevOrigins: z.array(z.string()).optional(),
nodeMiddleware: z.boolean().optional(),
after: z.boolean().optional(),
appDocumentPreloading: z.boolean().optional(),
diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts
index b8d5c533168b2..1528e9825223b 100644
--- a/packages/next/src/server/config-shared.ts
+++ b/packages/next/src/server/config-shared.ts
@@ -258,7 +258,6 @@ export interface LoggingConfig {
export interface ExperimentalConfig {
generateOnlyEnv?: boolean
- allowedDevOrigins?: string[]
nodeMiddleware?: boolean
cacheHandlers?: {
default?: string
@@ -674,6 +673,8 @@ export type ExportPathMap = {
* Read more: [Next.js Docs: `next.config.js`](https://nextjs.org/docs/app/api-reference/config/next-config-js)
*/
export interface NextConfig extends Record {
+ allowedDevOrigins?: string[]
+
exportPathMap?: (
defaultMap: ExportPathMap,
ctx: {
@@ -1135,9 +1136,9 @@ export const defaultConfig: NextConfig = {
output: !!process.env.NEXT_PRIVATE_STANDALONE ? 'standalone' : undefined,
modularizeImports: undefined,
outputFileTracingRoot: process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT || '',
+ allowedDevOrigins: [],
experimental: {
generateOnlyEnv: false,
- allowedDevOrigins: [],
nodeMiddleware: false,
cacheLife: {
default: {
diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts
index 4566051db8ca2..fd574f33c86fd 100644
--- a/packages/next/src/server/lib/router-server.ts
+++ b/packages/next/src/server/lib/router-server.ts
@@ -166,10 +166,7 @@ export async function initialize(opts: {
renderServer.instance =
require('./render-server') as typeof import('./render-server')
- const allowedOrigins = [
- 'localhost',
- ...(config.experimental.allowedDevOrigins || []),
- ]
+ const allowedOrigins = ['localhost', ...(config.allowedDevOrigins || [])]
if (opts.hostname) {
allowedOrigins.push(opts.hostname)
}
diff --git a/packages/next/src/server/lib/router-utils/block-cross-site.ts b/packages/next/src/server/lib/router-utils/block-cross-site.ts
index 718afacd3c46d..2431532c1c2ff 100644
--- a/packages/next/src/server/lib/router-utils/block-cross-site.ts
+++ b/packages/next/src/server/lib/router-utils/block-cross-site.ts
@@ -2,6 +2,7 @@ import type { Duplex } from 'stream'
import type { IncomingMessage, ServerResponse } from 'webpack-dev-server'
import { parseUrl } from '../../../lib/url'
import net from 'net'
+import { warnOnce } from '../../../build/output/log'
export const blockCrossSite = (
req: IncomingMessage,
@@ -23,6 +24,9 @@ export const blockCrossSite = (
res.statusCode = 403
}
res.end('Unauthorized')
+ warnOnce(
+ `Blocked cross-origin request to /_next/*. To allow this, configure "allowedDevOrigins" in next.config\nRead more: https://nextjs.org/docs/app/api-reference/config/next-config-js/allowedDevOrigins`
+ )
return true
}
@@ -50,6 +54,9 @@ export const blockCrossSite = (
res.statusCode = 403
}
res.end('Unauthorized')
+ warnOnce(
+ `Blocked cross-origin request from ${originLowerCase}. To allow this, configure "allowedDevOrigins" in next.config\nRead more: https://nextjs.org/docs/app/api-reference/config/next-config-js/allowedDevOrigins`
+ )
return true
}
}