From 4796660fd8df58fb5fc4c033abca9a113a7df9d4 Mon Sep 17 00:00:00 2001 From: Mike Jarosch Date: Mon, 5 Oct 2026 19:17:42 -0500 Subject: [PATCH] Add pathname helper to proxy base. --- packages/nextjs/src/proxy/locale-proxy.ts | 3 +- packages/nextjs/src/proxy/multisite-proxy.ts | 4 +- packages/nextjs/src/proxy/proxy.test.ts | 49 ++++++++++++++++++-- packages/nextjs/src/proxy/proxy.ts | 12 +++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/packages/nextjs/src/proxy/locale-proxy.ts b/packages/nextjs/src/proxy/locale-proxy.ts index 2288472881..dce58ed939 100644 --- a/packages/nextjs/src/proxy/locale-proxy.ts +++ b/packages/nextjs/src/proxy/locale-proxy.ts @@ -54,8 +54,7 @@ export class LocaleProxy extends ProxyBase { proxiesContext?: ProxiesContext ): Promise => { try { - const { pathname } = req.nextUrl; - + const pathname = this.getPathname(req, res); const localeFromPath = this.getLocaleFromPath(pathname); const locale = localeFromPath || this.getLanguage(req, res); diff --git a/packages/nextjs/src/proxy/multisite-proxy.ts b/packages/nextjs/src/proxy/multisite-proxy.ts index 55e5facf3e..d5aa25e497 100644 --- a/packages/nextjs/src/proxy/multisite-proxy.ts +++ b/packages/nextjs/src/proxy/multisite-proxy.ts @@ -2,7 +2,7 @@ import { NextResponse, NextRequest } from 'next/server'; import { getSiteRewrite, SITE_KEY } from '@sitecore-content-sdk/content/site'; -import { ProxyBase, ProxyBaseConfig, REWRITE_HEADER_NAME } from './proxy'; +import { ProxyBase, ProxyBaseConfig } from './proxy'; import { SitecoreConfig } from '../config'; import { PREVIEW_KEY } from '@sitecore-content-sdk/content/editing'; @@ -67,7 +67,7 @@ export class MultisiteProxy extends ProxyBase { ): Promise => { try { // Path can be rewritten by previously executed proxy - const pathname = res?.headers.get(REWRITE_HEADER_NAME) || req.nextUrl.pathname; + const pathname = this.getPathname(req, res); const language = this.getLanguage(req, res); const hostname = this.getHostHeader(req) || this.defaultHostname; const startTimestamp = Date.now(); diff --git a/packages/nextjs/src/proxy/proxy.test.ts b/packages/nextjs/src/proxy/proxy.test.ts index 847ecc6410..943dfaa912 100644 --- a/packages/nextjs/src/proxy/proxy.test.ts +++ b/packages/nextjs/src/proxy/proxy.test.ts @@ -390,6 +390,47 @@ describe('ProxyBase', () => { }); }); + describe('getPathname', () => { + it('should return pathname from nextUrl', () => { + const proxy = new SampleProxy({ sites: [] }); + const req = createReq({ + nextUrl: { + pathname: '/test/path', + }, + }); + + expect(proxy['getPathname'](req)).to.equal('/test/path'); + }); + + it('should return rewrite header when present', () => { + const proxy = new SampleProxy({ sites: [] }); + const req = createReq(); + const res = createRes({ + headers: { + [REWRITE_HEADER_NAME]: '/rewritten/path', + }, + }); + + expect(proxy['getPathname'](req, res)).to.equal('/rewritten/path'); + }); + + it('should prefer rewrite header over nextUrl pathname', () => { + const proxy = new SampleProxy({ sites: [] }); + const req = createReq({ + nextUrl: { + pathname: '/test/path', + }, + }); + const res = createRes({ + headers: { + [REWRITE_HEADER_NAME]: '/rewritten/path', + }, + }); + + expect(proxy['getPathname'](req, res)).to.equal('/rewritten/path'); + }); + }); + describe('getLanguage', () => { it('should return defined language', () => { const proxy = new SampleProxy({ sites: [] }); @@ -845,11 +886,9 @@ describe('defineProxy', () => { }, } as unknown as NextRequest; - const result = await defineProxy( - redirectsProxy, - personalizeProxy, - languageRedirectProxy - ).exec(req); + const result = await defineProxy(redirectsProxy, personalizeProxy, languageRedirectProxy).exec( + req + ); expect(redirectsProxy.handle).to.have.been.calledOnce; expect(personalizeProxy.handle).to.not.have.been.called; diff --git a/packages/nextjs/src/proxy/proxy.ts b/packages/nextjs/src/proxy/proxy.ts index 42230bed67..0bdea95bb9 100644 --- a/packages/nextjs/src/proxy/proxy.ts +++ b/packages/nextjs/src/proxy/proxy.ts @@ -198,6 +198,18 @@ export abstract class ProxyBase extends ProxyHandler { ); } + /** + * Get requested pathname. + * - If response is passed and REWRITE_HEADER_NAME header is set, use it as the pathname + * - If response isn't passed or REWRITE_HEADER_NAME header is not set, use the pathname from the request URL + * @param {NextRequest} req request + * @param {NextResponse} [res] response (optional) + * @returns {string} requested pathname + */ + protected getPathname(req: NextRequest, res?: NextResponse): string { + return res?.headers.get(REWRITE_HEADER_NAME) ?? req.nextUrl.pathname; + } + /** * Get site information. If site name is stored in cookie, use it, otherwise resolve by hostname * - If site can't be resolved by site name cookie use default site info based on provided parameters