From ee9f3df9e281432d4e6095dbf3fe45d6bdc07ede Mon Sep 17 00:00:00 2001 From: cesalberca Date: Tue, 16 Jul 2024 16:59:51 +0200 Subject: [PATCH] Add i18n --- global.d.ts | 2 +- next.config.mjs | 6 +++++- src/app/[locale]/page.tsx | 6 ++++++ src/app/layout.tsx | 10 +++++----- src/app/locale/layout.tsx | 21 +++++++++++++++++++++ src/app/middleware/middleware.ts | 14 ++++++++++++++ src/core/i18n/i18n.ts | 14 ++++++++++++++ src/core/i18n/{ => translations}/en.json | 0 src/core/i18n/{ => translations}/es.json | 0 9 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/app/[locale]/page.tsx create mode 100644 src/app/locale/layout.tsx create mode 100644 src/app/middleware/middleware.ts create mode 100644 src/core/i18n/i18n.ts rename src/core/i18n/{ => translations}/en.json (100%) rename src/core/i18n/{ => translations}/es.json (100%) diff --git a/global.d.ts b/global.d.ts index 4c9283a..a6635a1 100644 --- a/global.d.ts +++ b/global.d.ts @@ -1,4 +1,4 @@ -type Messages = typeof import('./src/core/i18n/en.json') +type Messages = typeof import('./src/core/i18n/translations/en.json') declare interface IntlMessages extends Messages {} declare module '*.svg' { diff --git a/next.config.mjs b/next.config.mjs index e312bfd..a8b4455 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,3 +1,7 @@ +import createNextIntlPlugin from 'next-intl/plugin' + +const withNextIntl = createNextIntlPlugin('./src/core/i18n/i18n.ts') + /** @type {import('next').NextConfig} */ const nextConfig = { async redirects() { @@ -11,4 +15,4 @@ const nextConfig = { }, } -export default nextConfig +export default withNextIntl(nextConfig) diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx new file mode 100644 index 0000000..4dd78c2 --- /dev/null +++ b/src/app/[locale]/page.tsx @@ -0,0 +1,6 @@ +import { useTranslations } from 'next-intl' + +export default function Index() { + const t = useTranslations('common') + return

{t('coverage')}

+} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 177837d..3a5b814 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,15 +13,15 @@ const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { metadataBase: new URL(baseUrl), title: { - default: 'Next.js Portfolio Starter', - template: '%s | Next.js Portfolio Starter', + default: 'César Alberca', + template: '%s | Blog', }, description: 'This is my portfolio.', openGraph: { - title: 'My Portfolio', - description: 'This is my portfolio.', + title: 'My blog', + description: 'César Alberca blog.', url: baseUrl, - siteName: 'My Portfolio', + siteName: 'cesalberca', locale: 'en_US', type: 'website', }, diff --git a/src/app/locale/layout.tsx b/src/app/locale/layout.tsx new file mode 100644 index 0000000..b234124 --- /dev/null +++ b/src/app/locale/layout.tsx @@ -0,0 +1,21 @@ +import { NextIntlClientProvider } from 'next-intl' +import { getMessages } from 'next-intl/server' +import type { ReactNode } from 'react' + +export default async function LocaleLayout({ + children, + params: { locale }, +}: { + children: ReactNode + params: { locale: string } +}) { + const messages = await getMessages() + + return ( + + + {children} + + + ) +} diff --git a/src/app/middleware/middleware.ts b/src/app/middleware/middleware.ts new file mode 100644 index 0000000..cc4be13 --- /dev/null +++ b/src/app/middleware/middleware.ts @@ -0,0 +1,14 @@ +import createMiddleware from 'next-intl/middleware' + +export default createMiddleware({ + // A list of all locales that are supported + locales: ['en', 'de'], + + // Used when no locale matches + defaultLocale: 'en', +}) + +export const config = { + // Match only internationalized pathnames + matcher: ['/', '/(en|es)/:path*'], +} diff --git a/src/core/i18n/i18n.ts b/src/core/i18n/i18n.ts new file mode 100644 index 0000000..56a5648 --- /dev/null +++ b/src/core/i18n/i18n.ts @@ -0,0 +1,14 @@ +import { notFound } from 'next/navigation' +import { getRequestConfig } from 'next-intl/server' + +// Can be imported from a shared config +const locales = ['en', 'es'] + +export default getRequestConfig(async ({ locale }) => { + // Validate that the incoming `locale` parameter is valid + if (!locales.includes(locale as any)) notFound() + + return { + messages: (await import(`../translations/${locale}.json`)).default, + } +}) diff --git a/src/core/i18n/en.json b/src/core/i18n/translations/en.json similarity index 100% rename from src/core/i18n/en.json rename to src/core/i18n/translations/en.json diff --git a/src/core/i18n/es.json b/src/core/i18n/translations/es.json similarity index 100% rename from src/core/i18n/es.json rename to src/core/i18n/translations/es.json