Skip to content

Commit 8e4e96a

Browse files
committed
add i18n
1 parent cba8b7d commit 8e4e96a

File tree

9 files changed

+81
-25
lines changed

9 files changed

+81
-25
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"eslint-plugin-qwik": "^1.2.6",
3636
"postcss": "^8.4.23",
3737
"prettier": "2.8.8",
38+
"qwik-speak": "^0.15.1",
3839
"tailwindcss": "^3.3.1",
3940
"typescript": "5.1.6",
4041
"undici": "5.22.1",

pnpm-lock.yaml

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/AddressForm/AddressForm.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import {
88
SfSelect,
99
} from 'qwik-storefront-ui';
1010
import { useAddressForm } from '~/routes/layout';
11-
import { useTranslation } from '~/shared/utils';
1211
import { FormHelperText, FormLabel } from '../Form';
1312
import type { AddressFormFields, AddressFormProps } from './types';
13+
import { useTranslate } from 'qwik-speak';
1414

1515
export const AddressForm = component$<AddressFormProps>(
1616
({ type, savedAddress }) => {
17+
const t = useTranslate();
1718
const addressFormAction = useAddressForm();
18-
const { t } = useTranslation('address');
1919
const formRefSig = useSignal<HTMLFormElement>();
2020
useStore<{ value: AddressFormFields }>({
2121
// const addressStore =

src/components/Footer/Footer.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
import { component$ } from '@builder.io/qwik';
22
import { Link } from '@builder.io/qwik-city';
3+
import { useTranslate } from 'qwik-speak';
34
import {
45
bottomLinks,
56
categories,
67
companyName,
78
contactOptions,
89
socialMedia,
910
} from '~/mocks';
10-
import { useTranslation } from '~/shared/utils';
1111
import { Divider } from '../UI';
1212

1313
type FooterProps = {
1414
class?: string;
1515
};
1616

1717
export const Footer = component$<FooterProps>(({ class: _class = '' }) => {
18-
const { t } = useTranslation('footer');
18+
const t = useTranslate();
19+
1920
return (
2021
<footer class={['pt-10 bg-neutral-100', _class]} data-testid='footer'>
2122
<div
@@ -47,9 +48,9 @@ export const Footer = component$<FooterProps>(({ class: _class = '' }) => {
4748
{contactOptions.map(({ icon, link, details, key }) => (
4849
<div
4950
key={key}
50-
class='mx-auto my-4 text-center flex flex-col items-center w-8'
51+
class='mx-auto my-4 text-center flex flex-col items-center'
5152
>
52-
{icon}
53+
<div class='w-8'>{icon}</div>
5354
<Link
5455
href={link}
5556
class='py-1 my-2 font-medium typography-text-lg font-body no-underline text-neutral-600 hover:underline hover:!text-neutral-900 active:underline active:!text-neutral-900'

src/components/ProductCard/ProductCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { component$ } from '@builder.io/qwik';
22
import { Link } from '@builder.io/qwik-city';
33
import { Image } from 'qwik-image';
4+
import { useTranslate } from 'qwik-speak';
45
import {
56
SfButton,
67
SfCounter,
78
SfIconShoppingCart,
89
SfLink,
910
SfRating,
1011
} from 'qwik-storefront-ui';
11-
import { useTranslation } from '~/shared/utils';
1212

1313
export type ProductCardProps = {
1414
name: string;
@@ -35,7 +35,7 @@ export const ProductCard = component$<ProductCardProps>(
3535
class: _class,
3636
...attributes
3737
}) => {
38-
const { t } = useTranslation('');
38+
const t = useTranslate();
3939

4040
return (
4141
<div

src/root.tsx

+16-12
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import {
44
RouterOutlet,
55
ServiceWorkerRegister,
66
} from '@builder.io/qwik-city';
7+
import { QwikSpeakProvider } from 'qwik-speak';
78
import { RouterHead } from './components/RouterHead/RouterHead';
8-
99
import './global.css';
10+
import { config } from './speak-config';
11+
import { translationFn } from './speak-functions';
1012

1113
export default component$(() => {
1214
/**
@@ -17,16 +19,18 @@ export default component$(() => {
1719
*/
1820

1921
return (
20-
<QwikCityProvider>
21-
<head>
22-
<meta charSet='utf-8' />
23-
<link rel='manifest' href='/manifest.json' />
24-
<RouterHead />
25-
</head>
26-
<body lang='en'>
27-
<RouterOutlet />
28-
<ServiceWorkerRegister />
29-
</body>
30-
</QwikCityProvider>
22+
<QwikSpeakProvider config={config} translationFn={translationFn}>
23+
<QwikCityProvider>
24+
<head>
25+
<meta charSet='utf-8' />
26+
<link rel='manifest' href='/manifest.json' />
27+
<RouterHead />
28+
</head>
29+
<body lang='en'>
30+
<RouterOutlet />
31+
<ServiceWorkerRegister />
32+
</body>
33+
</QwikCityProvider>
34+
</QwikSpeakProvider>
3135
);
3236
});

src/shared/utils.ts

-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
export const useTranslation = (fileName: string) => {
2-
console.log(fileName);
3-
return { t: (label: string, ...args) => label };
4-
};
5-
61
export const sleep = (timeout: number) => {
72
return new Promise((resolve) => {
83
setTimeout(resolve, timeout);

src/speak-config.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { SpeakConfig } from 'qwik-speak';
2+
3+
export const config: SpeakConfig = {
4+
defaultLocale: {
5+
lang: 'en-US',
6+
currency: 'USD',
7+
timeZone: 'America/Los_Angeles',
8+
},
9+
supportedLocales: [
10+
{ lang: 'en-US', currency: 'USD', timeZone: 'America/Los_Angeles' },
11+
],
12+
assets: [
13+
'address',
14+
'cart',
15+
'category',
16+
'checkout',
17+
'common',
18+
'footer',
19+
'order',
20+
'product',
21+
],
22+
};

src/speak-functions.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { server$ } from '@builder.io/qwik-city';
2+
import type { LoadTranslationFn, Translation, TranslationFn } from 'qwik-speak';
3+
4+
/**
5+
* Translation files are lazy-loaded via dynamic import and will be split into separate chunks during build.
6+
* Keys must be valid variable names
7+
*/
8+
const translationData = import.meta.glob<Translation>('/i18n/**/*.json');
9+
10+
/**
11+
* Using server$, translation data is always accessed on the server
12+
*/
13+
const loadTranslation$: LoadTranslationFn = server$(
14+
async (lang: string, asset: string) =>
15+
await translationData[`/i18n/${lang}/${asset}.json`]()
16+
);
17+
18+
export const translationFn: TranslationFn = {
19+
loadTranslation$: loadTranslation$,
20+
};

0 commit comments

Comments
 (0)