diff --git a/src/app/[lang]/content/page.tsx b/src/app/[lang]/content/page.tsx
new file mode 100644
index 0000000..1d51e6f
--- /dev/null
+++ b/src/app/[lang]/content/page.tsx
@@ -0,0 +1,14 @@
+import { getDictionary } from "@/utils/dictionaries";
+
+type ContentProps = {
+ params: {
+ lang: string;
+ };
+};
+const Content = async (props: ContentProps) => {
+ const { params } = props;
+ const dict = await getDictionary(params.lang);
+ return
{dict.generic.greeting}
;
+};
+
+export default Content;
diff --git a/src/dictionaries/en.json b/src/dictionaries/en.json
new file mode 100644
index 0000000..11a7f7d
--- /dev/null
+++ b/src/dictionaries/en.json
@@ -0,0 +1,5 @@
+{
+ "generic": {
+ "greeting": "Hello!"
+ }
+}
diff --git a/src/dictionaries/es.json b/src/dictionaries/es.json
new file mode 100644
index 0000000..56ad500
--- /dev/null
+++ b/src/dictionaries/es.json
@@ -0,0 +1,5 @@
+{
+ "generic": {
+ "greeting": "¡Hola!"
+ }
+}
diff --git a/src/dictionaries/fr.json b/src/dictionaries/fr.json
new file mode 100644
index 0000000..92307b6
--- /dev/null
+++ b/src/dictionaries/fr.json
@@ -0,0 +1,5 @@
+{
+ "generic": {
+ "greeting": "Salut!"
+ }
+}
diff --git a/src/middleware.ts b/src/middleware.ts
new file mode 100644
index 0000000..45ef5f6
--- /dev/null
+++ b/src/middleware.ts
@@ -0,0 +1,32 @@
+import { NextRequest, NextResponse } from "next/server";
+
+export const locales = ["es", "en", "fr"];
+
+// Get the preferred locale, similar to the above or using a library
+function getLocale() {
+ return locales[0];
+}
+
+export function middleware(request: NextRequest) {
+ // Check if there is any supported locale in the pathname
+ const { pathname } = request.nextUrl;
+ const pathnameHasLocale = locales.some(
+ (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`,
+ );
+
+ console.log(pathname);
+ if (pathname === "/") return;
+ if (pathnameHasLocale) return;
+
+ // Redirect if there is no locale
+ const locale = getLocale();
+ request.nextUrl.pathname = `/${locale}${pathname}`;
+ return NextResponse.redirect(request.nextUrl);
+}
+
+export const config = {
+ matcher: [
+ // Skip all internal paths (_next)
+ "/((?!_next).*)",
+ ],
+};
diff --git a/src/types/locales.ts b/src/types/locales.ts
new file mode 100644
index 0000000..7151f2d
--- /dev/null
+++ b/src/types/locales.ts
@@ -0,0 +1,3 @@
+import { locales } from "@/middleware";
+
+export type Locale = (typeof locales)[number];
diff --git a/src/utils/dictionaries.ts b/src/utils/dictionaries.ts
new file mode 100644
index 0000000..93c1bb1
--- /dev/null
+++ b/src/utils/dictionaries.ts
@@ -0,0 +1,17 @@
+import { Locale } from "@/types/locales";
+import "server-only";
+
+type DictionariesType = {
+ [key: Locale]: Function;
+};
+
+import dict from "@/dictionaries/en.json";
+
+const dictionaries: DictionariesType = {
+ en: () => import("@/dictionaries/en.json").then((module) => module.default),
+ es: () => import("@/dictionaries/es.json").then((module) => module.default),
+ fr: () => import("@/dictionaries/fr.json").then((module) => module.default),
+};
+
+export const getDictionary = async (locale: Locale): Promise =>
+ dictionaries[locale]();