mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
fix(i18n): fallback index when routing is prefix-always (#9032)
* fix(i18n): fallback index when routing is prefix-always * chore: add comment as per feedback
This commit is contained in:
parent
4e63467d74
commit
4e9f171ef2
4 changed files with 107 additions and 70 deletions
|
@ -161,7 +161,11 @@ export class BuildPipeline extends Pipeline {
|
||||||
for (const pageData of pageDataList) {
|
for (const pageData of pageDataList) {
|
||||||
if (routeIsRedirect(pageData.route)) {
|
if (routeIsRedirect(pageData.route)) {
|
||||||
pages.set(pageData, path);
|
pages.set(pageData, path);
|
||||||
} else if (routeIsFallback(pageData.route) && i18nHasFallback(this.getConfig())) {
|
} else if (
|
||||||
|
routeIsFallback(pageData.route) &&
|
||||||
|
(i18nHasFallback(this.getConfig()) ||
|
||||||
|
(routeIsFallback(pageData.route) && pageData.route.route === '/'))
|
||||||
|
) {
|
||||||
pages.set(pageData, path);
|
pages.set(pageData, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,13 +485,13 @@ export function createRouteManifest(
|
||||||
routes.push(routeData);
|
routes.push(routeData);
|
||||||
});
|
});
|
||||||
const i18n = settings.config.experimental.i18n;
|
const i18n = settings.config.experimental.i18n;
|
||||||
|
if (i18n) {
|
||||||
if (i18n && i18n.fallback) {
|
// In this block of code we group routes based on their locale
|
||||||
let fallback = Object.entries(i18n.fallback);
|
|
||||||
|
|
||||||
// A map like: locale => RouteData[]
|
// A map like: locale => RouteData[]
|
||||||
const routesByLocale = new Map<string, RouteData[]>();
|
const routesByLocale = new Map<string, RouteData[]>();
|
||||||
// We create a set, so we can remove the routes that have been added to the previous map
|
// This type is here only as a helper. We copy the routes and make them unique, so we don't "process" the same route twice.
|
||||||
|
// The assumption is that a route in the file system belongs to only one locale.
|
||||||
const setRoutes = new Set(routes);
|
const setRoutes = new Set(routes);
|
||||||
|
|
||||||
// First loop
|
// First loop
|
||||||
|
@ -524,70 +524,110 @@ export function createRouteManifest(
|
||||||
setRoutes.delete(route);
|
setRoutes.delete(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallback.length > 0) {
|
// Work done, now we start creating "fallback" routes based on the configuration
|
||||||
for (const [fallbackFromLocale, fallbackToLocale] of fallback) {
|
|
||||||
let fallbackToRoutes;
|
|
||||||
if (fallbackToLocale === i18n.defaultLocale) {
|
|
||||||
fallbackToRoutes = routesByLocale.get(i18n.defaultLocale);
|
|
||||||
} else {
|
|
||||||
fallbackToRoutes = routesByLocale.get(fallbackToLocale);
|
|
||||||
}
|
|
||||||
const fallbackFromRoutes = routesByLocale.get(fallbackFromLocale);
|
|
||||||
|
|
||||||
// Technically, we should always have a fallback to. Added this to make TS happy.
|
if (i18n.routingStrategy === 'prefix-always') {
|
||||||
if (!fallbackToRoutes) {
|
// we attempt to retrieve the index page of the default locale
|
||||||
continue;
|
const defaultLocaleRoutes = routesByLocale.get(i18n.defaultLocale);
|
||||||
}
|
if (defaultLocaleRoutes) {
|
||||||
|
const indexDefaultRoute = defaultLocaleRoutes.find((routeData) => {
|
||||||
|
// it should be safe to assume that an index page has "index" in their name
|
||||||
|
return routeData.component.includes('index');
|
||||||
|
});
|
||||||
|
if (indexDefaultRoute) {
|
||||||
|
// we found the index of the default locale, now we create a root index that will redirect to the index of the default locale
|
||||||
|
const pathname = '/';
|
||||||
|
const route = '/';
|
||||||
|
|
||||||
for (const fallbackToRoute of fallbackToRoutes) {
|
const segments = removeLeadingForwardSlash(route)
|
||||||
const hasRoute =
|
.split(path.posix.sep)
|
||||||
fallbackFromRoutes &&
|
.filter(Boolean)
|
||||||
// we check if the fallback from locale (the origin) has already this route
|
.map((s: string) => {
|
||||||
fallbackFromRoutes.some((route) => {
|
validateSegment(s);
|
||||||
|
return getParts(s, route);
|
||||||
|
});
|
||||||
|
routes.push({
|
||||||
|
...indexDefaultRoute,
|
||||||
|
pathname,
|
||||||
|
route,
|
||||||
|
segments,
|
||||||
|
pattern: getPattern(segments, config),
|
||||||
|
type: 'fallback',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i18n.fallback) {
|
||||||
|
let fallback = Object.entries(i18n.fallback);
|
||||||
|
|
||||||
|
if (fallback.length > 0) {
|
||||||
|
for (const [fallbackFromLocale, fallbackToLocale] of fallback) {
|
||||||
|
let fallbackToRoutes;
|
||||||
|
if (fallbackToLocale === i18n.defaultLocale) {
|
||||||
|
fallbackToRoutes = routesByLocale.get(i18n.defaultLocale);
|
||||||
|
} else {
|
||||||
|
fallbackToRoutes = routesByLocale.get(fallbackToLocale);
|
||||||
|
}
|
||||||
|
const fallbackFromRoutes = routesByLocale.get(fallbackFromLocale);
|
||||||
|
|
||||||
|
// Technically, we should always have a fallback to. Added this to make TS happy.
|
||||||
|
if (!fallbackToRoutes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const fallbackToRoute of fallbackToRoutes) {
|
||||||
|
const hasRoute =
|
||||||
|
fallbackFromRoutes &&
|
||||||
|
// we check if the fallback from locale (the origin) has already this route
|
||||||
|
fallbackFromRoutes.some((route) => {
|
||||||
|
if (fallbackToLocale === i18n.defaultLocale) {
|
||||||
|
return (
|
||||||
|
route.route.replace(`/${fallbackFromLocale}`, '') === fallbackToRoute.route
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
route.route.replace(`/${fallbackToLocale}`, `/${fallbackFromLocale}`) ===
|
||||||
|
fallbackToRoute.route
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hasRoute) {
|
||||||
|
let pathname: string | undefined;
|
||||||
|
let route: string;
|
||||||
if (fallbackToLocale === i18n.defaultLocale) {
|
if (fallbackToLocale === i18n.defaultLocale) {
|
||||||
return route.route.replace(`/${fallbackFromLocale}`, '') === fallbackToRoute.route;
|
if (fallbackToRoute.pathname) {
|
||||||
|
pathname = `/${fallbackFromLocale}${fallbackToRoute.pathname}`;
|
||||||
|
}
|
||||||
|
route = `/${fallbackFromLocale}${fallbackToRoute.route}`;
|
||||||
} else {
|
} else {
|
||||||
return (
|
pathname = fallbackToRoute.pathname?.replace(
|
||||||
route.route.replace(`/${fallbackToLocale}`, `/${fallbackFromLocale}`) ===
|
`/${fallbackToLocale}`,
|
||||||
fallbackToRoute.route
|
`/${fallbackFromLocale}`
|
||||||
|
);
|
||||||
|
route = fallbackToRoute.route.replace(
|
||||||
|
`/${fallbackToLocale}`,
|
||||||
|
`/${fallbackFromLocale}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (!hasRoute) {
|
const segments = removeLeadingForwardSlash(route)
|
||||||
let pathname: string | undefined;
|
.split(path.posix.sep)
|
||||||
let route: string;
|
.filter(Boolean)
|
||||||
if (fallbackToLocale === i18n.defaultLocale) {
|
.map((s: string) => {
|
||||||
if (fallbackToRoute.pathname) {
|
validateSegment(s);
|
||||||
pathname = `/${fallbackFromLocale}${fallbackToRoute.pathname}`;
|
return getParts(s, route);
|
||||||
}
|
});
|
||||||
route = `/${fallbackFromLocale}${fallbackToRoute.route}`;
|
routes.push({
|
||||||
} else {
|
...fallbackToRoute,
|
||||||
pathname = fallbackToRoute.pathname?.replace(
|
pathname,
|
||||||
`/${fallbackToLocale}`,
|
route,
|
||||||
`/${fallbackFromLocale}`
|
segments,
|
||||||
);
|
pattern: getPattern(segments, config),
|
||||||
route = fallbackToRoute.route.replace(
|
type: 'fallback',
|
||||||
`/${fallbackToLocale}`,
|
|
||||||
`/${fallbackFromLocale}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const segments = removeLeadingForwardSlash(route)
|
|
||||||
.split(path.posix.sep)
|
|
||||||
.filter(Boolean)
|
|
||||||
.map((s: string) => {
|
|
||||||
validateSegment(s);
|
|
||||||
return getParts(s, route);
|
|
||||||
});
|
});
|
||||||
routes.push({
|
}
|
||||||
...fallbackToRoute,
|
|
||||||
pathname,
|
|
||||||
route,
|
|
||||||
segments,
|
|
||||||
pattern: getPattern(segments, config),
|
|
||||||
type: 'fallback',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,8 @@ export async function handleRoute({
|
||||||
.some((segment) => {
|
.some((segment) => {
|
||||||
return locales.includes(segment);
|
return locales.includes(segment);
|
||||||
});
|
});
|
||||||
if (!pathNameHasLocale) {
|
// Even when we have `config.base`, the pathname is still `/` because it gets stripped before
|
||||||
|
if (!pathNameHasLocale && pathname !== '/') {
|
||||||
return handle404Response(origin, incomingRequest, incomingResponse);
|
return handle404Response(origin, incomingRequest, incomingResponse);
|
||||||
}
|
}
|
||||||
request = createRequest({
|
request = createRequest({
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Astro</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Hello
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in a new issue