From 27aadd32c4f660abf16aefc8a3e8e43c3922720e Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 9 Mar 2026 18:55:11 -0300 Subject: [PATCH] feat: integrate i18next for internationalization across components - Added translation support to FeaturesSection, Footer, HeroSection, Navbar, and SupportedBySection components. - Refactored static text to use translation keys from JSON files for English and Spanish languages. - Created new locale files for community, contact, download, features, footer, hero, navbar, and supportedBy sections in both English and Spanish. - Implemented a language switcher in the Navbar for dynamic language changes. - Updated package.json to include i18next and react-i18next dependencies. --- app/i18n.ts | 56 +++++++++ app/page.tsx | 3 + components/community-section.tsx | 39 +++--- components/contact-section.tsx | 26 ++-- components/download-section.tsx | 70 +++++++---- components/features-section.tsx | 83 ++++++------- components/footer.tsx | 163 ++++++++++++++----------- components/hero-section.tsx | 22 ++-- components/navbar.tsx | 178 ++++++++++++++++++---------- components/supported-by-section.tsx | 7 +- package.json | 3 + public/locales/en/community.json | 18 +++ public/locales/en/contact.json | 18 +++ public/locales/en/download.json | 25 ++++ public/locales/en/features.json | 26 ++++ public/locales/en/footer.json | 29 +++++ public/locales/en/hero.json | 7 ++ public/locales/en/navbar.json | 8 ++ public/locales/en/supportedBy.json | 4 + public/locales/es/community.json | 18 +++ public/locales/es/contact.json | 18 +++ public/locales/es/download.json | 25 ++++ public/locales/es/features.json | 26 ++++ public/locales/es/footer.json | 29 +++++ public/locales/es/hero.json | 7 ++ public/locales/es/navbar.json | 8 ++ public/locales/es/supportedBy.json | 4 + 27 files changed, 691 insertions(+), 229 deletions(-) create mode 100644 app/i18n.ts create mode 100644 public/locales/en/community.json create mode 100644 public/locales/en/contact.json create mode 100644 public/locales/en/download.json create mode 100644 public/locales/en/features.json create mode 100644 public/locales/en/footer.json create mode 100644 public/locales/en/hero.json create mode 100644 public/locales/en/navbar.json create mode 100644 public/locales/en/supportedBy.json create mode 100644 public/locales/es/community.json create mode 100644 public/locales/es/contact.json create mode 100644 public/locales/es/download.json create mode 100644 public/locales/es/features.json create mode 100644 public/locales/es/footer.json create mode 100644 public/locales/es/hero.json create mode 100644 public/locales/es/navbar.json create mode 100644 public/locales/es/supportedBy.json diff --git a/app/i18n.ts b/app/i18n.ts new file mode 100644 index 0000000..b29c6e2 --- /dev/null +++ b/app/i18n.ts @@ -0,0 +1,56 @@ +import i18n from "i18next"; +import LanguageDetector from "i18next-browser-languagedetector"; +import { initReactI18next } from "react-i18next"; +import supportedByEN from "../public/locales/en/supportedBy.json"; +import supportedByES from "../public/locales/es/supportedBy.json"; +import navbarEN from "../public/locales/en/navbar.json"; +import navbarES from "../public/locales/es/navbar.json"; +import heroEN from "../public/locales/en/hero.json"; +import heroES from "../public/locales/es/hero.json"; +import featuresEN from "../public/locales/en/features.json"; +import featuresES from "../public/locales/es/features.json"; +import downloadEN from "../public/locales/en/download.json"; +import downloadES from "../public/locales/es/download.json"; +import communityEN from "../public/locales/en/community.json"; +import communityES from "../public/locales/es/community.json"; +import contactEN from "../public/locales/en/contact.json"; +import contactES from "../public/locales/es/contact.json"; +import footerEN from "../public/locales/en/footer.json"; +import footerES from "../public/locales/es/footer.json"; + + +i18n + .use(initReactI18next) + .use(LanguageDetector) + .init({ + resources: { + en: { + navbar: navbarEN, + hero: heroEN, + supportedBy: supportedByEN, + features: featuresEN, + download: downloadEN, + community: communityEN, + contact: contactEN, + footer: footerEN, + }, + es: { + navbar: navbarES, + hero: heroES, + supportedBy: supportedByES, + features: featuresES, + download: downloadES, + community: communityES, + contact: contactES, + footer: footerES, + } + }, + supportedLngs: ["en", "es"], + fallbackLng: "en", + + interpolation: { + escapeValue: false + } + }); + +export default i18n; \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index 805f9f3..a276797 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,3 +1,5 @@ +"use client" + import { Navbar } from "@/components/navbar" import { HeroSection } from "@/components/hero-section" import { FeaturesSection } from "@/components/features-section" @@ -7,6 +9,7 @@ import { SupportedBySection } from "@/components/supported-by-section" import { CommunitySection } from "@/components/community-section" import { ContactSection } from "@/components/contact-section" import { Footer } from "@/components/footer" +import "./i18n" export default function Home() { return ( diff --git a/components/community-section.tsx b/components/community-section.tsx index 2f3c559..304ae2f 100644 --- a/components/community-section.tsx +++ b/components/community-section.tsx @@ -1,15 +1,16 @@ "use client" -import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Github, BookOpen, Code2, Package } from "lucide-react" import { siteConfig } from "@/lib/config" +import { useTranslation } from "react-i18next" const communityLinks = [ { icon: Github, - title: "GitHub", - description: "Explore the source code", + key: "github", + defaultTitle: "GitHub", + defaultDescription: "Explore the source code", link: siteConfig.github.url, // stats: "2.5k stars", }, @@ -22,41 +23,51 @@ const communityLinks = [ // }, { icon: BookOpen, - title: "Docs", - description: "Visit the technical documentation", + key: "docs", + defaultTitle: "Docs", + defaultDescription: "Visit the technical documentation", link: siteConfig.docs.url, // stats: "Complete guides", }, { icon: Code2, - title: "Contribute", - description: "Improve the project", + key: "contribute", + defaultTitle: "Contribute", + defaultDescription: "Improve the project", link: siteConfig.github.contribute, // stats: "Open to all", }, ] export function CommunitySection() { + const { t } = useTranslation() return (

- {"Built and extended by the community"} + {t("community:title", { defaultValue: "Built and extended by the community" })}

- { - "DashAI's plugin architecture enables anyone to contribute new capabilities. Build plugins, improve the core, and shape the future of open source AI tools." - } + {t("community:description", { + defaultValue: + "DashAI's plugin architecture enables anyone to contribute new capabilities. Build plugins, improve the core, and shape the future of open source AI tools.", + })}

{communityLinks.map((item, index) => { const Icon = item.icon + const title = t(`community:cards.${item.key}.title`, { + defaultValue: item.defaultTitle, + }) + const description = t(`community:cards.${item.key}.description`, { + defaultValue: item.defaultDescription, + }) return ( window.open(item.link, "_blank", "noopener,noreferrer")} > @@ -64,8 +75,8 @@ export function CommunitySection() {
-

{item.title}

-

{item.description}

+

{title}

+

{description}

{item.stats}
diff --git a/components/contact-section.tsx b/components/contact-section.tsx index 4bce56c..bb0e250 100644 --- a/components/contact-section.tsx +++ b/components/contact-section.tsx @@ -2,8 +2,10 @@ import { useState } from 'react' import { Button } from '@/components/ui/button' +import { useTranslation } from 'react-i18next' export function ContactSection() { + const { t } = useTranslation() const [formData, setFormData] = useState({ name: '', email: '', @@ -67,10 +69,12 @@ export function ContactSection() {

- Contact Us + {t('contact:title', { defaultValue: 'Contact Us' })}

- Have questions or feedback about DashAI? Feel free to get in touch — we’d love to hear from you. + {t('contact:description', { + defaultValue: 'Have questions or feedback about DashAI? Feel free to get in touch — we’d love to hear from you.', + })}

@@ -79,7 +83,7 @@ export function ContactSection() {