diff --git a/cypress/e2e/middleware/standard.cy.ts b/cypress/e2e/middleware/standard.cy.ts index 780f9f0c85..4992e0186c 100644 --- a/cypress/e2e/middleware/standard.cy.ts +++ b/cypress/e2e/middleware/standard.cy.ts @@ -45,6 +45,12 @@ describe('Standard middleware', () => { expect(response.headers).to.have.property('x-foo', 'bar') }) }) + + it('preserves locale on rewrites (skipMiddlewareUrlNormalize: true)', () => { + cy.visit('/de-de/locale-preserving-rewrite') + cy.get('div').should('contain', 'Locale: de-DE') + cy.url().should('eq', `${Cypress.config().baseUrl}/de-de/locale-preserving-rewrite`) + }) }) describe('Middleware matchers', () => { diff --git a/demos/middleware/middleware.ts b/demos/middleware/middleware.ts index d93e5fa9b6..9206540da1 100644 --- a/demos/middleware/middleware.ts +++ b/demos/middleware/middleware.ts @@ -21,7 +21,9 @@ export async function middleware(req: NextRequest) { } const request = new MiddlewareRequest(req) - if (pathname.startsWith('/static')) { + + // skipMiddlewareUrlNormalize next config option is used so we have to try to match both html path and data blob path + if (pathname.startsWith('/static') || pathname.endsWith('/static.json')) { // Unlike NextResponse.next(), this actually sends the request to the origin const res = await request.next() const message = `This was static (& escaping test &) but has been transformed in ${req.geo?.city}` @@ -36,7 +38,8 @@ export async function middleware(req: NextRequest) { return res } - if (pathname.startsWith('/request-rewrite')) { + // skipMiddlewareUrlNormalize next config option is used so we have to try to match both html path and data blob path + if (pathname.startsWith('/request-rewrite') || pathname.endsWith('/request-rewrite.json')) { // request.rewrite() should return the MiddlewareResponse object instead of the Response object. const res = await request.rewrite('/static-rewrite') const message = `This was static (& escaping test &) but has been transformed in ${req.geo?.city}` @@ -100,6 +103,10 @@ export async function middleware(req: NextRequest) { return response } + if (pathname.includes('locale-preserving-rewrite')) { + return NextResponse.rewrite(new URL('/locale-test', req.url)) + } + if (pathname.startsWith('/shows')) { if (pathname.startsWith('/shows/222')) { response = NextResponse.next() @@ -151,6 +158,7 @@ export const config = { matcher: [ '/api/:all*', '/headers', + '/:all*/locale-preserving-rewrite', '/cookies/:path*', { source: '/static' }, {source: '/request-rewrite' }, diff --git a/demos/middleware/next.config.js b/demos/middleware/next.config.js index 9ce274ced3..ee7bb8a36e 100644 --- a/demos/middleware/next.config.js +++ b/demos/middleware/next.config.js @@ -11,6 +11,7 @@ const nextConfig = { defaultLocale: 'en', locales: ['en', 'de-DE'], }, + skipMiddlewareUrlNormalize: true, } module.exports = nextConfig diff --git a/demos/middleware/pages/locale-test.js b/demos/middleware/pages/locale-test.js new file mode 100644 index 0000000000..67d8592b1c --- /dev/null +++ b/demos/middleware/pages/locale-test.js @@ -0,0 +1,15 @@ +import * as React from 'react' + +const Page = ({ pageLocale }) => { + return