-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
201 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,30 @@ | ||
import { NextRouter, SingletonRouter } from 'next/router' | ||
import { UrlObject, parse as parseUrl } from 'url' | ||
|
||
import { getNtrData } from './ntrData' | ||
|
||
export const getLocale = ( | ||
{ locale, defaultLocale, locales }: NextRouter | SingletonRouter, | ||
explicitLocale?: string | false, | ||
) => explicitLocale || locale || defaultLocale || locales?.[0] || getNtrData().defaultLocale || getNtrData().locales[0] | ||
export const getLocale = ({ | ||
router, | ||
locale: explicitLocale, | ||
url, | ||
}: { | ||
router?: NextRouter | SingletonRouter | ||
locale?: string | false | ||
url?: string | UrlObject | URL | ||
} = {}) => { | ||
if (explicitLocale) { | ||
return explicitLocale | ||
} | ||
const { i18n } = getNtrData() | ||
|
||
// explicitLocale === false if opted-out of automatically handling the locale prefixing | ||
// Cf. https://nextjs.org/docs/advanced-features/i18n-routing#transition-between-locales | ||
if (explicitLocale === false && url) { | ||
const { pathname } = typeof url === 'string' ? parseUrl(url) : url | ||
const localeSegment = pathname?.split('/')[1] | ||
if (localeSegment && i18n.locales.includes(localeSegment)) { | ||
return localeSegment | ||
} | ||
} | ||
return router?.locale || router?.defaultLocale || i18n.defaultLocale || router?.locales?.[0] || i18n.locales[0] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,67 @@ | ||
import { isDefaultLocale } from '../shared/isDefaultLocale' | ||
import { getNtrData } from './ntrData' | ||
|
||
export function removeLangPrefix(pathname: string, toArray?: false, locale?: string): string | ||
export function removeLangPrefix(pathname: string, toArray: true, locale?: string): string[] | ||
export function removeLangPrefix(pathname: string, toArray?: boolean, givenLocale?: string): string | string[] { | ||
const pathParts = pathname.split('/').filter(Boolean) | ||
const { routesTree, defaultLocale, locales } = getNtrData() | ||
/** | ||
* Remove both the lang prefix and the root prefix from a pathname | ||
* | ||
* (The root prefix is a prefix that can be added for a locale between the locale prefix | ||
* and the rest of the pathname. It is defined in the root _routes.json file for the "/" key.) | ||
*/ | ||
export function removeLangPrefix( | ||
pathname: string, | ||
/** | ||
* If locale is explicitely given, removeLangPrefix will use it, | ||
* it it is not, removeLangPrefix will try to deduce the locale from the pathname | ||
*/ | ||
locale?: string, | ||
): string { | ||
const { | ||
routesTree, | ||
i18n, | ||
i18n: { locales }, | ||
} = getNtrData() | ||
let lang = locale | ||
let root = '' | ||
|
||
const getLangRoot = (lang: string) => routesTree.paths[lang] || routesTree.paths.default | ||
|
||
const defaultLocaleRoot = defaultLocale && getLangRoot(defaultLocale) | ||
const hasLangPrefix = givenLocale ? pathParts[0] === givenLocale : locales.includes(pathParts[0]) | ||
const hasDefaultLocalePrefix = !hasLangPrefix && !!defaultLocaleRoot && pathParts[0] === defaultLocaleRoot | ||
const hasGivenLocalePrefix = givenLocale ? pathParts[hasLangPrefix ? 1 : 0] === getLangRoot(givenLocale) : false | ||
if (locale) { | ||
root = getLangRoot(locale) | ||
} else { | ||
const prefixLocale = locales.find((locale) => new RegExp(`\\/${locale}(\\/|$)`).test(pathname)) | ||
if (prefixLocale) { | ||
lang = prefixLocale | ||
root = getLangRoot(prefixLocale) | ||
} else { | ||
for (const l of locales) { | ||
if (isDefaultLocale(l, i18n)) { | ||
lang = l | ||
root = getLangRoot(l) | ||
break | ||
} | ||
} | ||
} | ||
} | ||
|
||
let remainingPathname: string | undefined = undefined | ||
|
||
if (!lang) { | ||
return pathname | ||
} | ||
|
||
const fullPrefix = `/${lang}/${root}` | ||
|
||
if (!hasLangPrefix && !hasDefaultLocalePrefix && !hasGivenLocalePrefix) { | ||
return toArray ? pathParts : pathname | ||
if (root && pathname.startsWith(fullPrefix)) { | ||
remainingPathname = pathname.slice(fullPrefix.length) | ||
} else if (root && pathname.startsWith(`/${root}`)) { | ||
remainingPathname = pathname.slice(root.length + 1) | ||
} else if (pathname.startsWith(`/${lang}`)) { | ||
remainingPathname = pathname.slice(lang.length + 1) | ||
} | ||
|
||
const locale = givenLocale || hasLangPrefix ? pathParts[0] : defaultLocale | ||
const localeRootParts = (locale || hasGivenLocalePrefix) && getLangRoot(locale)?.split('/') | ||
const nbPathPartsToRemove = | ||
(hasLangPrefix ? 1 : 0) + | ||
(localeRootParts && (!hasLangPrefix || pathParts[1] === localeRootParts[0]) ? localeRootParts.length : 0) | ||
if (typeof remainingPathname === 'string' && /^($|\/)/.test(remainingPathname)) { | ||
return remainingPathname | ||
} | ||
|
||
return toArray ? pathParts.slice(nbPathPartsToRemove) : `/${pathParts.slice(nbPathPartsToRemove).join('/')}` | ||
return pathname | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.