Skip to content

Commit de7af38

Browse files
goanpecamelissawm
authored andcommitted
Add i18n and 10n with lingui and babel
1 parent c790ddb commit de7af38

File tree

16 files changed

+1757
-548
lines changed

16 files changed

+1757
-548
lines changed

.babelrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": [
3+
"next/babel"
4+
],
5+
"plugins": ["@lingui/babel-plugin-lingui-macro"]
6+
}

lingui.config.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const nextConfig = require('./next.config')
2+
3+
console.log('nextConfig', nextConfig)
4+
5+
/** @type {import('@lingui/conf').LinguiConfig} */
6+
module.exports = {
7+
locales: nextConfig.i18n.locales,
8+
pseudoLocale: 'pseudo',
9+
sourceLocale: nextConfig.i18n.defaultLocale,
10+
fallbackLocales: {
11+
default: 'en',
12+
},
13+
catalogs: [
14+
{
15+
path: 'src/locales/{locale}/messages',
16+
// path: 'src/locales/{locale}',
17+
include: ['src/'],
18+
},
19+
],
20+
}

next.config.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ export default withMDX({
1818
images: {
1919
domains: ["raw.githubusercontent.com", "numpy.org", "dask.org", "chainer.org", ],
2020
},
21+
i18n: {
22+
// These are all the locales you want to support in
23+
// your application
24+
locales: ["en", "es", "pt"],
25+
defaultLocale: "en",
26+
},
2127
})

package.json

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
"private": true,
55
"scripts": {
66
"build-cards": "node build-cards.js",
7+
"extract": "lingui extract",
8+
"compile": "lingui compile",
79
"dev": "next dev",
8-
"build": "next build",
10+
"build": "yarn extract && next build",
911
"start": "next start",
1012
"lint": "next lint"
1113
},
@@ -16,42 +18,48 @@
1618
"author": "Xarray Developers & Contributors",
1719
"license": "Apache 2.0",
1820
"dependencies": {
19-
"@chakra-ui/icons": "^2.2.1",
20-
"@chakra-ui/next-js": "^2.3.1",
21-
"@chakra-ui/react": "^2.9.1",
21+
"@chakra-ui/icons": "^2.2.4",
22+
"@chakra-ui/next-js": "^2.4.2",
23+
"@chakra-ui/react": "^2.10.9",
2224
"@chakra-ui/system": "^2.6.2",
23-
"@emotion/react": "^11.13.3",
24-
"@emotion/styled": "^11.13.0",
25-
"@fontsource-variable/inter": "^5.2.5",
26-
"@giscus/react": "^3.0.0",
27-
"@mdx-js/loader": "^3.0.1",
28-
"@mdx-js/react": "^3.0.1",
29-
"@next/mdx": "^14.2.14",
25+
"@emotion/react": "^11.14.0",
26+
"@emotion/styled": "^11.14.1",
27+
"@fontsource-variable/inter": "^5.2.8",
28+
"@giscus/react": "^3.1.0",
29+
"@lingui/core": "^5.6.0",
30+
"@lingui/react": "^5.6.0",
31+
"@mdx-js/loader": "^3.1.1",
32+
"@mdx-js/react": "^3.1.1",
33+
"@next/mdx": "^14.2.33",
3034
"apexcharts": "3.54.0",
3135
"d3": "^7.9.0",
32-
"date-fns": "^3.0.0",
36+
"date-fns": "^3.6.0",
3337
"date-fns-tz": "^3.2.0",
3438
"feed": "^5.1.0",
35-
"framer-motion": "^11.9.0",
36-
"glob": "^11.0.3",
39+
"framer-motion": "^11.18.2",
40+
"glob": "^11.1.0",
3741
"gray-matter": "^4.0.3",
38-
"isomorphic-dompurify": "^2.16.0",
39-
"next": "^14.2.30",
42+
"isomorphic-dompurify": "^2.32.0",
43+
"next": "^14.2.33",
4044
"next-mdx-remote": "^5.0.0",
4145
"react": "^18.3.1",
42-
"react-apexcharts": "^1.4.1",
46+
"react-apexcharts": "^1.8.0",
4347
"react-dom": "^18.3.1",
44-
"react-icons": "^5.3.0",
45-
"react-syntax-highlighter": "^15.5.0",
48+
"react-icons": "^5.5.0",
49+
"react-syntax-highlighter": "^15.6.6",
4650
"rehype-slug": "^6.0.0",
47-
"swr": "^2.2.5"
51+
"swr": "^2.3.6",
52+
"yarn": "^1.22.22"
4853
},
4954
"devDependencies": {
50-
"@types/react": "^18.3.11",
51-
"eslint": "^9.25.1",
55+
"@lingui/babel-plugin-lingui-macro": "^5.6.0",
56+
"@lingui/cli": "^5.6.0",
57+
"@lingui/loader": "^5.6.0",
58+
"@types/react": "^18.3.26",
59+
"eslint": "^9.39.1",
5260
"eslint-config-next": "15.3.3",
53-
"playwright": "^1.47.2",
54-
"typescript": ">=5.9.2",
55-
"webpack": "^5.101.0"
61+
"playwright": "^1.56.1",
62+
"typescript": "^5.9.3",
63+
"webpack": "^5.102.1"
5664
}
5765
}

src/components/layout.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { Header } from '@/components/header'
44
import { Link } from '@/components/mdx'
55
import { Box, Flex } from '@chakra-ui/react'
66
import Head from 'next/head'
7+
import { Trans, useLingui } from '@lingui/react/macro'
8+
import { useRouter } from 'next/router'
79

810
export const Layout = ({
911
title,
@@ -13,6 +15,14 @@ export const Layout = ({
1315
url = 'https://xarray.dev',
1416
enableBanner = false,
1517
}) => {
18+
/**
19+
* This macro hook is needed to get `t` which
20+
* is bound to i18n from React.Context
21+
*/
22+
const { t } = useLingui()
23+
const router = useRouter()
24+
const { pathname, asPath, query } = router
25+
1626
const bannerTitle = 'Check out the latest blog post:'
1727
// The first link will be the main description for the banner
1828
const bannerDescription = (

src/i18n.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { i18n, Messages } from '@lingui/core'
2+
import { useRouter } from 'next/router'
3+
import { useEffect } from 'react'
4+
5+
/**
6+
* Load messages for requested locale and activate it.
7+
* This function isn't part of the LinguiJS library because there are
8+
* many ways how to load messages — from REST API, from file, from cache, etc.
9+
*/
10+
export async function loadCatalog(locale: string) {
11+
const catalog = await import(`@lingui/loader!./locales/${locale}/messages.po`)
12+
return catalog.messages
13+
}
14+
15+
export function useLinguiInit(messages: Messages) {
16+
const router = useRouter()
17+
const locale = router.locale || router.defaultLocale!
18+
const isClient = typeof window !== 'undefined'
19+
20+
if (!isClient && locale !== i18n.locale) {
21+
// there is single instance of i18n on the server
22+
// note: on the server, we could have an instance of i18n per supported locale
23+
// to avoid calling loadAndActivate for (worst case) each request, but right now that's what we do
24+
i18n.loadAndActivate({ locale, messages })
25+
}
26+
if (isClient && !i18n.locale) {
27+
// first client render
28+
i18n.loadAndActivate({ locale, messages })
29+
}
30+
31+
useEffect(() => {
32+
const localeDidChange = locale !== i18n.locale
33+
if (localeDidChange) {
34+
i18n.loadAndActivate({ locale, messages })
35+
}
36+
}, [locale])
37+
38+
return i18n
39+
}

src/locales/en/messages.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.po

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
msgid ""
2+
msgstr ""
3+
"POT-Creation-Date: 2025-05-01 08:03-0500\n"
4+
"MIME-Version: 1.0\n"
5+
"Content-Type: text/plain; charset=utf-8\n"
6+
"Content-Transfer-Encoding: 8bit\n"
7+
"X-Generator: @lingui/cli\n"
8+
"Language: en\n"
9+
"Project-Id-Version: \n"
10+
"Report-Msgid-Bugs-To: \n"
11+
"PO-Revision-Date: \n"
12+
"Last-Translator: \n"
13+
"Language-Team: \n"
14+
"Plural-Forms: \n"
15+
16+
#: src/components/layout.js:26
17+
msgid "Check out the new blog post on DataTree!"
18+
msgstr "Check out the new blog post on DataTree!"

src/locales/es/messages.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/es/messages.mo

420 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)