Skip to content

Commit

Permalink
fix: Handle overlapping locale prefixes correctly pt. 2
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn committed Sep 17, 2024
1 parent 72c1731 commit b34a632
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export default function getAlternateLinksHeaderValue<

const links = getLocalePrefixes(
routing.locales as AppLocales,
routing.localePrefix
routing.localePrefix,
false
).flatMap(([locale, prefix]) => {
function prefixPathname(pathname: string) {
if (pathname === '/') {
Expand Down
17 changes: 17 additions & 0 deletions packages/next-intl/src/middleware/middleware.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,23 @@ describe('prefix-based routing', () => {
);
});

it('handles overlapping custom prefixes correctly', () => {
createMiddleware({
locales: ['en-US', 'es-US'],
defaultLocale: 'en-US',
localePrefix: {
mode: 'always',
prefixes: {
'es-US': '/us/es',
'en-US': '/us'
}
}
})(createMockRequest('/us/es'));
expect(MockedNextResponse.rewrite.mock.calls[0][0].toString()).toBe(
'http://localhost:3000/es-US'
);
});

it('serves requests for a prefixed locale at the root', () => {
middlewareWithPrefixes(createMockRequest('/uk?test'));
expect(MockedNextResponse.redirect).not.toHaveBeenCalled();
Expand Down
15 changes: 10 additions & 5 deletions packages/next-intl/src/middleware/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,20 @@ export function findCaseInsensitiveString(

export function getLocalePrefixes<AppLocales extends Locales>(
locales: AppLocales,
localePrefix: LocalePrefixConfigVerbose<AppLocales>
localePrefix: LocalePrefixConfigVerbose<AppLocales>,
sort = true
): Array<[AppLocales[number], string]> {
return locales.map((locale) => [
const prefixes = locales.map((locale) => [
locale as AppLocales[number],
getLocalePrefix(locale, localePrefix)
]);

if (sort) {
// More specific ones first
prefixes.sort((a, b) => b[1].length - a[1].length);
}

return prefixes as Array<[AppLocales[number], string]>;
}

export function getPathnameMatch<AppLocales extends Locales>(
Expand All @@ -151,9 +159,6 @@ export function getPathnameMatch<AppLocales extends Locales>(
| undefined {
const localePrefixes = getLocalePrefixes(locales, localePrefix);

// More specific ones first
localePrefixes.sort((a, b) => b[1].length - a[1].length);

for (const [locale, prefix] of localePrefixes) {
let exact, matches;
if (pathname === prefix || pathname.startsWith(prefix + '/')) {
Expand Down

0 comments on commit b34a632

Please sign in to comment.