Skip to content

Commit

Permalink
More redirects
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn committed Jul 21, 2023
1 parent b9e05a4 commit f4dd8fa
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 45 deletions.
2 changes: 2 additions & 0 deletions examples/example-next-13/src/components/NavigationLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type Props = Omit<ComponentProps<typeof Link>, 'href'> & {

export default function NavigationLink({href, ...rest}: Props) {
const pathname = usePathname();

// TODO: We need to consult the pathnames map here
const isActive = pathname === href;

return (
Expand Down
54 changes: 17 additions & 37 deletions packages/next-intl/src/middleware/LocalizedPathnames.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,52 +24,32 @@ export function getLocalizedRedirectPathname<Locales extends AllLocales>(
configWithDefaults.locales
);

if (pathLocale) {
if (pathLocale === configWithDefaults.defaultLocale) {
return;
for (const [, routePath] of Object.entries(configWithDefaults.pathnames)) {
if (typeof routePath === 'string') {
// No redirect is necessary if all locales use the same pathname
continue;
}

for (const [, routePath] of Object.entries(configWithDefaults.pathnames)) {
if (typeof routePath === 'string') {
// No redirect is necessary if all locales use the same pathname
for (const [locale, localePathname] of Object.entries(routePath)) {
if (resolvedLocale === locale) {
continue;
}

const defaultLocaleTemplate = routePath[configWithDefaults.defaultLocale];
const pathLocalePathname = `/${pathLocale}${defaultLocaleTemplate}`;
const matches = matchesPathname(pathLocalePathname, pathname);
let template = '';
if (pathLocale) template = `/${pathLocale}`;
template += localePathname;

const matches = matchesPathname(template, pathname);
if (matches) {
const params = getRouteParams(pathLocalePathname, pathname);
return getPathWithSearch(
`/${pathLocale}` + formatPathname(routePath[pathLocale], params),
request.nextUrl.search
);
}
}
} else if (resolvedLocale !== configWithDefaults.defaultLocale) {
if (resolvedLocale === configWithDefaults.defaultLocale) {
return;
}
const params = getRouteParams(template, pathname);

// Check if the path matches a route from the default locale.
// If this is the case, then redirect to a localized version.
for (const [, routePath] of Object.entries(configWithDefaults.pathnames)) {
if (typeof routePath === 'string') {
// No redirect is necessary if all locales use the same pathname
continue;
}
let targetPathname = '';
if (resolvedLocale !== configWithDefaults.defaultLocale || pathLocale) {
targetPathname = `/${resolvedLocale}`;
}
targetPathname += formatPathname(routePath[resolvedLocale], params);

const defaultLocalePathname = routePath[configWithDefaults.defaultLocale];
const matches = matchesPathname(defaultLocalePathname, pathname);

if (matches) {
const params = getRouteParams(defaultLocalePathname, pathname);
return getPathWithSearch(
`/${resolvedLocale}` +
formatPathname(routePath[resolvedLocale], params),
request.nextUrl.search
);
return getPathWithSearch(targetPathname, request.nextUrl.search);
}
}
}
Expand Down
22 changes: 14 additions & 8 deletions packages/next-intl/test/middleware/middleware.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,13 @@ describe('prefix-based routing', () => {
);
});

it('forwards a request for a localized route that is not associated with the requested locale so that a 404 response can be returned', () => {
it('redirects a request for a localized route that is not associated with the requested locale', () => {
middlewareWithPathnames(createMockRequest('/über', 'en'));
expect(MockedNextResponse.next).not.toHaveBeenCalled();
expect(MockedNextResponse.redirect).not.toHaveBeenCalled();
expect(MockedNextResponse.rewrite).toHaveBeenCalledTimes(1);
expect(MockedNextResponse.rewrite.mock.calls[0][0].toString()).toBe(
'http://localhost:3000/en/%C3%BCber'
expect(MockedNextResponse.rewrite).not.toHaveBeenCalled();
expect(MockedNextResponse.redirect).toHaveBeenCalledTimes(1);
expect(MockedNextResponse.redirect.mock.calls[0][0].toString()).toBe(
'http://localhost:3000/about'
);
});

Expand Down Expand Up @@ -516,13 +516,19 @@ describe('prefix-based routing', () => {
);
});

it('forwards a request for a localized route that is not associated with the requested locale so that a 404 response can be returned', () => {
it('redirects a request for a localized route that is not associated with the requested locale', () => {
// Relevant to avoid duplicate content issues
middlewareWithPathnames(createMockRequest('/en/über', 'en'));
middlewareWithPathnames(createMockRequest('/en/benutzer/12', 'en'));
expect(MockedNextResponse.next).not.toHaveBeenCalled();
expect(MockedNextResponse.rewrite).not.toHaveBeenCalled();
expect(MockedNextResponse.redirect).not.toHaveBeenCalled();
expect(MockedNextResponse.next).toHaveBeenCalledTimes(2);
expect(MockedNextResponse.redirect).toHaveBeenCalledTimes(2);
expect(MockedNextResponse.redirect.mock.calls[0][0].toString()).toBe(
'http://localhost:3000/en/about'
);
expect(MockedNextResponse.redirect.mock.calls[1][0].toString()).toBe(
'http://localhost:3000/en/users/12'
);
});
});
});
Expand Down

0 comments on commit f4dd8fa

Please sign in to comment.