From 6b80b1639a84809ceaff3afbbe1870f41085302a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85rth=E1=80=9Dur?= Date: Wed, 4 Oct 2023 02:13:03 +0400 Subject: [PATCH] fix: dictionary usage (#19) * fix: use dictionary * chore: fix typings * fix: translation issues * chore: some moves * fix: build --- README.md | 10 +++++++++- app/layout.tsx | 16 +++++++++++++--- app/page.tsx | 11 +++++++++-- components/hello-world/hello-world.stories.ts | 10 ++++++++-- components/hello-world/hello-world.tsx | 14 +++++++++++--- dictionaries/en.json | 6 ++++-- dictionaries/es.json | 6 ++++-- dictionaries/index.ts | 10 ++++++++++ i18n-config.ts | 6 ++++++ tsconfig.json | 4 +++- types/locales.ts | 1 + 11 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 dictionaries/index.ts create mode 100644 i18n-config.ts create mode 100644 types/locales.ts diff --git a/README.md b/README.md index 50910de..6d6f85d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ +# React.js Hello World (Enterprise Edition) + This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +## Currently Supported Features to be continued... + +- A/B testing +- Localization +- Server-side rendering + ## Getting Started First, run the development server: -```bash +```sh bun run dev # or pnpm dev diff --git a/app/layout.tsx b/app/layout.tsx index 8bc3f36..7dc0acd 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,23 +1,33 @@ -import './globals.css'; import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import Providers from './providers'; +import type { Locales } from '@/types/locales'; + +import './globals.css'; + +export async function generateStaticParams() { + return [{ lang: 'en' }, { lang: 'es' }]; +} const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { - title: 'React Hello World Enterprise Edition', + title: 'React Hello World | Enterprise Edition', description: 'Generated by create next app', }; export default function RootLayout({ children, + params, }: { children: React.ReactNode; + params: { + lang: Locales; + }; }) { return ( - + {children} diff --git a/app/page.tsx b/app/page.tsx index be146b8..234c12c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,14 @@ import Image from 'next/image'; import { HelloWorld } from '@/components/hello-world'; +import { Locales } from '@/types/locales'; +import { getDictionary } from '@/dictionaries/index'; -export default function Home() { +export default async function Home({ + params: { lang }, +}: { + params: { lang: Locales }; +}) { + const dict = await getDictionary(lang); return (
@@ -40,7 +47,7 @@ export default function Home() { />
- +
; -export const LoggedIn: Story = { +export const LangdEn: Story = { args: { name: 'Jane Doe', + lang: 'en', }, }; -export const LoggedOut: Story = {}; +export const LangEs: Story = { + args: { + name: 'Jane Doe', + lang: 'es', + }, +}; diff --git a/components/hello-world/hello-world.tsx b/components/hello-world/hello-world.tsx index 662dff8..27417fb 100644 --- a/components/hello-world/hello-world.tsx +++ b/components/hello-world/hello-world.tsx @@ -1,11 +1,19 @@ import Image from 'next/image'; import Earth from '@/public/earth.svg'; +import { getDictionary } from '@/dictionaries/index'; +import type { Locales } from '@/types/locales'; + import { Title } from './hello-world.css'; -import { getDictionary } from '../../app/dictionaries'; -export const HelloWorld = async ({ name = 'World' }) => { - const dict = await getDictionary('en'); +export const HelloWorld = async ({ + name, + lang = 'en', +}: { + name: string; + lang: Locales; +}) => { + const dict = await getDictionary(lang); return ( <>

diff --git a/dictionaries/en.json b/dictionaries/en.json index 8a91e98..2ba81d0 100644 --- a/dictionaries/en.json +++ b/dictionaries/en.json @@ -1,3 +1,5 @@ { - "hello": "Hola" -} \ No newline at end of file + "hello": "Hello", + "hey": "Hey", + "world": "World" +} diff --git a/dictionaries/es.json b/dictionaries/es.json index a479da3..d6c98c2 100644 --- a/dictionaries/es.json +++ b/dictionaries/es.json @@ -1,3 +1,5 @@ { - "hello": "Hello" -} \ No newline at end of file + "hello": "Hola", + "hey": "Eh", + "world": "Mundo" +} diff --git a/dictionaries/index.ts b/dictionaries/index.ts new file mode 100644 index 0000000..48a3b96 --- /dev/null +++ b/dictionaries/index.ts @@ -0,0 +1,10 @@ +import 'server-only'; +import type { Locales } from '@/types/locales'; + +const dictionaries = { + en: () => import('./en.json').then((module) => module.default), + es: () => import('./es.json').then((module) => module.default), +}; + +export const getDictionary = async (locale: Locales) => + dictionaries[locale]?.() ?? dictionaries.en(); diff --git a/i18n-config.ts b/i18n-config.ts new file mode 100644 index 0000000..46b2e75 --- /dev/null +++ b/i18n-config.ts @@ -0,0 +1,6 @@ +export const i18n = { + defaultLocale: 'en', + locales: ['en', 'es'], +} as const; + +export type Locale = (typeof i18n)['locales'][number]; diff --git a/tsconfig.json b/tsconfig.json index dc4f358..94cb2f1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,7 +31,9 @@ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ "paths": { "@/components/*": ["./components/*"], - "@/public/*": ["./public/*"] + "@/public/*": ["./public/*"], + "@/dictionaries/*": ["./dictionaries/*"], + "@/types/*": ["./types/*"] }, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ diff --git a/types/locales.ts b/types/locales.ts new file mode 100644 index 0000000..9396ab6 --- /dev/null +++ b/types/locales.ts @@ -0,0 +1 @@ +export type Locales = 'en' | 'es';