Skip to content

Commit

Permalink
fix: Handle overlapping locale prefixes correctly pt. 2 (#1344)
Browse files Browse the repository at this point in the history
Follow-up for #1343, as the
issue was only addressed partially before.

Closes #1329
  • Loading branch information
amannn authored Sep 17, 2024
1 parent ea69a82 commit 7958659
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/next-intl/.size-limit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const config: SizeLimitConfig = [
},
{
path: 'dist/production/middleware.js',
limit: '9.595 KB'
limit: '9.61 KB'
},
{
path: 'dist/production/routing.js',
Expand Down
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 7958659

Please sign in to comment.