Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(presenter): make i18n locale extractable from url #335

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f66d696
Make i18n for page titles.
Elweyn Mar 14, 2024
e33dd42
Locale in i18n.global.locale.value is 'de' or 'en' for testing set fi…
Elweyn Mar 16, 2024
a4e9ccf
Locale in i18n.global.locale.value is 'de' or 'en' for testing set fi…
Elweyn Mar 16, 2024
c2044a1
We don't want to use 'de-DE' and use 'de' instead.
Elweyn Mar 16, 2024
f547fe8
Set i18n.global.locale.value to the value extracted out of the url.
Elweyn Mar 16, 2024
a89eb31
Change export function to export const title.
Elweyn Mar 16, 2024
e5ab2d7
Create localeStore.
Elweyn Mar 18, 2024
85a6817
Remove changes on +title.ts
Elweyn Mar 18, 2024
c371959
Merge branch 'master' into 208-feature-implement-page-title-translati…
Elweyn Mar 18, 2024
db89d5e
Add locale to pageContext.
Elweyn Mar 19, 2024
d40547e
Change html lang to store value.
Elweyn Mar 19, 2024
94c6915
Use localeStore as value of languageselector.
Elweyn Mar 19, 2024
d3172be
Transfere locale to frontend.
Elweyn Mar 22, 2024
d34b5e8
Change pageContext.url to pageContext.urlLogical.
Elweyn Mar 22, 2024
861eb45
Remove LocaleStore.
Elweyn Mar 22, 2024
5de2157
Set locale to pageContext and add default i18n value.
Elweyn Mar 22, 2024
2251b90
Set default locale to the locale given in pageContext.
Elweyn Mar 22, 2024
15ac759
Remove LocaleStorage.
Elweyn Mar 22, 2024
dc7cdc3
Add locale to the pageContext
Elweyn Mar 22, 2024
9a099de
Add non default locale to the prerenderContext.pageContexts.
Elweyn Mar 22, 2024
7e0bdfb
Merge branch 'master' into 208-feature-implement-page-title-translati…
Elweyn Mar 22, 2024
a87ea62
Correct linting.
Elweyn Mar 22, 2024
d43176e
Define LocaleCode and give the type to array of locales.
Elweyn Mar 23, 2024
88cadea
Make extractLocale more dynamic to locales changes.
Elweyn Mar 23, 2024
70d50b0
Use the defined locales and localeDefault.
Elweyn Mar 23, 2024
5fc33b3
Make locales check more dynamic.
Elweyn Mar 23, 2024
04f8c1c
Make PageContext.locale use the defined LocaleCode type.
Elweyn Mar 23, 2024
022c869
Make locales check more dynamic.
Elweyn Mar 23, 2024
d3bc59a
Move localizedLocale to locales folder.
Elweyn Mar 23, 2024
4bdcfa1
Add default locale to the mock pageContext.
Elweyn Mar 25, 2024
79faef1
Test if changing language switch the i18n value.
Elweyn Mar 25, 2024
244901e
Merge branch 'master' into 208-feature-implement-page-title-translati…
Elweyn Mar 25, 2024
114aeec
Merge branch 'master' into 208-feature-implement-page-title-translati…
Elweyn Mar 25, 2024
1cbc7bd
Update presenter/src/components/language/LanguageSelector.vue
Elweyn Mar 26, 2024
4f88924
Update presenter/renderer/app.ts
Elweyn Mar 26, 2024
0a101c7
Update presenter/locales/extractLocale.ts
Elweyn Mar 26, 2024
d61220e
Update presenter/renderer/+onBeforeRoute.ts
Elweyn Mar 26, 2024
fe90407
Remove changes to LanguageSelector since the locale is set somewhere …
Elweyn Mar 26, 2024
82c9452
Fix linting error.
Elweyn Mar 26, 2024
d6a1980
Change test description.
Elweyn Mar 26, 2024
67eebde
Remove check on defaultLocale in prerenderStart
Elweyn Mar 26, 2024
805d515
Move /locales to /src/locales.
Elweyn Mar 26, 2024
91f5b0b
Move src/locales/*.ts to src/locales/index.ts and change import.
Elweyn Mar 26, 2024
a80a6ed
Remove text in LanguageSelector.
Elweyn Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion presenter/renderer/+config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
export default {
clientRouting: true,
prefetchStaticAssets: 'viewport',
passToClient: ['pageProps', /* 'urlPathname', */ 'routeParams'],
passToClient: ['pageProps', /* 'urlPathname', */ 'routeParams', 'locale'],
meta: {
title: {
// Make the value of `title` available on both the server- and client-side
Expand Down
16 changes: 16 additions & 0 deletions presenter/renderer/+onBeforeRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { PageContext } from 'vike/types'

import { extractLocale } from '#src/locales'

export function onBeforeRoute(pageContext: PageContext) {
const { urlWithoutLocale, locale } = extractLocale(pageContext.urlPathname)

return {
pageContext: {
// Make `locale` available as `pageContext.locale`
locale,
// Vike's router will use pageContext.urlLogical instead of pageContext.urlOriginal
urlLogical: urlWithoutLocale,
},
}
}
32 changes: 32 additions & 0 deletions presenter/renderer/+onPrerenderStart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { PageContextServer } from 'vike/types'

import { locales } from '#src/locales'

export { onPrerenderStart }

function onPrerenderStart(prerenderContext: { pageContexts: PageContextServer[] }): {
prerenderContext: {
pageContexts: PageContextServer[]
}
} {
const storePageContexts: PageContextServer[] = []
prerenderContext.pageContexts.forEach((pageContext) => {
// Duplicate pageContext for each locale
locales.forEach((locale) => {
// Localize URL
let { urlOriginal } = pageContext
urlOriginal = `/${locale}${urlOriginal}`
storePageContexts.push({
...pageContext,
urlOriginal,
// Set pageContext.locale
locale,
})
})
})
return {
prerenderContext: {
pageContexts: storePageContexts,
},
}
}
7 changes: 7 additions & 0 deletions presenter/renderer/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createApolloClient } from '#plugins/apollo'
import i18n from '#plugins/i18n'
import pinia from '#plugins/pinia'
import CreateVuetify from '#plugins/vuetify'
import { locales } from '#src/locales'
import AuthService from '#src/services/AuthService'
import { useAuthStore } from '#stores/authStore'

Expand All @@ -25,6 +26,7 @@ function createApp(pageContext: PageContext, isClient = true) {
data: () => ({
Page: markRaw(pageContext.Page),
pageProps: markRaw(pageContext.pageProps || {}),
locale: markRaw(pageContext.locale || {}),
isClient,
}),
created() {
Expand Down Expand Up @@ -64,13 +66,18 @@ function createApp(pageContext: PageContext, isClient = true) {
Object.assign(pageContextReactive, pageContext)
rootComponent.Page = markRaw(pageContext.Page)
rootComponent.pageProps = markRaw(pageContext.pageProps || {})
rootComponent.locale = markRaw(pageContext.locale || {})
},
})

const pageContextReactive = reactive(pageContext)

setPageContext(app, pageContextReactive)

if (pageContext.locale && locales.includes(pageContext.locale)) {
i18n.global.locale.value = pageContext.locale
}

return { app, i18n }
}

