Skip to content

Commit

Permalink
Fix already translated url translation
Browse files Browse the repository at this point in the history
  • Loading branch information
cvolant committed Aug 25, 2021
1 parent e85abc9 commit c1ed9c3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export const withTranslateRoutes = (nextConfig: Partial<NextConfig>): NextConfig
// TODO: validateRoutesTree(routesTree)

process.env.NEXT_PUBLIC_ROUTES = JSON.stringify(routesTree)
process.env.NEXT_PUBLIC_LOCALES = nextConfig.i18n?.locales?.join(',') || ''
process.env.NEXT_PUBLIC_DEFAULT_LOCALE = nextConfig.i18n?.defaultLocale || ''

return {
Expand Down
60 changes: 49 additions & 11 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import type { PrefetchOptions } from 'next/dist/next-server/lib/router/router'
type Options<F extends 'string' | 'object' = 'string' | 'object'> = {
format?: F
/** For testing only: do not use this option in production */
routes?: TRouteBranch
routesTree?: TRouteBranch
/** For testing only: do not use this option in production */
locales?: string[]
/** For testing only: do not use this option in production */
defaultLocale?: string
}
Expand All @@ -26,6 +28,7 @@ interface TransitionOptions {
}

const routesTree = JSON.parse(process.env.NEXT_PUBLIC_ROUTES || 'null') as TRouteBranch
const locales = (process.env.NEXT_PUBLIC_LOCALES || '').split(',') as string[]
const defaultLocale = process.env.NEXT_PUBLIC_DEFAULT_LOCALE as string

/** Get children + (grand)children of children whose path must be ignord (path === '.') */
Expand Down Expand Up @@ -129,6 +132,38 @@ const translatePathParts = ({
}
}

const removeLangPrefix = (pathParts: string[], options: Options = {}): string[] => {
const {
routesTree: optionsRoutesTree = routesTree,
locales: optionsLocales = locales,
defaultLocale: optionsDefaultLocale = defaultLocale,
} = options

const getLangRoot = (lang: string) => optionsRoutesTree.paths[lang] || optionsRoutesTree.paths.default

const hasLangPrefix = optionsLocales.includes(pathParts[0])
const defaultLocaleRoot = getLangRoot(optionsDefaultLocale)
const hasDefaultLocalePrefix = !hasLangPrefix && !!defaultLocaleRoot && pathParts[0] === defaultLocaleRoot

const locale = hasLangPrefix ? pathParts[0] : hasDefaultLocalePrefix ? optionsDefaultLocale : undefined

console.log('From index, removeLangPrefix.', {
pathParts,
hasLangPrefix,
defaultLocaleRoot,
hasDefaultLocalePrefix,
locale,
})

if (!locale) {
return pathParts
}

const nbPathPartsToRemove = (locale === optionsDefaultLocale ? 0 : 1) + getLangRoot(locale).split('/').length

return pathParts.slice(nbPathPartsToRemove)
}

/**
* Translate url into option.locale locale, or if not defined, in current locale
*
Expand All @@ -154,11 +189,12 @@ export function translateUrl<U extends string | UrlObject, F extends 'string' |
? string
: UrlObject

export function translateUrl(
url: Url,
locale: string,
{ format, routes = routesTree, defaultLocale: tuDefaultLocale = defaultLocale }: Options = {},
): Url {
export function translateUrl(url: Url, locale: string, options: Options = {}): Url {
const {
format,
routesTree: optionsRoutesTree = routesTree,
defaultLocale: optionsDefaultLocale = defaultLocale,
} = options
const returnFormat = format || typeof url
const urlObject = typeof url === 'object' ? (url as UrlObject) : parseUrl(url, true)
const { pathname, query } = urlObject
Expand All @@ -167,18 +203,20 @@ export function translateUrl(
return returnFormat === 'object' ? url : formatUrl(url)
}

if (!routes) {
if (!optionsRoutesTree) {
throw new Error(
'> next-translate-routes - No routes tree defined. next-translate-routes plugin is probably missing from next.config.js',
)
}

const pathParts = pathname.replace(/^\//, '').split('/')
const rawPathParts = pathname.replace(/^\//, '').split('/')
const pathParts = removeLangPrefix(rawPathParts, options)

const { translatedPathParts, augmentedQuery = {} } = translatePathParts({
locale,
pathParts,
query: parseQuery(typeof query === 'string' ? query : stringifyQuery(query || {})),
routeBranch: routes,
routeBranch: optionsRoutesTree,
})
const path = translatedPathParts.join('/')
const compiledPath = compile(path, { validate: false })(augmentedQuery)
Expand All @@ -193,8 +231,8 @@ export function translateUrl(
{},
)

const fullPathname = `${locale !== tuDefaultLocale ? `/${locale}` : ''}${
routes.paths[locale] ? `/${routes.paths[locale]}` : ''
const fullPathname = `${locale !== optionsDefaultLocale ? `/${locale}` : ''}${
optionsRoutesTree.paths[locale] ? `/${optionsRoutesTree.paths[locale]}` : ''
}/${compiledPath}`

const translatedUrlObject = {
Expand Down
23 changes: 21 additions & 2 deletions tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ declare global {
test('parsePagesTree.', () => {
const pagesPath = path.resolve(process.cwd(), './tests/fixtures/pages')
const parsedPagesTree = parsePagesTree(pagesPath, true)
// console.log('From test, parsedPagesTree:', JSON.stringify(parsedPagesTree, null, 4))
expect(parsedPagesTree).toEqual(routesTree)
})

Expand Down Expand Up @@ -77,7 +76,27 @@ test('translateHref.', () => {
href: '/?baz=3#section',
expected: '/?baz=3#section',
},
{
href: {
pathname: '/community/[communityId]/[communitySlug]/statistics',
query: { communityId: 300, communitySlug: 'three-hundred', baz: 3 },
hash: 'section',
},
locale: 'en',
expected: {
pathname: '/en/root/community/300-three-hundred/statistics',
query: { baz: 3 },
hash: 'section',
},
},
{
href: '/en/root/feast-days/foo/bar?baz=3#section',
locale: 'en',
expected: '/en/root/feast-days/foo/bar?baz=3#section',
},
].forEach(({ href, locale = 'fr', expected }) => {
expect(translateUrl(href, locale || 'fr', { routes: routesTree, defaultLocale: 'fr' })).toEqual(expected)
expect(
translateUrl(href, locale || 'fr', { routesTree, locales: ['fr', 'en', 'es', 'pt'], defaultLocale: 'fr' }),
).toEqual(expected)
})
})

0 comments on commit c1ed9c3

Please sign in to comment.