Skip to content

vinnie4k/eqqo-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eqqo-react

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.

Installation

npm install eqqo-react
# or
yarn add eqqo-react
# or
pnpm add eqqo-react

Note: 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.

Quick Start

1. Wrap Your App

import { TranslatorProvider } from "eqqo-react";

function App() {
  return (
    <TranslatorProvider publicKey="your-public-key" defaultLanguage="en">
      <YourApp />
    </TranslatorProvider>
  );
}

2. Add a Language Switcher

Option A: Use the Built-in LanguageSelector Component

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"
/>

Option B: Build Your Own with useTranslation Hook

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.

Excluding Content from Translation

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":

Using the dnt() function

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>
  );
}

Using the <NoTranslate> Component

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>
  );
}

Using the data-no-translate Attribute

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.

Grouped Translation

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.

Using the <TranslateGroup> Component

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>
  );
}

Using the data-translate-group Attribute

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>

How It Works

  1. Combines text: All text nodes within the group are combined into a single string (e.g., "The first AI for corporate events")
  2. Translates as one: The combined text is sent to the translation API as a single phrase, preserving context
  3. 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.

API Reference

<TranslatorProvider>

Wrap your app with this component to enable translations.

Props

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

Example

<TranslatorProvider publicKey="pk_live_abc123xyz" defaultLanguage="en">
  <App />
</TranslatorProvider>

<LanguageSelector>

A ready-to-use language selector component with dropdown UI. Includes loading states, searchable variant, and customizable styling.

Props

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

Examples

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.

useTranslation()

Access translation controls from any component. Must be used inside TranslatorProvider.

Returns

Property Type Description
switchLanguage (lang: string) => Promise<void> Switch to a different language
currentLanguage string Currently active language code
isLoading boolean True while translating

Example

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>
  );
}

<NoTranslate>

Component that prevents its children from being translated.

Props

Prop Type Required Description
children ReactNode ✅ Yes Content to exclude from translation

Example

<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.

dnt()

Helper function that wraps text in a component to exclude it from translation.

Parameters

Parameter Type Description
text string The text to exclude from translation

Returns

A React element that prevents the text from being translated.

Example

<p>Welcome to {dnt("GitHub")} - the world's leading platform</p>

<TranslateGroup>

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.

Props

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

Example

<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.

Supported Languages

eqqo-react supports 40+ language codes, including source languages and target language variants:

Source Languages

  • 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)

Target Language 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.

Customization

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):

With Tailwind CSS

<LanguageSelector
  className="shadow-2xl ring-2 ring-blue-500"
  languages={["en", "es"]}
/>

With Custom CSS

<LanguageSelector className="my-custom-selector" languages={["en", "es"]} />
.my-custom-selector {
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}

Build Your Own UI

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>
  );
}

Features

  • 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

Framework Support

Works seamlessly with all major React frameworks:

  • Next.js (App Router & Pages Router)
  • Vite
  • Create React App
  • Remix
  • Gatsby
  • Any React 16.8+ app

Error Handling

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>
  );
}

Getting Your API Key

Private access only at this moment...

License

MIT

About

React package for Eqqo

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors