Skip to content

Commit 74e2502

Browse files
committed
fix: pass NextConfig in NextRequest (needed even though it's not in the Next types)
1 parent b010192 commit 74e2502

File tree

3 files changed

+49
-67
lines changed

3 files changed

+49
-67
lines changed

edge-runtime/lib/next-request.ts

+21-44
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,12 @@ import {
1010
} from './util.ts'
1111

1212
import type { NextConfig } from 'next/dist/server/config-shared'
13-
import type { NextRequest } from 'next/server'
14-
15-
export type NetlifyNextRequest = Pick<
16-
NextRequest,
17-
'url' | 'headers' | 'geo' | 'ip' | 'method' | 'body'
18-
>
19-
20-
export type NetlifyNextContext = {
21-
localizedUrl: string
22-
detectedLocale?: string
23-
i18n?: NextConfig['i18n']
24-
basePath?: NextConfig['basePath']
25-
trailingSlash?: NextConfig['trailingSlash']
26-
}
13+
import type { NextRequest, RequestInit } from 'next/dist/server/web/spec-extension/request.js'
2714

28-
const normalizeRequestURL = (originalURL: string, nextConfig?: NextConfig): string => {
29-
const url = new URL(originalURL)
15+
export type NetlifyNextRequest = RequestInit &
16+
Pick<NextRequest, 'url' | 'headers' | 'geo' | 'ip' | 'method' | 'body'>
3017

18+
const normalizeRequest = (url: URL, nextConfig?: NextConfig): URL => {
3119
url.pathname = removeBasePath(url.pathname, nextConfig?.basePath)
3220

3321
// We want to run middleware for data requests and expose the URL of the
@@ -41,15 +29,13 @@ const normalizeRequestURL = (originalURL: string, nextConfig?: NextConfig): stri
4129

4230
url.pathname = addBasePath(url.pathname, nextConfig?.basePath)
4331

44-
return url.toString()
32+
return url
4533
}
4634

47-
const localizeRequestURL = (
48-
originalURL: string,
35+
export const localizeRequest = (
36+
url: URL,
4937
nextConfig?: NextConfig,
50-
): { localizedUrl: string; detectedLocale?: string } => {
51-
const url = new URL(originalURL)
52-
38+
): { localizedUrl: URL; locale?: string } => {
5339
url.pathname = removeBasePath(url.pathname, nextConfig?.basePath)
5440

5541
// Detect the locale from the URL
@@ -61,28 +47,27 @@ const localizeRequestURL = (
6147
url.pathname = addBasePath(url.pathname, nextConfig?.basePath)
6248

6349
return {
64-
localizedUrl: url.toString(),
65-
detectedLocale,
50+
localizedUrl: url,
51+
locale: detectedLocale,
6652
}
6753
}
6854

6955
export const buildNextRequest = (
7056
request: Request,
7157
context: Context,
7258
nextConfig?: NextConfig,
73-
): { nextRequest: NetlifyNextRequest; nextContext: NetlifyNextContext } => {
74-
const { url, method, body, headers } = request
59+
): NetlifyNextRequest => {
60+
const { method, body, headers } = request
7561
const { country, subdivision, city, latitude, longitude } = context.geo
7662
const { i18n, basePath, trailingSlash } = nextConfig ?? {}
7763

64+
const url = new URL(request.url)
7865
const normalizedUrl = nextConfig?.skipMiddlewareUrlNormalize
7966
? url
80-
: normalizeRequestURL(url, nextConfig)
81-
82-
const { localizedUrl, detectedLocale } = localizeRequestURL(normalizedUrl, nextConfig)
67+
: normalizeRequest(url, nextConfig)
8368

84-
const nextRequest: NetlifyNextRequest = {
85-
url: normalizedUrl,
69+
return {
70+
url: normalizedUrl.toString(),
8671
headers,
8772
geo: {
8873
city,
@@ -94,18 +79,10 @@ export const buildNextRequest = (
9479
ip: context.ip,
9580
method,
9681
body,
97-
}
98-
99-
const nextContext = {
100-
localizedUrl,
101-
detectedLocale,
102-
i18n,
103-
trailingSlash,
104-
basePath,
105-
}
106-
107-
return {
108-
nextRequest,
109-
nextContext,
82+
nextConfig: {
83+
i18n,
84+
basePath,
85+
trailingSlash,
86+
},
11087
}
11188
}

edge-runtime/lib/response.ts

+21-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { HTMLRewriter } from '../vendor/deno.land/x/[email protected]/
44
import { updateModifiedHeaders } from './headers.ts'
55
import type { StructuredLogger } from './logging.ts'
66
import { addMiddlewareHeaders, isMiddlewareRequest, isMiddlewareResponse } from './middleware.ts'
7-
import { NetlifyNextContext } from './next-request.ts'
7+
import { NetlifyNextRequest } from './next-request.ts'
88
import {
99
addBasePath,
1010
normalizeDataUrl,
@@ -20,15 +20,17 @@ export interface FetchEventResult {
2020

2121
interface BuildResponseOptions {
2222
context: Context
23-
nextContext?: NetlifyNextContext
23+
config?: NetlifyNextRequest['nextConfig']
24+
locale?: string
2425
request: Request
2526
result: FetchEventResult
2627
logger: StructuredLogger
2728
}
2829

2930
export const buildResponse = async ({
3031
context,
31-
nextContext,
32+
config,
33+
locale,
3234
request,
3335
result,
3436
logger,
@@ -183,9 +185,9 @@ export const buildResponse = async ({
183185
}
184186

185187
// respect trailing slash rules to prevent 308s
186-
rewriteUrl.pathname = normalizeTrailingSlash(rewriteUrl.pathname, nextContext?.trailingSlash)
188+
rewriteUrl.pathname = normalizeTrailingSlash(rewriteUrl.pathname, config?.trailingSlash)
187189

188-
const target = normalizeLocalizedTarget({ target: rewriteUrl.toString(), request, nextContext })
190+
const target = normalizeLocalizedTarget({ target: rewriteUrl.toString(), request, config })
189191
if (target === request.url) {
190192
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
191193
return
@@ -196,8 +198,8 @@ export const buildResponse = async ({
196198
}
197199

198200
// If we are redirecting a request that had a locale in the URL, we need to add it back in
199-
if (redirect && nextContext?.detectedLocale) {
200-
redirect = normalizeLocalizedTarget({ target: redirect, request, nextContext })
201+
if (redirect && locale) {
202+
redirect = normalizeLocalizedTarget({ target: redirect, request, config })
201203
if (redirect === request.url) {
202204
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
203205
return
@@ -231,26 +233,27 @@ export const buildResponse = async ({
231233
function normalizeLocalizedTarget({
232234
target,
233235
request,
234-
nextContext,
236+
config,
237+
locale,
235238
}: {
236239
target: string
237240
request: Request
238-
nextContext?: NetlifyNextContext
241+
config?: NetlifyNextRequest['nextConfig']
242+
locale?: string
239243
}) {
240244
const targetUrl = new URL(target, request.url)
245+
const normalizedTarget = normalizeLocalePath(targetUrl.pathname, config?.i18n?.locales)
246+
const targetPathname = normalizedTarget.pathname
247+
const targetLocale = normalizedTarget.detectedLocale ?? locale
241248

242-
const normalizedTarget = normalizeLocalePath(targetUrl.pathname, nextContext?.i18n?.locales)
243-
244-
const locale = normalizedTarget.detectedLocale ?? nextContext?.detectedLocale
245249
if (
246-
locale &&
247-
!normalizedTarget.pathname.startsWith(`/api/`) &&
248-
!normalizedTarget.pathname.startsWith(`/_next/static/`)
250+
targetLocale &&
251+
!targetPathname.startsWith(`/api/`) &&
252+
!targetPathname.startsWith(`/_next/static/`)
249253
) {
250-
targetUrl.pathname =
251-
addBasePath(`/${locale}${normalizedTarget.pathname}`, nextContext?.basePath) || `/`
254+
targetUrl.pathname = addBasePath(`/${targetLocale}${targetPathname}`, config?.basePath) || `/`
252255
} else {
253-
targetUrl.pathname = addBasePath(normalizedTarget.pathname, nextContext?.basePath) || `/`
256+
targetUrl.pathname = addBasePath(targetPathname, config?.basePath) || `/`
254257
}
255258
return targetUrl.toString()
256259
}

edge-runtime/middleware.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import nextConfig from './next.config.json' with { type: 'json' }
55

66
import { InternalHeaders } from './lib/headers.ts'
77
import { logger, LogLevel } from './lib/logging.ts'
8-
import { buildNextRequest, NetlifyNextRequest } from './lib/next-request.ts'
8+
import { buildNextRequest, localizeRequest, NetlifyNextRequest } from './lib/next-request.ts'
99
import { buildResponse, FetchEventResult } from './lib/response.ts'
1010
import {
1111
getMiddlewareRouteMatcher,
@@ -39,14 +39,15 @@ export async function handleMiddleware(
3939
.withFields({ url_path: url.pathname })
4040
.withRequestID(request.headers.get(InternalHeaders.NFRequestID))
4141

42-
const { nextRequest, nextContext } = buildNextRequest(request, context, nextConfig)
43-
const { pathname: localizedPath } = new URL(nextContext.localizedUrl)
42+
const nextRequest = buildNextRequest(request, context, nextConfig)
43+
const { localizedUrl, locale } = localizeRequest(url, nextConfig)
44+
const query = searchParamsToUrlQuery(url.searchParams)
4445

4546
// While we have already checked the path when mapping to the edge function,
4647
// Next.js supports extra rules that we need to check here too, because we
4748
// might be running an edge function for a path we should not. If we find
4849
// that's the case, short-circuit the execution.
49-
if (!matchesMiddleware(localizedPath, request, searchParamsToUrlQuery(url.searchParams))) {
50+
if (!matchesMiddleware(localizedUrl.pathname, request, query)) {
5051
reqLogger.debug('Aborting middleware due to runtime rules')
5152
return
5253
}
@@ -55,7 +56,8 @@ export async function handleMiddleware(
5556
const result = await nextHandler({ request: nextRequest })
5657
const response = await buildResponse({
5758
context,
58-
nextContext,
59+
config: nextRequest.nextConfig,
60+
locale,
5961
request,
6062
result,
6163
logger: reqLogger,

0 commit comments

Comments
 (0)