fix: Use next-intl for improved locale support

This commit is contained in:
Sol Irvine
2023-08-17 11:56:36 +09:00
parent 32bb4ffd0c
commit c1d06e90bb
42 changed files with 237 additions and 212 deletions

View File

Before

Width:  |  Height:  |  Size: 6.2 MiB

After

Width:  |  Height:  |  Size: 6.2 MiB

View File

@@ -1,11 +1,11 @@
import Navbar from 'components/layout/navbar';
import { Locale, i18n } from 'i18n-config';
import { Locale } from 'i18n-config';
import { Noto_Sans_JP } from 'next/font/google';
import localFont from 'next/font/local';
import { ReactNode, Suspense } from 'react';
import { LanguageProvider } from 'app/context/language-context';
import { getDictionary } from 'dictionaries';
import { NextIntlClientProvider } from 'next-intl';
import { notFound } from 'next/navigation';
import './globals.css';
const { TWITTER_CREATOR, TWITTER_SITE, SITE_NAME } = process.env;
@@ -69,8 +69,8 @@ const mincho = localFont({
variable: '--font-mincho'
});
export async function generateStaticParams() {
return i18n.locales.map((locale) => ({ lang: locale }));
export function generateStaticParams() {
return [{ locale: 'en' }, { locale: 'ja' }];
}
export default async function RootLayout({
@@ -78,20 +78,25 @@ export default async function RootLayout({
params
}: {
children: ReactNode;
params: { lang: Locale };
params: { locale: Locale };
}) {
const dictionary = await getDictionary(params?.lang);
let messages;
try {
messages = (await import(`../../messages/${params?.locale}.json`)).default;
} catch (error) {
notFound();
}
return (
<html lang={params.lang} className={`${cinzel.variable} ${alpina.variable} ${noto.variable}`}>
<html lang={params.locale} className={`${cinzel.variable} ${alpina.variable} ${noto.variable}`}>
<body className="bg-dark text-white selection:bg-green-800 selection:text-green-400">
<div className="mx-auto max-w-screen-2xl">
<LanguageProvider locale={params.lang as Locale} dictionary={dictionary}>
<NextIntlClientProvider locale={params?.locale} messages={messages}>
<Navbar />
<Suspense>
<main>{children}</main>
</Suspense>
</LanguageProvider>
</NextIntlClientProvider>
</div>
</body>
</html>

View File

@@ -1,8 +1,7 @@
import { Carousel } from 'components/carousel';
import { ThreeItemGrid } from 'components/grid/three-items';
import Footer from 'components/layout/footer';
import { LanguageControl } from 'components/layout/navbar/language-control';
import type { Locale } from '../../i18n-config';
import { LanguageControl, SupportedLocales } from 'components/layout/navbar/language-control';
import clsx from 'clsx';
import LogoNamemark from 'components/icons/namemark';
@@ -23,16 +22,20 @@ export const metadata = {
}
};
export default async function HomePage({ params: { lang } }: { params: { lang: Locale } }) {
export default async function HomePage({
params: { locale }
}: {
params: { locale: SupportedLocales };
}) {
return (
<>
<div className="invisible absolute right-40 top-12 md:visible">
<LanguageControl lang={lang} />
<LanguageControl lang={locale} />
</div>
<div className="px-6 pb-12 pt-6 md:pb-48 md:pl-6 md:pt-12">
<LogoNamemark className="w-[260px] fill-current md:w-[600px]" />
</div>
<ThreeItemGrid lang={lang} />
<ThreeItemGrid lang={locale} />
<div className="py-48">
<NewsletterSignup />
</div>

View File

@@ -1,44 +0,0 @@
'use client';
import { Locale } from 'i18n-config';
import { ReactNode, createContext, useContext, useState } from 'react';
interface IContextProps {
currentLocale?: Locale;
currentLanguage?: Locale;
setCurrentLanguage: (language: Locale) => void;
currentDictionary?: any;
}
export const LanguageContext = createContext<IContextProps>({} as IContextProps);
export function LanguageProvider({
locale,
dictionary,
children
}: {
locale: Locale;
dictionary?: any;
children: ReactNode | ReactNode[] | string;
}) {
const [currentLocale, setCurrentLocale] = useState<Locale>(locale || 'en');
const [currentLanguage, setCurrentLanguage] = useState<Locale>(locale || 'en');
const [currentDictionary] = useState<any | undefined>(dictionary);
return (
<LanguageContext.Provider
value={{
currentLocale,
currentLanguage,
setCurrentLanguage,
currentDictionary
}}
>
{children}
</LanguageContext.Provider>
);
}
export const useLanguage = () => {
return useContext(LanguageContext);
};