{t('app.title')}
{t('app.subtitle')}
-{t('page.text@@I\'m a default value')}
- > +{t('page.text')}
+{t('page.default@@I\'m a default value')}
+{t(`runtimePage.${key}`)}
+diff --git a/docs/adapters.md b/docs/adapters.md index 6c0bfc6..8cb0d60 100644 --- a/docs/adapters.md +++ b/docs/adapters.md @@ -26,7 +26,8 @@ export const loadTranslation$: LoadTranslationFn = $(async (lang: string, asset: If you use Qwik-provided adapters for publishing your app, especially with _edge functions_ or _static generation_, it is recommended to bundle the translation files: ```typescript /** - * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build + * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build. + * Json files are converted to objects: keys must be valid variable names */ const translationData = import.meta.glob('/i18n/**/*.json'); @@ -50,6 +51,8 @@ const loadTranslation$: LoadTranslationFn = server$((lang: string, asset: string > Note. It is recommended to put this function in a separate file from the configuration, to allow the Qwik compiler to respect the initialization order of the functions +Refer to _Vite_ documentation for more information on [Glob import](https://vitejs.dev/guide/features.html#glob-import) + ## Static Site Generation (SSG) If you want to use Static Site Generation with the localized router, it is necessary to manage the dynamic language parameter, and you need to add the values it can take to the pages: diff --git a/docs/quick-start.md b/docs/quick-start.md index 30e45d3..ea31a5a 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -29,7 +29,8 @@ import { server$ } from '@builder.io/qwik-city'; import type { LoadTranslationFn, TranslationFn } from 'qwik-speak'; /** - * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build + * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build. + * Json files are converted to objects: keys must be valid variable names */ const translationData = import.meta.glob('/i18n/**/*.json'); diff --git a/docs/tutorial-routing.md b/docs/tutorial-routing.md index 198250c..dd5776e 100644 --- a/docs/tutorial-routing.md +++ b/docs/tutorial-routing.md @@ -26,7 +26,8 @@ export const config: SpeakConfig = { _src/speak-functions.ts_ ```typescript /** - * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build + * Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build. + * Json files are converted to objects: keys must be valid variable names */ const translationData = import.meta.glob('/i18n/**/*.json'); diff --git a/i18n/en-US/page.json b/i18n/en-US/page.json index b765c29..cb2e3e3 100644 --- a/i18n/en-US/page.json +++ b/i18n/en-US/page.json @@ -1,5 +1,6 @@ { "page": { - "text": "I'm a default value" + "default": "I'm a default value", + "text": "I'm another page" } } \ No newline at end of file diff --git a/i18n/en-US/runtimePage.json b/i18n/en-US/runtimePage.json new file mode 100644 index 0000000..fe289f7 --- /dev/null +++ b/i18n/en-US/runtimePage.json @@ -0,0 +1,5 @@ +{ + "runtimePage": { + "dynamic": "I'm a dynamic value" + } +} \ No newline at end of file diff --git a/i18n/it-IT/page.json b/i18n/it-IT/page.json index b765c29..0f02394 100644 --- a/i18n/it-IT/page.json +++ b/i18n/it-IT/page.json @@ -1,5 +1,6 @@ { "page": { - "text": "I'm a default value" + "default": "I'm a default value", + "text": "Io sono un'altra pagina" } } \ No newline at end of file diff --git a/i18n/it-IT/runtimePage.json b/i18n/it-IT/runtimePage.json new file mode 100644 index 0000000..a65133e --- /dev/null +++ b/i18n/it-IT/runtimePage.json @@ -0,0 +1,5 @@ +{ + "runtimePage": { + "dynamic": "Io sono un valore dinamico" + } +} \ No newline at end of file diff --git a/packages/qwik-speak/src/core.ts b/packages/qwik-speak/src/core.ts index 3444cff..945d850 100644 --- a/packages/qwik-speak/src/core.ts +++ b/packages/qwik-speak/src/core.ts @@ -35,7 +35,12 @@ export const loadTranslations = async ( if (isDev === true || isServer || runtimeAssets) { const { locale, translation, translationFn } = ctx; - const resolvedAssets = [...assets, ...runtimeAssets ?? []]; + let resolvedAssets: string[]; + if (isDev === true || isServer) { + resolvedAssets = [...assets, ...runtimeAssets ?? []]; + } else { + resolvedAssets = [...runtimeAssets ?? []]; + } // Multilingual const resolvedLangs = new Set(langs || []); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/e2e/home.spec.ts b/src/e2e/home.spec.ts index d2a7cbb..66b8bbe 100644 --- a/src/e2e/home.spec.ts +++ b/src/e2e/home.spec.ts @@ -19,7 +19,7 @@ test.describe('Home', () => { }); test('change language', async ({ page }) => { - await page.locator('text=it-IT').click(); + await page.locator('text=Italian (Italy)').click(); await expect(page.locator('main')).toContainText('Qwik Speak'); await expect(page.locator('main')).toContainText('Traduci le tue app Qwik in qualsiasi lingua'); @@ -34,7 +34,7 @@ test.describe('Home', () => { await page.locator('text=Pagina').click(); - await expect(page.locator('main')).toContainText('Qwik Speak'); - await expect(page.locator('main')).toContainText('Traduci le tue app Qwik in qualsiasi lingua'); + await expect(page.locator('main')).toContainText("Io sono un'altra pagina"); + await expect(page.locator('main')).toContainText("Io sono un valore dinamico"); }); }); diff --git a/src/e2e/page.spec.ts b/src/e2e/page.spec.ts index a6078fc..b003ed6 100644 --- a/src/e2e/page.spec.ts +++ b/src/e2e/page.spec.ts @@ -8,18 +8,22 @@ test.describe('Page', () => { test('translate', async ({ page }) => { await expect(page.locator('main')).toContainText('Qwik Speak'); await expect(page.locator('main')).toContainText('Translate your Qwik apps into any language'); + await expect(page.locator('main')).toContainText("I'm another page"); await expect(page.locator('main')).toContainText("I'm a default value"); + await expect(page.locator('main')).toContainText("I'm a dynamic value"); await expect(page).toHaveTitle('Page - Qwik Speak'); await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', "I'm another page"); }); test('change language', async ({ page }) => { - await page.locator('text=it-IT').click(); + await page.locator('text=Italian (Italy)').click(); await expect(page.locator('main')).toContainText('Qwik Speak'); await expect(page.locator('main')).toContainText('Traduci le tue app Qwik in qualsiasi lingua'); + await expect(page.locator('main')).toContainText("Io sono un'altra pagina"); await expect(page.locator('main')).toContainText("I'm a default value"); + await expect(page.locator('main')).toContainText("Io sono un valore dinamico"); await expect(page).toHaveTitle('Pagina - Qwik Speak'); await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', "Io sono un'altra pagina"); diff --git a/src/routes/[...lang]/page/index.tsx b/src/routes/[...lang]/page/index.tsx index f0c0315..6f9f85f 100644 --- a/src/routes/[...lang]/page/index.tsx +++ b/src/routes/[...lang]/page/index.tsx @@ -3,13 +3,17 @@ import type { DocumentHead } from '@builder.io/qwik-city'; import { Speak, $translate as t } from 'qwik-speak'; export const Page = component$(() => { + const key = 'dynamic'; + return ( - <> +
{t('page.text@@I\'m a default value')}
- > +{t('page.text')}
+{t('page.default@@I\'m a default value')}
+{t(`runtimePage.${key}`)}
+