Translate your React app into any language with a few lines of code. No code changes, no i18n files, no hassle. Just wrap your app and switch languages on the fly, powered by AI.
npm install eqqo-react
# or
yarn add eqqo-react
# or
pnpm add eqqo-reactNote: The LanguageSelector component works out of the box with inline styles. No CSS framework required! However, you can optionally customize it with Tailwind CSS or your own className.
import { TranslatorProvider } from "eqqo-react";
function App() {
return (
<TranslatorProvider publicKey="your-public-key" defaultLanguage="en">
<YourApp />
</TranslatorProvider>
);
}The easiest way to add language switching is with the pre-built LanguageSelector component:
import { LanguageSelector } from "eqqo-react";
function App() {
return (
<div>
<LanguageSelector />
<YourContent />
</div>
);
}Customize the appearance with props:
<LanguageSelector
languages={["en", "es", "fr", "de", "ja", "zh-hans"]}
textStyle="abbreviated"
variant="searchable"
className="my-custom-class"
/>For custom UI, use the useTranslation hook:
import { useTranslation } from "eqqo-react";
function LanguageSwitcher() {
const { switchLanguage, currentLanguage, isLoading } = useTranslation();
return (
<div>
<button onClick={() => switchLanguage("es")} disabled={isLoading}>
Español
</button>
<button onClick={() => switchLanguage("en")} disabled={isLoading}>
English
</button>
</div>
);
}That's it! Your entire app will automatically translate when users switch languages.
Sometimes you need to prevent certain text from being translated (like brand names, code snippets, or proper nouns). Eqqo provides three ways to mark content as "do not translate":
The dnt() function is a quick way to mark inline text:
import { dnt } from "eqqo-react";
function App() {
return (
<div>
<h1>Welcome to {dnt("MyBrand")}</h1>
<p>Use the command {dnt("npm install")} to get started</p>
</div>
);
}For larger blocks of content, use the NoTranslate component:
import { NoTranslate } from "eqqo-react";
function App() {
return (
<div>
<h1>Welcome to our app</h1>
<NoTranslate>
<pre>
<code>const greeting = "Hello, World!"; console.log(greeting);</code>
</pre>
</NoTranslate>
<p>This text will be translated normally</p>
</div>
);
}You can also add the data-no-translate attribute directly to any element:
function App() {
return (
<div>
<h1>
Welcome to <span data-no-translate="true">MyBrand</span>
</h1>
<p>
Use the command <code data-no-translate="true">npm install</code> to get
started
</p>
</div>
);
}Or in plain HTML:
<div>
<h1>Welcome to <span data-no-translate="true">MyBrand</span></h1>
<pre data-no-translate="true">
<code>const greeting = "Hello, World!";</code>
</pre>
</div>Note: Any content marked with dnt(), <NoTranslate>, or data-no-translate="true" will remain in its original form regardless of the selected language.
When you have text split across multiple elements (like individual <span> elements for styling), translating each word separately can lose context and produce poor translations. Use grouped translation to translate all text within a container as a single unit while preserving your formatting.
Wrap your content with the TranslateGroup component:
import { TranslateGroup } from "eqqo-react";
function Hero() {
return (
<TranslateGroup className="w-full max-w-[692px] text-left lg:text-center">
<span className="inline-block mr-[0.3em]">The</span>
<span className="inline-block mr-[0.3em]">first</span>
<span className="inline-block mr-[0.3em]">AI</span>
<span className="inline-block mr-[0.3em]">for</span>
<span className="inline-block mr-[0.3em]">corporate</span>
<span className="inline-block mr-[0.3em]">events</span>
</TranslateGroup>
);
}You can also add the attribute directly to any element:
<div data-translate-group className="your-classes">
<span>The</span>
<span>first</span>
<span>AI</span>
<span>for</span>
<span>corporate</span>
<span>events</span>
</div>Or in plain HTML:
<div data-translate-group class="w-full max-w-[692px]">
<span class="inline-block mr-[0.3em]">The</span>
<span class="inline-block mr-[0.3em]">first</span>
<span class="inline-block mr-[0.3em]">AI</span>
<span class="inline-block mr-[0.3em]">for</span>
<span class="inline-block mr-[0.3em]">corporate</span>
<span class="inline-block mr-[0.3em]">events</span>
</div>- Combines text: All text nodes within the group are combined into a single string (e.g., "The first AI for corporate events")
- Translates as one: The combined text is sent to the translation API as a single phrase, preserving context
- Preserves formatting: After translation, the text is intelligently distributed back to the original elements, maintaining your styling and structure
Note: The system automatically handles cases where the translated text has a different number of words by distributing them across the available elements.
Wrap your app with this component to enable translations.
| Prop | Type | Required | Description |
|---|---|---|---|
publicKey |
string | ✅ Yes | Your Eqqo public API key |
defaultLanguage |
string | ✅ Yes | The language of your original content (e.g., "en") |
children |
ReactNode | ✅ Yes | Your app components |
rootElement |
HTMLElement | ❌ No | Custom root element to translate. Defaults to document.body |
<TranslatorProvider publicKey="pk_live_abc123xyz" defaultLanguage="en">
<App />
</TranslatorProvider>A ready-to-use language selector component with dropdown UI. Includes loading states, searchable variant, and customizable styling.
| Prop | Type | Default | Description |
|---|---|---|---|
languages |
string[] |
["en", "es"] |
Array of language codes to display |
textStyle |
"abbreviated" | "default" |
"default" |
Display style: "EN" vs "English" |
variant |
"default" | "searchable" |
"default" |
Dropdown variant: simple or with search |
className |
string |
"" |
Additional CSS class for custom styling |
Default variant:
<LanguageSelector languages={["en", "es", "fr", "de"]} />With language variants:
<LanguageSelector
languages={["en-gb", "en-us", "pt-br", "pt-pt", "zh-hans", "zh-hant"]}
/>Searchable variant with abbreviated text:
<LanguageSelector variant="searchable" textStyle="abbreviated" />Custom styling with Tailwind:
<LanguageSelector
className="shadow-xl"
languages={["en", "es", "fr", "de", "ja"]}
/>You can override any of the default Tailwind classes by passing your own className.
Access translation controls from any component. Must be used inside TranslatorProvider.
| Property | Type | Description |
|---|---|---|
switchLanguage |
(lang: string) => Promise<void> |
Switch to a different language |
currentLanguage |
string |
Currently active language code |
isLoading |
boolean |
True while translating |
function LanguageMenu() {
const { switchLanguage, currentLanguage, isLoading } = useTranslation();
return (
<select
value={currentLanguage}
onChange={(e) => switchLanguage(e.target.value)}
disabled={isLoading}
>
<option value="en">English</option>
<option value="es">Español</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
<option value="ja">日本語</option>
</select>
);
}Component that prevents its children from being translated.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode | ✅ Yes | Content to exclude from translation |
<NoTranslate>
<div>This content will not be translated</div>
</NoTranslate>Note: You can also use the data-no-translate="true" attribute directly on any HTML element instead of using this component.
Helper function that wraps text in a component to exclude it from translation.
| Parameter | Type | Description |
|---|---|---|
text |
string | The text to exclude from translation |
A React element that prevents the text from being translated.
<p>Welcome to {dnt("GitHub")} - the world's leading platform</p>Component that marks its children to be translated as a group. All text nodes within this component will be combined and translated together, preserving context while maintaining the original formatting structure.
| Prop | Type | Required | Description |
|---|---|---|---|
children |
ReactNode | ✅ Yes | Content to translate as a group |
groupId |
string | ❌ No | Optional group identifier. Defaults to "true" |
...props |
HTMLAttributes | ❌ No | All standard HTML div attributes (className, style, etc.) are supported |
<TranslateGroup className="text-center">
<span>The</span>
<span>first</span>
<span>AI</span>
<span>for</span>
<span>corporate</span>
<span>events</span>
</TranslateGroup>Note: You can also use the data-translate-group attribute directly on any element instead of using the component.
eqqo-react supports 40+ language codes, including source languages and target language variants:
- AR - Arabic (العربية)
- BG - Bulgarian (Български)
- CS - Czech (Čeština)
- DA - Danish (Dansk)
- DE - German (Deutsch)
- EL - Greek (Ελληνικά)
- EN - English (all English variants)
- ES - Spanish (all Spanish variants)
- ET - Estonian (Eesti)
- FI - Finnish (Suomi)
- FR - French (Français)
- HE - Hebrew (עברית) - next-gen models only
- HU - Hungarian (Magyar)
- ID - Indonesian (Bahasa Indonesia)
- IT - Italian (Italiano)
- JA - Japanese (日本語)
- KO - Korean (한국어)
- LT - Lithuanian (Lietuvių)
- LV - Latvian (Latviešu)
- NB - Norwegian Bokmål (Norsk Bokmål)
- NL - Dutch (Nederlands)
- PL - Polish (Polski)
- PT - Portuguese (all Portuguese variants)
- RO - Romanian (Română)
- RU - Russian (Русский)
- SK - Slovak (Slovenčina)
- SL - Slovenian (Slovenščina)
- SV - Swedish (Svenska)
- TH - Thai (ไทย) - next-gen models only
- TR - Turkish (Türkçe)
- UK - Ukrainian (Українська)
- VI - Vietnamese (Tiếng Việt) - next-gen models only
- ZH - Chinese (all Chinese variants)
- EN-GB - English (British)
- EN-US - English (American)
- ES-419 - Spanish (Latin American)
- PT-BR - Portuguese (Brazilian)
- PT-PT - Portuguese (European)
- ZH-HANS - Chinese (Simplified)
- ZH-HANT - Chinese (Traditional)
Note: Language codes are case-insensitive. You can use "en-gb", "EN-GB", or "En-Gb" - they all work the same way.
The LanguageSelector component works out of the box with built-in styles. You can customize it by passing a className prop with your own CSS classes (Tailwind, CSS modules, or plain CSS):
<LanguageSelector
className="shadow-2xl ring-2 ring-blue-500"
languages={["en", "es"]}
/><LanguageSelector className="my-custom-selector" languages={["en", "es"]} />.my-custom-selector {
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}If you need complete control, build your own UI using the useTranslation hook:
function CustomLanguageSelector() {
const { switchLanguage, currentLanguage, isLoading } = useTranslation();
return (
<div>
<button onClick={() => switchLanguage("en")} disabled={isLoading}>
{currentLanguage === "en" ? "✓" : ""} English
</button>
<button onClick={() => switchLanguage("es")} disabled={isLoading}>
{currentLanguage === "es" ? "✓" : ""} Español
</button>
</div>
);
}- ✅ Zero Configuration - Just wrap and go
- ✅ No Code Changes - Works with your existing app
- ✅ Instant Translations - Fast, on-demand translation
- ✅ Smart Deduplication - Only translates unique text to save API calls
- ✅ Original Text Restoration - Switch back to default language instantly
- ✅ TypeScript Support - Full type definitions included
- ✅ SSR Safe - Works with Next.js, Remix, and other SSR frameworks
- ✅ Framework Agnostic - Works with any React setup
- ✅ Styled & Ready - Pre-built component that works out of the box, customizable with any CSS
Works seamlessly with all major React frameworks:
- Next.js (App Router & Pages Router)
- Vite
- Create React App
- Remix
- Gatsby
- Any React 16.8+ app
Handle translation errors gracefully:
function LanguageButton() {
const { switchLanguage, isLoading } = useTranslation();
const [error, setError] = useState(null);
const handleSwitch = async (lang) => {
try {
setError(null);
await switchLanguage(lang);
} catch (err) {
setError("Translation failed. Please try again.");
console.error(err);
}
};
return (
<div>
<button onClick={() => handleSwitch("es")} disabled={isLoading}>
Translate to Español
</button>
{error && <p style={{ color: "red" }}>{error}</p>}
</div>
);
}Private access only at this moment...
MIT