未验证 提交 e1737809 编写于 作者: J JJ Kasper 提交者: GitHub

Update fallback locale for locale: false (#19322)

This updates the fallback locale for `locale: false` to be the `defaultLocale` instead of the currently active `locale` as it allows passing through URLs more seamlessly as a URL without the locale prefixed can be treated as the `defaultLocale` instead of having to worry if the locale matches the currently active locale. This also ensures `locale={false}` is tested in the i18n-support-catchall suite

Closes: https://github.com/vercel/next.js/issues/19048
上级 c1702c23
......@@ -616,7 +616,10 @@ export default class Router implements BaseRouter {
let localeChange = options.locale !== this.locale
if (process.env.__NEXT_I18N_SUPPORT) {
this.locale = options.locale || this.locale
this.locale =
options.locale === false
? this.defaultLocale
: options.locale || this.locale
if (typeof options.locale === 'undefined') {
options.locale = this.locale
......@@ -627,12 +630,10 @@ export default class Router implements BaseRouter {
} = require('../i18n/normalize-locale-path') as typeof import('../i18n/normalize-locale-path')
const parsedAs = parseRelativeUrl(hasBasePath(as) ? delBasePath(as) : as)
const localePathResult = normalizeLocalePath(
parsedAs.pathname,
this.locales
)
if (localePathResult.detectedLocale) {
this.locale = localePathResult.detectedLocale
url = addBasePath(localePathResult.pathname)
......@@ -1235,7 +1236,7 @@ export default class Router implements BaseRouter {
this.locales
)
parsedAs.pathname = localePathResult.pathname
options.locale = localePathResult.detectedLocale || options.locale
options.locale = localePathResult.detectedLocale || this.defaultLocale
asPath = formatWithValidation(parsedAs)
}
}
......
......@@ -42,6 +42,14 @@ export default function Page(props) {
<a id="to-gssp-slug">to /gssp/first</a>
</Link>
<br />
<Link href={`/gssp/first`} locale={false}>
<a id="to-gssp-slug-default">to /gssp/first (default locale)</a>
</Link>
<br />
<Link href={`/gsp`} locale={false}>
<a id="to-gsp-default">to /gsp (default locale)</a>
</Link>
<br />
</>
)
}
......
......@@ -35,12 +35,12 @@ export default function Page(props) {
</Link>
<br />
<Link href="/" locale="fr">
<Link href="/fr" locale={false}>
<a id="to-fr-locale-index">to /fr</a>
</Link>
<br />
<Link href="/another" locale="fr">
<Link href="/fr/another" locale={false}>
<a id="to-fr-locale-another">to /fr/another</a>
</Link>
<br />
......
......@@ -42,6 +42,14 @@ export default function Page(props) {
<a id="to-gssp-slug">to /gssp/first</a>
</Link>
<br />
<Link href={`/gssp/first`} locale={false}>
<a id="to-gssp-slug-default">to /gssp/first (default locale)</a>
</Link>
<br />
<Link href={`/gsp`} locale={false}>
<a id="to-gsp-default">to /gsp (default locale)</a>
</Link>
<br />
</>
)
}
......
......@@ -27,56 +27,42 @@ async function addDefaultLocaleCookie(browser) {
}
export function runTests(ctx) {
it('should trigger full navigation for unsupported locale', async () => {
const browser = await webdriver(ctx.appPort, '/')
it('should use default locale when no locale is in href with locale false', async () => {
const browser = await webdriver(
ctx.appPort,
`${ctx.basePath}/nl/locale-false?nextLocale=fr`
)
await browser.eval('window.beforeNav = 1')
await browser.eval(`(function() {
window.next.router.push('/auto-export', '/auto-export', { locale: 'no' })
})()`)
await browser.waitForElementByCss('#not-found')
expect(await browser.eval('window.beforeNav')).toBe(null)
const props = JSON.parse(await browser.elementByCss('#props').text())
expect(props.is404).toBe(true)
expect(props.locale).toBe('en-US')
expect(props.locales).toEqual(locales)
expect(props.defaultLocale).toBe('en-US')
})
it('should 404 for non configured locales direct visit', async () => {
for (const [pathname, gssp] of [
['/gsp', true],
['/gssp', true],
['/auto-export'],
['/'],
['/gsp/fallback/first'],
]) {
const res = await fetchViaHTTP(
ctx.appPort,
`/no${pathname === '/' ? '' : pathname}`,
undefined,
{
redirect: 'manual',
}
)
if (!ctx.isDev) {
await browser.eval(`(function() {
document.querySelector('#to-gssp-slug-default').scrollIntoView()
document.querySelector('#to-gsp-default').scrollIntoView()
})()`)
expect(res.status).toBe(404)
await check(async () => {
const hrefs = await browser.eval(`Object.keys(window.next.router.sdc)`)
hrefs.sort()
if (gssp) {
const res = await fetchViaHTTP(
ctx.appPort,
`/_next/data/${ctx.buildId}/no${pathname}.json`,
undefined,
{
redirect: 'manual',
}
assert.deepEqual(
hrefs.map((href) =>
new URL(href).pathname
.replace(ctx.basePath, '')
.replace(/^\/_next\/data\/[^/]+/, '')
),
[
'/en-US/gsp.json',
'/fr/gsp.json',
'/fr/gsp/fallback/first.json',
'/fr/gsp/fallback/hello.json',
]
)
expect(res.status).toBe(404)
}
return 'yes'
}, 'yes')
}
expect(await browser.eval('window.beforeNav')).toBe(1)
})
if (ctx.isDev) {
......@@ -802,6 +788,7 @@ export function runTests(ctx) {
.replace(/^\/_next\/data\/[^/]+/, '')
),
[
'/en-US/gsp.json',
'/fr/gsp.json',
'/fr/gsp/fallback/first.json',
'/fr/gsp/fallback/hello.json',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册