diff --git a/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts b/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts index 5295e3aba2841..f0bd3b750f938 100644 --- a/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts +++ b/packages/next/src/shared/lib/router/utils/get-next-pathname-info.ts @@ -64,9 +64,9 @@ export function getNextPathnameInfo( info.pathname = removePathPrefix(info.pathname, basePath) info.basePath = basePath } + let pathnameNoDataPrefix = info.pathname if ( - options.parseData === true && info.pathname.startsWith('/_next/data/') && info.pathname.endsWith('.json') ) { @@ -76,21 +76,36 @@ export function getNextPathnameInfo( .split('/') const buildId = paths[0] - info.pathname = paths[1] !== 'index' ? `/${paths.slice(1).join('/')}` : '/' info.buildId = buildId + pathnameNoDataPrefix = + paths[1] !== 'index' ? `/${paths.slice(1).join('/')}` : '/' + + // update pathname with normalized if enabled although + // we use normalized to populate locale info still + if (options.parseData === true) { + info.pathname = pathnameNoDataPrefix + } } // If provided, use the locale route normalizer to detect the locale instead // of the function below. - if (options.i18nProvider) { - const result = options.i18nProvider.analyze(info.pathname) + if (i18n) { + let result = options.i18nProvider + ? options.i18nProvider.analyze(info.pathname) + : normalizeLocalePath(info.pathname, i18n.locales) + info.locale = result.detectedLocale info.pathname = result.pathname ?? info.pathname - } else if (i18n) { - const pathLocale = normalizeLocalePath(info.pathname, i18n.locales) - info.locale = pathLocale.detectedLocale - info.pathname = pathLocale.pathname ?? info.pathname - } + if (!result.detectedLocale && info.buildId) { + result = options.i18nProvider + ? options.i18nProvider.analyze(pathnameNoDataPrefix) + : normalizeLocalePath(pathnameNoDataPrefix, i18n.locales) + + if (result.detectedLocale) { + info.locale = result.detectedLocale + } + } + } return info } diff --git a/test/e2e/skip-trailing-slash-redirect/app/middleware.js b/test/e2e/skip-trailing-slash-redirect/app/middleware.js index 672e385aeaaed..cc9f0a9e22ee4 100644 --- a/test/e2e/skip-trailing-slash-redirect/app/middleware.js +++ b/test/e2e/skip-trailing-slash-redirect/app/middleware.js @@ -18,6 +18,13 @@ export default function handler(req) { console.log(req.nextUrl) let { pathname } = req.nextUrl + if (pathname.startsWith('/_next/data') && pathname.includes('locale-test')) { + return NextResponse.json({ + locale: req.nextUrl.locale, + pathname: req.nextUrl.pathname, + }) + } + if (pathname.includes('docs') || pathname.includes('chained-rewrite')) { if (pathname.startsWith('/en')) { pathname = pathname.replace(/^\/en/, '') || '/' diff --git a/test/e2e/skip-trailing-slash-redirect/index.test.ts b/test/e2e/skip-trailing-slash-redirect/index.test.ts index 76877d34ff696..a1fd62379b6a3 100644 --- a/test/e2e/skip-trailing-slash-redirect/index.test.ts +++ b/test/e2e/skip-trailing-slash-redirect/index.test.ts @@ -16,6 +16,16 @@ describe('skip-trailing-slash-redirect', () => { }) afterAll(() => next.destroy()) + it('should parse locale info for data request correctly', async () => { + const pathname = `/_next/data/${next.buildId}/ja-jp/locale-test.json` + const res = await next.fetch(pathname) + + expect(await res.json()).toEqual({ + locale: 'ja-jp', + pathname, + }) + }) + it.each(['EN', 'JA-JP'])( 'should be able to redirect locale casing $1', async (locale) => {