Expand Down
5 changes: 3 additions & 2 deletions presenter/renderer/plugins/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { createI18n } from 'vue-i18n'
import { de as vuetifyDe, en as vuetifyEn } from 'vuetify/locale'

import { localeDefault, fallbackLocale } from '#src/locales'
import de from '#src/locales/de.json'
import en from '#src/locales/en.json'

export default createI18n({
legacy: false, // Vuetify does not support the legacy mode of vue-i18n
globalInjection: true,
locale: 'de',
fallbackLocale: 'en',
locale: localeDefault,
fallbackLocale,
messages: {
de: {
$vuetify: vuetifyDe,
Expand Down
1 change: 1 addition & 0 deletions presenter/scripts/tests/mock.vikePageContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ config.global.provide = {
routeParams: {
code: 'my-code',
},
locale: 'de',
},
}
14 changes: 14 additions & 0 deletions presenter/src/components/language/LanguageSelector.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { mount } from '@vue/test-utils'
import { describe, it, expect, beforeEach } from 'vitest'

import i18n from '#plugins/i18n'

import LanguageSelector from './LanguageSelector.vue'

describe('LanguageSelector', () => {
Expand All @@ -10,12 +12,24 @@ describe('LanguageSelector', () => {
})
}
let wrapper: ReturnType<typeof Wrapper>
let vSelect: ReturnType<typeof wrapper.findComponent>

beforeEach(() => {
wrapper = Wrapper()
vSelect = wrapper.findComponent({ name: 'v-select' })
})

it('renders', () => {
expect(wrapper.element).toMatchSnapshot()
})

describe('switch locale', () => {
beforeEach(async () => {
await vSelect.setValue('en')
})

it('to en', () => {
expect(i18n.global.locale.value).toBe('en')
})
})
})
8 changes: 3 additions & 5 deletions presenter/src/components/language/LanguageSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@
<script lang="ts" setup>
import { ref } from 'vue'

// TODO better place? maybe locales folder?
const languages = ref([
{ locale: 'de', title: 'Deutsch' },
{ locale: 'en', title: 'English' },
])
import { localizedLocale } from '#src/locales'

const languages = ref(localizedLocale)
</script>

<style lang="scss">
Expand Down
25 changes: 25 additions & 0 deletions presenter/src/locales/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export type LocaleCode = 'de' | 'en'
export const locales: LocaleCode[] = ['de', 'en']
export const localeDefault = 'de'
export const fallbackLocale = 'en'
export const localizedLocale = [
{ locale: 'de', title: 'Deutsch' },
{ locale: 'en', title: 'English' },
]

export function extractLocale(url: string) {
const urlPaths = url.split('/')
let locale: LocaleCode
let urlWithoutLocale
// We remove the URL locale, for example `/de/about` => `/about`
const firstPath = urlPaths[1] as LocaleCode
if (locales.includes(firstPath)) {
locale = firstPath
urlWithoutLocale = '/' + urlPaths.slice(2).join('/')
} else {
locale = localeDefault
urlWithoutLocale = url
}

return { locale, urlWithoutLocale }
}
2 changes: 2 additions & 0 deletions presenter/types/PageContext.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LocaleCode } from '#src/locales'
import { Page } from '#types/Page'
import { PageProps } from '#types/PageProps'

Expand All @@ -11,6 +12,7 @@ declare global {
}
Page: Page
pageProps?: PageProps
locale?: LocaleCode
}
}
}
2 changes: 1 addition & 1 deletion presenter/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const config: UserConfig = {
!isStorybook() && vike({ prerender: true }), // SSR only when storybook is not running
vueI18n({
ssr: true,
include: path.resolve(__dirname, './src/locales/**'),
include: path.resolve(__dirname, './src/locales/**.json'),
jitCompilation: false,
}),
checker({
Expand Down