# afritranslate

[Lire en francais](./README.fr.md)

`afritranslate` is a CLI tool that scans web projects, detects human-readable text, and generates translation JSON files for i18n integration. Google Cloud Translation is the default provider, and Groq is available as an optional provider for non-African language pairs.

African languages supported by Google, such as `fon`, `yo`, `ha`, `ig`, `sw`, `wo`, `ee`, `ln`, `bm`, `rw`, `xh`, and `zu`, are always translated with Google Cloud Translation, even when Groq is selected.

## Installation

```bash
npm install -g afritranslate
```

After installation, configure your API keys once:

```bash
afritranslate configure
```

The wizard asks for a Google Cloud Translation API key and, optionally, a Groq API key. Keys are saved in `~/.afritranslate/config.json` with user-only permissions where the operating system supports it.

## API Keys

### Google Cloud Translation

1. Create or select a Google Cloud project.
2. Enable the Cloud Translation API.
3. Create an API key in Google Cloud Console.
4. Restrict the key to the Cloud Translation API before using it in production.
5. Run `afritranslate configure` and paste the key.

You can also provide the key at runtime:

```bash
GOOGLE_TRANSLATE_API_KEY=your_google_key afritranslate translate --source fr --lang fon
```

Accepted Google key variables are `GOOGLE_TRANSLATE_API_KEY`, `GOOGLE_CLOUD_TRANSLATE_API_KEY`, and `GOOGLE_API_KEY`.

### Groq Console

Groq is optional. Create a key from Groq Console, save it with `afritranslate configure`, or provide it at runtime:

```bash
GROQ_API_KEY=your_groq_key afritranslate translate --provider groq --source en --lang fr
```

The default Groq model is `llama-3.3-70b-versatile`. Override it with `--groq-model` or `GROQ_MODEL`.

## Usage

### 1. Scan a project

Go to the project you want to translate and run the scanner:

```bash
cd my-project
afritranslate scan --verbose
```

![afritranslate scan terminal output](./docs/assets/scan-terminal.png)

The scanner walks through supported folders and files, extracts likely user-facing text, detects languages, and writes `afritranslate.scan.json` in the current directory.

```bash
afritranslate scan ./src
afritranslate scan ./pages --verbose
afritranslate scan --output my-scan.json
```

The scan report keeps each text with its source file, line number, detected language, and language name.

![afritranslate scan report](./docs/assets/scan-report.png)

### 2. Translate the scan

Translate from French to Fon:

```bash
afritranslate translate --source fr --lang fon
```

Translate from English to French:

```bash
afritranslate translate --source en --lang fr
```

Use a custom input or output file:

```bash
afritranslate translate --input afritranslate.scan.json --output src/i18n/afritranslate.fon.json --source fr --lang fon
```

Use Google directly:

```bash
afritranslate translate --provider google --google-key YOUR_GOOGLE_KEY --source fr --lang fon
```

Use Groq for non-African language pairs:

```bash
afritranslate translate --provider groq --groq-key YOUR_GROQ_KEY --source en --lang fr
```

The translation command generates `afritranslate.json` by default.

```json
{
  "version": "0.0.3",
  "provider": "google",
  "sourceLanguage": "fr",
  "targetLanguage": "fon",
  "totalTexts": 42,
  "translatedTexts": 42,
  "translations": {
    "Bienvenue sur notre plateforme": "..."
  }
}
```

## Wire Translations Into Your Site

`afritranslate` generates JSON. It does not rewrite your source code automatically. After translation, add a small `t()` helper and replace visible strings with translation keys.

### Recommended project layout

Generate the output inside your source tree:

```bash
mkdir -p src/i18n
afritranslate translate --output src/i18n/afritranslate.fon.json --source fr --lang fon
```

Create `src/i18n/translate.ts`:

```typescript
import fon from './afritranslate.fon.json';

const translations = fon.translations as Record<string, string>;

export function t(key: string): string {
  return translations[key] ?? key;
}
```

If TypeScript cannot import JSON, enable this in `tsconfig.json`:

```json
{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}
```

### React

