Without pre-rendering, we can simply determine the locale at the vite-plugin-ssr
server middleware:
const renderPage = createPageRenderer(/* ... */)
// `vite-plugin-ssr` server middleware
app.get('*', async (req, res) => {
let { url } = req
const { locale, urlWithoutLocale } = extractLocale(url)
// We set `pageContext.url` to `urlWithoutLocale` instead of `req.url`.
// So that the locale `/en-US/` in the URL is stripped away.
url = urlWithoutLocale
const pageContext = {
url,
// We make `locale` available to pages as `pageContext.locale`
locale
}
const result = await renderPage(pageContext)
/* ... */
})
// We usually use a library instead of implementing our own locale retrieval mechanism
function extractLocale(url) {
// We determine the locale, for example:
// extractLocale('/en-US/film/42').locale === 'en-US'
// extractLocale('/de-DE/film/42').locale === 'de-DE'
const locale = /*...*/
// We may also strip the language URL pathname, for example:
// extractLocale('/en-US/film/42').urlWithoutLocale === '/film/42'
// extractLocale('/de-DE/film/42').urlWithoutLocale === '/film/42'
// ...
urlWithoutLocale = /*...*/
return { locale, urlWithoutLocale }
}
We can then make pageContext.locale
available to all our components, see Access pageContext
anywhere.
This technique also works with:
Accept-Language: fr
headers?lang=fr
query parametersdomain.fr
domain TLDsExample:
When using pre-rendering,
we can use the hooks onBeforeRoute()
and onBeforePrerender()
.
// _default.page.route.js
export { onBeforeRoute }
function onBeforeRoute(pageContext) {
let { url } = pageContext
const { urlWithoutLocale, locale } = extractLocale(url)
url = urlWithoutLocale
return {
pageContext: {
// We make `locale` available as `pageContext.locale`.
// We can then use https://vite-plugin-ssr.com/pageContext-anywhere
// to access `pageContext.locale` in any React/Vue component.
locale,
// We overwrite the original URL
url
}
}
}
// _default.page.server.js
export { onBeforePrerender }
function onBeforePrerender(globalContext) {
const prerenderPageContexts = []
globalContext.prerenderPageContexts.forEach((pageContext) => {
prerenderPageContexts.push({
...pageContext,
locale: localeDefault
})
// We add the localized pages to the list of pages that are going to be pre-rendered
locales
.filter((locale) => locale !== localeDefault)
.forEach((locale) => {
prerenderPageContexts.push({
...pageContext,
url: `/${locale}${pageContext.url}`,
locale
})
})
})
return {
globalContext: {
prerenderPageContexts,
}
}
}
Example: