Skip to content

Commit 2c817f8

Browse files
committed
refactor: react-intl provider added
1 parent 9c26580 commit 2c817f8

8 files changed

Lines changed: 155 additions & 93 deletions

File tree

components/Layout/index.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import NavBar from '../Navigation';
77
import MetaBar from '../Metabar';
88
import SideBar from '../Sidebar';
99
import Footer from '../Footer';
10+
import LocaleProvider from '../../providers/LocaleProvider';
1011

1112
/**
1213
* @typedef {Object} Props
@@ -20,7 +21,7 @@ import Footer from '../Footer';
2021
* @param {Props} props
2122
*/
2223
export default ({ metadata, headings, readingTime, children }) => (
23-
<>
24+
<LocaleProvider>
2425
<Analytics basePath="/learn/_vercel" />
2526
<SpeedInsights basePath="/learn/_vercel" />
2627
<NavBar metadata={metadata} />
@@ -40,5 +41,5 @@ export default ({ metadata, headings, readingTime, children }) => (
4041
</div>
4142
</Article>
4243
<Footer metadata={metadata} />
43-
</>
44+
</LocaleProvider>
4445
);

components/Navigation/index.jsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,39 @@ import ThemeToggle from '@node-core/ui-components/Common/ThemeToggle';
22
import NavBar from '@node-core/ui-components/Containers/NavBar';
33
import styles from '@node-core/ui-components/Containers/NavBar/index.module.css';
44
import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
5-
65
import SearchBox from '@node-core/doc-kit/src/generators/web/ui/components/SearchBox';
76
import { useTheme } from '@node-core/doc-kit/src/generators/web/ui/hooks/useTheme.mjs';
7+
8+
import { useEffect, useState } from 'preact/hooks';
9+
import { useIntl } from 'react-intl';
10+
11+
import localizeLink from '../../util/link';
812
import { navigation } from '../../site.json' with { type: 'json' };
13+
914
import Logo from '#theme/Logo';
10-
import useLocalizedLink from '../../hooks/useLocalizedLink';
1115

1216
/**
1317
* NavBar component that displays the headings, search, etc.
1418
*/
1519
export default ({ metadata }) => {
1620
const [themePreference, setThemePreference] = useTheme();
17-
const getLocalizedLink = useLocalizedLink();
18-
const navItems = navigation.map((item) => ({
19-
...item,
20-
link: getLocalizedLink(item.link),
21-
}));
21+
const [navigationItems, setNavigationItems] = useState(navigation);
22+
const { locale } = useIntl();
23+
24+
useEffect(() => {
25+
const items = navigation.map(item => ({
26+
...item,
27+
link: localizeLink(item.link, locale),
28+
}));
29+
30+
setNavigationItems(items);
31+
}, [locale]);
2232

2333
return (
2434
<NavBar
2535
Logo={Logo}
2636
sidebarItemTogglerAriaLabel="Toggle navigation menu"
27-
navItems={navItems}
37+
navItems={navigationItems}
2838
>
2939
<SearchBox pathname={metadata.path} />
3040
<ThemeToggle

hooks/useLocalizedLink.jsx

Lines changed: 0 additions & 79 deletions
This file was deleted.

package-lock.json

Lines changed: 59 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"dependencies": {
2424
"@node-core/ui-components": "^1.6.3",
2525
"@vercel/analytics": "^2.0.1",
26-
"@vercel/speed-insights": "^2.0.0"
26+
"@vercel/speed-insights": "^2.0.0",
27+
"react-intl": "^10.1.2"
2728
},
2829
"engines": {
2930
"node": "24.x"

providers/LocaleProvider.jsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { IntlProvider } from 'react-intl';
2+
3+
import { defaultLocale } from '../site.json' with { type: 'json' };
4+
5+
const LOCALE_COOKIE = 'NEXT_LOCALE';
6+
7+
/**
8+
* Detects the locale from the cookie.
9+
* Falls back to the default locale when the cookie is missing.
10+
*
11+
* @returns {string}
12+
*/
13+
export const detectLocaleFromCookies = () => {
14+
if (typeof document === 'undefined') {
15+
return defaultLocale;
16+
}
17+
18+
const localeCookie = document.cookie
19+
.split(';')
20+
.map(cookie => cookie.trim())
21+
.find(cookie => cookie.startsWith(`${LOCALE_COOKIE}=`));
22+
23+
if (!localeCookie) {
24+
return defaultLocale;
25+
}
26+
27+
return decodeURIComponent(localeCookie.slice(LOCALE_COOKIE.length + 1));
28+
};
29+
30+
/**
31+
* LocaleProvider component that provides the locale context to its children.
32+
*
33+
* @param {{ locale?: string, children: import('preact').ComponentChildren }} props
34+
*/
35+
export default function LocaleProvider({ locale, children }) {
36+
const detectedLocale = locale ?? detectLocaleFromCookies();
37+
38+
return (
39+
<IntlProvider locale={detectedLocale} messages={{}}>
40+
{children}
41+
</IntlProvider>
42+
);
43+
}

site.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
"text": "Learn"
77
},
88
{
9-
"link": "/about",
9+
"link": "/en/about",
1010
"text": "About"
1111
},
1212
{
1313
"link": "/en/download",
1414
"text": "Download"
1515
},
1616
{
17-
"link": "/blog",
17+
"link": "/en/blog",
1818
"text": "Blog"
1919
},
2020
{

util/link.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { defaultLocale } from '../site.json' with { type: 'json' };
2+
3+
/**
4+
* Replaces the default locale in a link with the provided locale.
5+
*
6+
* @param {string} link - The link to be localized.
7+
* @param {string|null} locale - The locale to apply to the link.
8+
* @returns {string} - The localized link.
9+
*/
10+
const localizeLink = (link, locale) => {
11+
if (
12+
typeof document === 'undefined' ||
13+
!link.startsWith('/') ||
14+
!link.startsWith(`/${defaultLocale}`)
15+
) {
16+
return link;
17+
}
18+
19+
const localizedPrefix = locale ? `/${locale}` : '';
20+
const localizedLink = link.replace(
21+
`/${defaultLocale}/`,
22+
`${localizedPrefix}/`
23+
);
24+
25+
return localizedLink;
26+
};
27+
28+
export default { localizeLink };

0 commit comments

Comments
 (0)