diff --git a/components/Layout/index.jsx b/components/Layout/index.jsx
index dfe472b..e473b68 100644
--- a/components/Layout/index.jsx
+++ b/components/Layout/index.jsx
@@ -7,6 +7,7 @@ import NavBar from '../Navigation';
import MetaBar from '../Metabar';
import SideBar from '../Sidebar';
import Footer from '../Footer';
+import LocaleProvider from '../../providers/LocaleProvider';
/**
* @typedef {Object} Props
@@ -20,7 +21,7 @@ import Footer from '../Footer';
* @param {Props} props
*/
export default ({ metadata, headings, readingTime, children }) => (
- <>
+
@@ -40,5 +41,5 @@ export default ({ metadata, headings, readingTime, children }) => (
- >
+
);
diff --git a/components/Navigation/index.jsx b/components/Navigation/index.jsx
index 5a3f369..f1a3253 100644
--- a/components/Navigation/index.jsx
+++ b/components/Navigation/index.jsx
@@ -2,10 +2,15 @@ import ThemeToggle from '@node-core/ui-components/Common/ThemeToggle';
import NavBar from '@node-core/ui-components/Containers/NavBar';
import styles from '@node-core/ui-components/Containers/NavBar/index.module.css';
import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub';
-
import SearchBox from '@node-core/doc-kit/src/generators/web/ui/components/SearchBox';
import { useTheme } from '@node-core/doc-kit/src/generators/web/ui/hooks/useTheme.mjs';
+
+import { useEffect, useState } from 'preact/hooks';
+import { useIntl } from 'react-intl';
+
+import { localizeLink } from '../../util/link';
import { navigation } from '../../site.json' with { type: 'json' };
+
import Logo from '#theme/Logo';
/**
@@ -13,12 +18,23 @@ import Logo from '#theme/Logo';
*/
export default ({ metadata }) => {
const [themePreference, setThemePreference] = useTheme();
+ const [navigationItems, setNavigationItems] = useState(navigation);
+ const { locale } = useIntl();
+
+ useEffect(() => {
+ const items = navigation.map(item => ({
+ ...item,
+ link: localizeLink(item.link, locale),
+ }));
+
+ setNavigationItems(items);
+ }, [locale]);
return (
{
+ if (typeof document === 'undefined') {
+ return defaultLocale;
+ }
+
+ const localeCookie = document.cookie
+ .split(';')
+ .map(cookie => cookie.trim())
+ .find(cookie => cookie.startsWith(`${LOCALE_COOKIE}=`));
+
+ if (!localeCookie) {
+ return defaultLocale;
+ }
+
+ return decodeURIComponent(localeCookie.slice(LOCALE_COOKIE.length + 1));
+};
+
+/**
+ * LocaleProvider component that provides the locale context to its children.
+ *
+ * @param {{ locale?: string, children: import('preact').ComponentChildren }} props
+ */
+export default function LocaleProvider({ locale, children }) {
+ const detectedLocale = locale ?? detectLocaleFromCookies();
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/site.json b/site.json
index 2e0e07b..fc9675a 100644
--- a/site.json
+++ b/site.json
@@ -1,11 +1,12 @@
{
+ "defaultLocale": "en",
"navigation": [
{
"link": "/learn",
"text": "Learn"
},
{
- "link": "/about",
+ "link": "/en/about",
"text": "About"
},
{
@@ -13,7 +14,7 @@
"text": "Download"
},
{
- "link": "/blog",
+ "link": "/en/blog",
"text": "Blog"
},
{
diff --git a/util/link.js b/util/link.js
new file mode 100644
index 0000000..a816759
--- /dev/null
+++ b/util/link.js
@@ -0,0 +1,26 @@
+import { defaultLocale } from '../site.json' with { type: 'json' };
+
+/**
+ * Replaces the default locale in a link with the provided locale.
+ *
+ * @param {string} link - The link to be localized.
+ * @param {string|null} locale - The locale to apply to the link.
+ * @returns {string} - The localized link.
+ */
+export const localizeLink = (link, locale) => {
+ if (
+ typeof document === 'undefined' ||
+ !link.startsWith('/') ||
+ !link.startsWith(`/${defaultLocale}`)
+ ) {
+ return link;
+ }
+
+ const localizedPrefix = locale ? `/${locale}` : '';
+ const localizedLink = link.replace(
+ `/${defaultLocale}/`,
+ `${localizedPrefix}/`
+ );
+
+ return localizedLink;
+};