diff --git a/components/i18n-provider.tsx b/components/i18n-provider.tsx
new file mode 100644
index 0000000..cefac11
--- /dev/null
+++ b/components/i18n-provider.tsx
@@ -0,0 +1,64 @@
+'use client';
+
+import React, { createContext, useContext, useState, useEffect } from 'react';
+import en from '../messages/en.json';
+import es from '../messages/es.json';
+import pt from '../messages/pt.json';
+import zh from '../messages/zh.json';
+import fr from '../messages/fr.json';
+import de from '../messages/de.json';
+import hi from '../messages/hi.json';
+import tr from '../messages/tr.json';
+
+const translations = { en, es, pt, zh, fr, de, hi, tr };
+
+type Language = 'en' | 'es' | 'pt' | 'zh' | 'fr' | 'de' | 'hi' | 'tr';
+type Translations = typeof en;
+
+interface I18nContextProps {
+ locale: Language;
+ setLocale: (locale: Language) => void;
+ t: (key: string) => any;
+}
+
+const I18nContext = createContext
(undefined);
+
+export const I18nProvider = ({ children }: { children: React.ReactNode }) => {
+ const [locale, setLocaleState] = useState('en');
+
+ useEffect(() => {
+ const savedLocale = localStorage.getItem('locale') as Language;
+ if (savedLocale && translations[savedLocale]) {
+ setLocaleState(savedLocale);
+ }
+ }, []);
+
+ const setLocale = (newLocale: Language) => {
+ setLocaleState(newLocale);
+ localStorage.setItem('locale', newLocale);
+ };
+
+ const t = (path: string) => {
+ const keys = path.split('.');
+ let current: any = translations[locale];
+ for (const key of keys) {
+ if (current[key] === undefined) return path;
+ current = current[key];
+ }
+ return current;
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useI18n = () => {
+ const context = useContext(I18nContext);
+ if (!context) {
+ throw new Error('useI18n must be used within an I18nProvider');
+ }
+ return context;
+};
diff --git a/components/main-nav.tsx b/components/main-nav.tsx
index 1410091..55f7aae 100644
--- a/components/main-nav.tsx
+++ b/components/main-nav.tsx
@@ -5,9 +5,11 @@ import { usePathname } from 'next/navigation';
import { cn } from '@/lib/utils';
import { Icons } from './icon';
+import { useI18n } from './i18n-provider';
export function MainNav() {
const pathname = usePathname();
+ const { t } = useI18n();
return (
@@ -26,7 +28,7 @@ export function MainNav() {
pathname === '/docs/installation' ? 'text-foreground' : 'text-foreground/80',
)}
>
- Components
+ {t('Navbar.components')}
- Templates
+ {t('Navbar.templates')}
Pro
@@ -47,13 +49,13 @@ export function MainNav() {
pathname?.startsWith('/blocks') ? 'text-foreground' : 'text-foreground/80',
)}
>
- Blocks
+ {t('Navbar.blocks')}
- Blogs
+ {t('Navbar.blogs')}
diff --git a/components/navbar.tsx b/components/navbar.tsx
index 75d194e..9c88c19 100644
--- a/components/navbar.tsx
+++ b/components/navbar.tsx
@@ -5,6 +5,7 @@ import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Icons } from '@/components/icon';
import { MobileNav } from '@/components/mobile-nav';
+import { useI18n } from './i18n-provider';
import { MainNav } from './main-nav';
import { ThemeToggle } from './theme-toggle';
import { UserNav } from './user-nav';
@@ -13,6 +14,7 @@ import type { Session } from 'next-auth';
export function SiteHeader({ session }: { session: Session | null }) {
const pathname = usePathname();
+ const { t } = useI18n();
return (
@@ -42,7 +44,7 @@ export function SiteHeader({ session }: { session: Session | null }) {
>
-
Sponsor
+
{t('Navbar.sponsor')}
{/*
@@ -72,7 +74,7 @@ export function SiteHeader({ session }: { session: Session | null }) {
) : (
)}
diff --git a/components/providers.tsx b/components/providers.tsx
index 0aaccb0..68f635f 100644
--- a/components/providers.tsx
+++ b/components/providers.tsx
@@ -3,18 +3,21 @@
import { SessionProvider } from "next-auth/react";
import { ThemeProvider } from "@/components/theme-provider";
import { PostHogProvider } from "@/components/provider";
+import { I18nProvider } from "@/components/i18n-provider";
export function Providers({ children }: { children: React.ReactNode }) {
return (
-
-
- {children}
-
-
+
+
+
+ {children}
+
+
+
);
}
diff --git a/messages/de.json b/messages/de.json
new file mode 100644
index 0000000..495e2b3
--- /dev/null
+++ b/messages/de.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Startseite",
+ "components": "Komponenten",
+ "templates": "Vorlagen",
+ "blocks": "Blöcke",
+ "blogs": "Blogs",
+ "signIn": "Anmelden",
+ "sponsor": "Sponsoren"
+ },
+ "Footer": {
+ "builtBy": "Erstellt von",
+ "rights": "Alle Rechte vorbehalten.",
+ "pages": "Seiten",
+ "socials": "Soziale Medien",
+ "legal": "Rechtliches",
+ "docs": "Dokumentation",
+ "colors": "Farben",
+ "privacy": "Datenschutz",
+ "tos": "Nutzungsbedingungen",
+ "faqs": "FAQs",
+ "language": "Sprache"
+ },
+ "HomePage": {
+ "heroTitle1": "Sofortige UI-Komponenten",
+ "heroTitle2": "Kopieren, Einfügen, Fertig",
+ "heroDescription": "Über 250 produktionsbereite Komponenten, erstellt mit Next.js, shadcn/ui und Tailwind CSS.",
+ "explore": "Komponenten erkunden",
+ "starGithub": "Star auf GitHub",
+ "builtWith": "Erstellt mit",
+ "readyToUse": "Sofort einsatzbereite UI-Blöcke"
+ },
+ "CTA": {
+ "title1": "Hören Sie auf, von Grund auf neu zu bauen.",
+ "title2": "Schneller veröffentlichen mit ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Premium Next.js-Vorlagen, basierend auf Spectrum UI. Dunkel. Animiert. Produktionsfertig. Ab 49 $.",
+ "button": "Zugang anfordern"
+ }
+}
diff --git a/messages/en.json b/messages/en.json
new file mode 100644
index 0000000..fd18a30
--- /dev/null
+++ b/messages/en.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Home",
+ "components": "Components",
+ "templates": "Templates",
+ "blocks": "Blocks",
+ "blogs": "Blogs",
+ "signIn": "Sign In",
+ "sponsor": "Sponsor"
+ },
+ "Footer": {
+ "builtBy": "Built by",
+ "rights": "All rights reserved.",
+ "pages": "Pages",
+ "socials": "Socials",
+ "legal": "Legal",
+ "docs": "Docs",
+ "colors": "Colors",
+ "privacy": "Privacy Policy",
+ "tos": "Terms of Service",
+ "faqs": "FAQs",
+ "language": "Language"
+ },
+ "HomePage": {
+ "heroTitle1": "Instant UI Components",
+ "heroTitle2": "Just Copy, Paste & Done",
+ "heroDescription": "250+ Production ready components, built with Next.js, shadcn/ui and Tailwind CSS.",
+ "explore": "Explore Components",
+ "starGithub": "Star on GitHub",
+ "builtWith": "Built With",
+ "readyToUse": "Ready-to-Use UI Blocks"
+ },
+ "CTA": {
+ "title1": "Stop building from scratch",
+ "title2": "Ship fast with ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Premium Next.js templates built on Spectrum UI. Dark. Animated. Production-ready. From $49.",
+ "button": "Get access"
+ }
+}
diff --git a/messages/es.json b/messages/es.json
new file mode 100644
index 0000000..e4b264f
--- /dev/null
+++ b/messages/es.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Inicio",
+ "components": "Componentes",
+ "templates": "Plantillas",
+ "blocks": "Bloques",
+ "blogs": "Blogs",
+ "signIn": "Iniciar sesión",
+ "sponsor": "Patrocinar"
+ },
+ "Footer": {
+ "builtBy": "Creado por",
+ "rights": "Todos los derechos reservados.",
+ "pages": "Páginas",
+ "socials": "Redes Sociales",
+ "legal": "Legal",
+ "docs": "Docs",
+ "colors": "Colores",
+ "privacy": "Política de Privacidad",
+ "tos": "Términos de Servicio",
+ "faqs": "Preguntas frecuentes",
+ "language": "Idioma"
+ },
+ "HomePage": {
+ "heroTitle1": "Componentes de UI Instantáneos",
+ "heroTitle2": "Solo Copiar, Pegar y Listo",
+ "heroDescription": "Más de 250 componentes listos para producción, creados con Next.js, shadcn/ui y Tailwind CSS.",
+ "explore": "Explorar Componentes",
+ "starGithub": "Estrella en GitHub",
+ "builtWith": "Desarrollado con",
+ "readyToUse": "Bloques de UI listos para usar"
+ },
+ "CTA": {
+ "title1": "Deja de construir desde cero.",
+ "title2": "Envía rápido con ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Plantillas premium de Next.js creadas en Spectrum UI. Oscuras. Animadas. Listas para producción. Desde $49.",
+ "button": "Obtener acceso"
+ }
+}
diff --git a/messages/fr.json b/messages/fr.json
new file mode 100644
index 0000000..5cc26c1
--- /dev/null
+++ b/messages/fr.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Accueil",
+ "components": "Composants",
+ "templates": "Modèles",
+ "blocks": "Blocs",
+ "blogs": "Blogs",
+ "signIn": "Se connecter",
+ "sponsor": "Sponsoriser"
+ },
+ "Footer": {
+ "builtBy": "Créé par",
+ "rights": "Tous droits réservés.",
+ "pages": "Pages",
+ "socials": "Réseaux Sociaux",
+ "legal": "Légal",
+ "docs": "Docs",
+ "colors": "Couleurs",
+ "privacy": "Politique de Confidentialité",
+ "tos": "Conditions d'Utilisation",
+ "faqs": "FAQ",
+ "language": "Langue"
+ },
+ "HomePage": {
+ "heroTitle1": "Composants UI Instantanés",
+ "heroTitle2": "Copiez, Collez, C'est Fait",
+ "heroDescription": "Plus de 250 composants prêts pour la production, créés avec Next.js, shadcn/ui et Tailwind CSS.",
+ "explore": "Explorer les Composants",
+ "starGithub": "Star sur GitHub",
+ "builtWith": "Développé avec",
+ "readyToUse": "Blocs UI prêts à l'emploi"
+ },
+ "CTA": {
+ "title1": "Arrêtez de construire à partir de zéro.",
+ "title2": "Expédiez rapidement avec ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Modèles premium Next.js construits sur Spectrum UI. Sombre. Animé. Prêt pour la production. À partir de 49 $.",
+ "button": "Obtenir l'accès"
+ }
+}
diff --git a/messages/hi.json b/messages/hi.json
new file mode 100644
index 0000000..699caf3
--- /dev/null
+++ b/messages/hi.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "होम",
+ "components": "कंपोनेंट्स",
+ "templates": "टेम्प्लेट्स",
+ "blocks": "ब्लॉक्स",
+ "blogs": "ब्लॉग्स",
+ "signIn": "लॉग इन",
+ "sponsor": "स्पॉन्सर"
+ },
+ "Footer": {
+ "builtBy": "द्वारा निर्मित",
+ "rights": "सर्वाधिकार सुरक्षित।",
+ "pages": "पेज",
+ "socials": "सोशल",
+ "legal": "कानूनी",
+ "docs": "डॉक्युमेंटेशन",
+ "colors": "रंग",
+ "privacy": "गोपनीयता नीति",
+ "tos": "सेवा की शर्तें",
+ "faqs": "अक्सर पूछे जाने वाले सवाल",
+ "language": "भाषा"
+ },
+ "HomePage": {
+ "heroTitle1": "इंस्टेंट यूआई कंपोनेंट्स",
+ "heroTitle2": "बस कॉपी, पेस्ट और हो गया",
+ "heroDescription": "Next.js, shadcn/ui और Tailwind CSS के साथ निर्मित 250+ प्रोडक्शन रेडी कंपोनेंट्स।",
+ "explore": "यूआई कंपोनेंट्स देखें",
+ "starGithub": "गिटहब पर स्टार दें",
+ "builtWith": "के साथ निर्मित",
+ "readyToUse": "उपयोग के लिए तैयार यूआई ब्लॉक्स"
+ },
+ "CTA": {
+ "title1": "शुरुआत से बनाना बंद करें।",
+ "title2": "तेजी से शिप करें ",
+ "title2Pro": "स्पेक्ट्रम प्रो के साथ",
+ "description": "स्पेक्ट्रम यूआई पर निर्मित प्रीमियम नेक्स्ट.जीएस टेम्प्लेट्स। डार्क। एनिमेटेड। प्रोडक्शन-रेडी। $49 से शुरू।",
+ "button": "एक्सेस प्राप्त करें"
+ }
+}
diff --git a/messages/pt.json b/messages/pt.json
new file mode 100644
index 0000000..e1e83bc
--- /dev/null
+++ b/messages/pt.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Início",
+ "components": "Componentes",
+ "templates": "Modelos",
+ "blocks": "Blocos",
+ "blogs": "Blogs",
+ "signIn": "Entrar",
+ "sponsor": "Patrocinar"
+ },
+ "Footer": {
+ "builtBy": "Criado por",
+ "rights": "Todos os direitos reservados.",
+ "pages": "Páginas",
+ "socials": "Redes Sociais",
+ "legal": "Legal",
+ "docs": "Docs",
+ "colors": "Cores",
+ "privacy": "Política de Privacidade",
+ "tos": "Termos de Serviço",
+ "faqs": "Perguntas Frequentes",
+ "language": "Idioma"
+ },
+ "HomePage": {
+ "heroTitle1": "Componentes de UI Instantâneos",
+ "heroTitle2": "Basta Copiar, Colar e Pronto",
+ "heroDescription": "Mais de 250 componentes prontos para produção, criados com Next.js, shadcn/ui e Tailwind CSS.",
+ "explore": "Explorar Componentes",
+ "starGithub": "Estrela no GitHub",
+ "builtWith": "Desenvolvido com",
+ "readyToUse": "Blocos de UI prontos para usar"
+ },
+ "CTA": {
+ "title1": "Pare de construir do zero.",
+ "title2": "Envie rápido com ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Modelos premium Next.js criados no Spectrum UI. Escuro. Animado. Pronto para produção. A partir de $49.",
+ "button": "Obter acesso"
+ }
+}
diff --git a/messages/tr.json b/messages/tr.json
new file mode 100644
index 0000000..89ad1b6
--- /dev/null
+++ b/messages/tr.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "Ana Sayfa",
+ "components": "Bileşenler",
+ "templates": "Şablonlar",
+ "blocks": "Bloklar",
+ "blogs": "Bloglar",
+ "signIn": "Giriş Yap",
+ "sponsor": "Sponsor Ol"
+ },
+ "Footer": {
+ "builtBy": "Geliştiren",
+ "rights": "Tüm hakları saklıdır.",
+ "pages": "Sayfalar",
+ "socials": "Sosyal Medya",
+ "legal": "Yasal",
+ "docs": "Belgeler",
+ "colors": "Renkler",
+ "privacy": "Gizlilik Politikası",
+ "tos": "Hizmet Şartları",
+ "faqs": "SSS",
+ "language": "Dil"
+ },
+ "HomePage": {
+ "heroTitle1": "Anında UI Bileşenleri",
+ "heroTitle2": "Kopyala, Yapıştır ve Bitti",
+ "heroDescription": "Next.js, shadcn/ui ve Tailwind CSS ile oluşturulmuş 250+ üretime hazır bileşen.",
+ "explore": "Bileşenleri Keşfet",
+ "starGithub": "GitHub'da Yıldızla",
+ "builtWith": "ile Oluşturuldu",
+ "readyToUse": "Kullanıma Hazır UI Blokları"
+ },
+ "CTA": {
+ "title1": "Sıfırdan inşa etmeyi bırakın.",
+ "title2": "Hızlıca yayına alın: ",
+ "title2Pro": "Spectrum Pro",
+ "description": "Spectrum UI üzerine inşa edilmiş Premium Next.js şablonları. Karanlık. Animasyonlu. Üretime hazır. 49 dolardan başlayan fiyatlarla.",
+ "button": "Erişim sağla"
+ }
+}
diff --git a/messages/zh.json b/messages/zh.json
new file mode 100644
index 0000000..3f99d31
--- /dev/null
+++ b/messages/zh.json
@@ -0,0 +1,40 @@
+{
+ "Navbar": {
+ "home": "首页",
+ "components": "组件",
+ "templates": "模板",
+ "blocks": "区块",
+ "blogs": "博客",
+ "signIn": "登录",
+ "sponsor": "赞助"
+ },
+ "Footer": {
+ "builtBy": "由...创建",
+ "rights": "保留所有权利。",
+ "pages": "页面",
+ "socials": "社交媒体",
+ "legal": "法律信息",
+ "docs": "文档",
+ "colors": "颜色",
+ "privacy": "隐私政策",
+ "tos": "服务条款",
+ "faqs": "常见问题",
+ "language": "语言"
+ },
+ "HomePage": {
+ "heroTitle1": "即时 UI 组件",
+ "heroTitle2": "只需复制、粘贴,即可完成",
+ "heroDescription": "250多个生产级组件,基于 Next.js、shadcn/ui 和 Tailwind CSS 构建。",
+ "explore": "探索组件",
+ "starGithub": "GitHub 点星",
+ "builtWith": "构建环境",
+ "readyToUse": "开箱即用的 UI 区块"
+ },
+ "CTA": {
+ "title1": "停止从零开始构建。",
+ "title2": "快速发布,尽在 ",
+ "title2Pro": "Spectrum Pro",
+ "description": "基于 Spectrum UI 构建的高级 Next.js 模板。深色模式、动态效果、生产就绪。起售价仅为 49 美元。",
+ "button": "获取访问权限"
+ }
+}