```tsx
import { t } from './i18n/translate';

export function HomePage() {
  return (
    <main>
      <h1>{t('Bienvenue sur notre plateforme')}</h1>
      <button>{t('Commencer')}</button>
    </main>
  );
}
```

### Vue 3

```vue
<script setup lang="ts">
import { t } from './i18n/translate';
</script>

<template>
  <main>
    <h1>{{ t('Bienvenue sur notre plateforme') }}</h1>
    <button>{{ t('Commencer') }}</button>
  </main>
</template>
```

### Plain JavaScript

```javascript
import translations from './i18n/afritranslate.fon.json' assert { type: 'json' };

const t = (key) => translations.translations[key] ?? key;

document.querySelector('h1').textContent = t('Bienvenue sur notre plateforme');
```

### Static sites without JSON imports

Put the generated JSON file in `public/` and load it at runtime:

```javascript
const response = await fetch('/afritranslate.fon.json');
const dictionary = await response.json();
const t = (key) => dictionary.translations[key] ?? key;
```

### Multiple languages

Generate one file per target language:

```bash
afritranslate translate --output src/i18n/afritranslate.fon.json --source fr --lang fon
afritranslate translate --output src/i18n/afritranslate.yo.json --source fr --lang yo
afritranslate translate --output src/i18n/afritranslate.en.json --source fr --lang en
```

Then map the dictionaries in your app:

```typescript
import fon from './afritranslate.fon.json';
import yo from './afritranslate.yo.json';
import en from './afritranslate.en.json';

const dictionaries = {
  fon: fon.translations,
  yo: yo.translations,
  en: en.translations,
} as const;

export type Locale = keyof typeof dictionaries;

export function t(key: string, locale: Locale = 'fon'): string {
  return dictionaries[locale][key] ?? key;
}
```

## Scanner Rules

The scanner extracts:

- `.html` / `.htm`: text nodes and common visible attributes.
- `.js` / `.jsx` / `.ts` / `.tsx`: JSX text, visible props, i18n calls, and strings attached to user-facing keys such as `title`, `label`, `description`, `placeholder`, `pageTitle`, `emptyMessage`, and `helperText`.
- `.vue` / `.svelte`: template and script sections.
- `.md` / `.mdx`: prose after stripping code blocks and markdown syntax.
- `.json`: natural-language strings under user-facing keys or inside locale/i18n/message files.

The scanner ignores:

- `node_modules/`, `.git/`, `dist/`, `build/`, `.next/`, `.nuxt/`, `public/assets/`.
- Generated translation files such as `afritranslate.json` and `afritranslate.scan.json`.
- Project config files such as `package.json`, `tailwind.config.ts`, `vite.config.ts`, `next.config.js`, and similar `*.config.*` files.
- CSS values and technical strings such as `2rem`, `1400px`, `hsl(var(--neon-purple))`, `scale(1)`, class names, URLs, paths, payload/schema/error values, and short non-language strings.

## Commands

```bash
afritranslate configure
afritranslate configure --reset
afritranslate scan [directory]
afritranslate scan --verbose
afritranslate translate --source fr --lang fon
afritranslate translate --provider groq --source en --lang fr
```

## Environment Variables

| Variable | Description |
|---|---|
| `GOOGLE_TRANSLATE_API_KEY` | Google Cloud Translation API key. |
| `GOOGLE_CLOUD_TRANSLATE_API_KEY` | Alternative Google key variable. |
| `GOOGLE_API_KEY` | Alternative Google key variable. |
| `GROQ_API_KEY` | Groq API key for `--provider groq`. |
| `GROQ_MODEL` | Groq model name, defaults to `llama-3.3-70b-versatile`. |
| `AFRITRANSLATE_CONFIG` | Custom path for the CLI config file. |

## Development

```bash
npm install
npm run check
```

`npm run check` runs TypeScript typechecking, builds `dist/`, and runs the Node test suite.

## License

MIT. See [LICENSE](./LICENSE).

## Maintainer

- GitHub: [REBCDR07](https://github.com/REBCDR07)
- LinkedIn: [elton27](https://www.linkedin.com/in/elton27)
- Portfolio: [www.thekof.site](https://www.thekof.site)
