npm package: @proxylang/sdk
Description: ProxyLang SDK - Instant website translation for JavaScript frameworks. Works standalone or with ProxyLang server-side proxy.
Author: Stringer
Latest version: 0.3.0

# @proxylang/sdk

**ProxyLang** is an instant website translation service. It translates your website content in real-time and delivers it to users in their preferred language.

## How ProxyLang Works

ProxyLang offers two translation approaches:

### 🚀 Server-Side Proxy (Recommended)

The proxy intercepts requests to your website, translates the content server-side, and delivers **fully translated pages** to users. Zero flicker, instant load times, perfect SEO.

**URL patterns supported:**
- `/ko-kr/about` — Full locale code
- `/kr/about` — Country code (auto-detected)
- `/ko/about` — Language code (auto-detected)

With server-side proxy, users receive pre-translated HTML. No JavaScript required.

### ⚡ Client-Side SDK

For **dynamic content** rendered by JavaScript frameworks (React, Vue, Next.js, Nuxt, etc.), the SDK translates content in the browser after it renders.

**Use the SDK when:**
- Your app has client-side routing (SPAs)
- Content is loaded dynamically via AJAX
- You're using the proxy and need to translate JavaScript-rendered content

---

## Installation

```bash
npm install @proxylang/sdk
# or
pnpm add @proxylang/sdk
# or
yarn add @proxylang/sdk
```

Or include via CDN:

```html
<script src="https://unpkg.com/@proxylang/sdk/dist/proxylang-sdk.umd.js"></script>
```

---

## Quick Start

### With Server-Side Proxy (Dynamic Mode)

If you're using ProxyLang's server-side proxy, the SDK only needs to handle new content added by JavaScript:

```javascript
import { ProxyLang } from '@proxylang/sdk'

ProxyLang.init({
  apiKey: 'pk_live_xxx',
  targetLang: 'ko-KR',
  mode: 'dynamic',  // Only translate new DOM content
})
```

### Standalone (Full Mode)

For client-side only translation:

```javascript
import { ProxyLang } from '@proxylang/sdk'

ProxyLang.init({
  apiKey: 'pk_live_xxx',
  targetLang: 'es-MX',
  mode: 'full',  // Translate entire page (default)
})
```

---

## Configuration

```javascript
ProxyLang.init({
  // Required
  apiKey: 'pk_live_xxx',
  targetLang: 'es-MX',
  
  // Mode
  mode: 'full',  // 'full' (default) or 'dynamic'
  
  // Optional
  sourceLang: 'en',                    // Default source language
  selectors: ['body'],                 // CSS selectors to translate
  exclude: ['.no-translate', 'code'],  // Exclude these selectors
  autoTranslate: true,                 // Translate on page load
  observeMutations: true,              // Watch for DOM changes
  debug: false,                        // Enable console logging
  
  // Callbacks
  onStart: () => {},
  onComplete: (stats) => console.log('Done:', stats),
  onError: (error) => console.error(error),
  onQuotaExceeded: (info) => {
    window.location.href = info.upgradeUrl
  },
})
```

### Mode Options

| Mode | Description | Use Case |
|------|-------------|----------|
| `full` | Translates entire page on load | Client-side only apps |
| `dynamic` | Only translates new DOM content | With server-side proxy |

---

## API Reference

### `ProxyLang.init(config)`

Initialize the SDK. Call once on app startup.

### `ProxyLang.translate()`

Manually trigger translation. Returns stats.

```javascript
const stats = await ProxyLang.translate()
// { stringsTranslated: 42, cacheHits: 30, cacheMisses: 12, timeMs: 150 }
```

### `ProxyLang.setLanguage(langCode)`

Change language and re-translate.

```javascript
await ProxyLang.setLanguage('fr-CA')
```

### `ProxyLang.getLanguage()`

Get current target language.

```javascript
ProxyLang.getLanguage()  // 'es-MX'
```

### `ProxyLang.clearCache()`

Clear all cached translations.

```javascript
ProxyLang.clearCache()
```

### `ProxyLang.destroy()`

Clean up the SDK instance.

---

## Language Switcher

### With Server-Side Proxy (Redirect)

When using the proxy, switching languages is a simple URL redirect:

```javascript
function switchLanguage(langCode) {
  // Remove existing language prefix
  const path = window.location.pathname.replace(/^\/[a-z]{2}(-[a-z]{2})?\//i, '/')
  
  // Redirect to new language
  window.location.href = `/${langCode.toLowerCase()}${path}`
}
```

```html
<select onchange="switchLanguage(this.value)">
  <option value="en-US">English</option>
  <option value="ko-KR">한국어</option>
  <option value="ja-JP">日本語</option>
  <option value="es-MX">Español</option>
</select>
```

### With Client-Side SDK

```javascript
const changeLanguage = async (lang) => {
  await ProxyLang.setLanguage(lang)
}
```

---

## Helper Functions

### `isProxyTranslated()`

Check if the current page was served by ProxyLang proxy:

```javascript
import { isProxyTranslated } from '@proxylang/sdk'

if (isProxyTranslated()) {
  // Page is pre-translated, use dynamic mode
  ProxyLang.init({ mode: 'dynamic', ... })
} else {
  // Full client-side translation
  ProxyLang.init({ mode: 'full', ... })
}
```

### `getLanguageFromPath()`

Extract language code from URL path:

```javascript
import { getLanguageFromPath } from '@proxylang/sdk'

const lang = getLanguageFromPath()  // 'ko-kr' from /ko-kr/about
```

---

## Framework Examples

### React

```jsx
import { useEffect, useState } from 'react'
import { ProxyLang, isProxyTranslated } from '@proxylang/sdk'

function App() {
  useEffect(() => {
    ProxyLang.init({
      apiKey: 'pk_live_xxx',
      targetLang: 'es-MX',
      mode: isProxyTranslated() ? 'dynamic' : 'full',
    })
    
    return () => ProxyLang.destroy()
  }, [])
  
  return <div>Your app content</div>
}
```

### Vue / Nuxt

```vue
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { ProxyLang, isProxyTranslated } from '@proxylang/sdk'

onMounted(() => {
  ProxyLang.init({
    apiKey: 'pk_live_xxx',
    targetLang: 'es-MX',
    mode: isProxyTranslated() ? 'dynamic' : 'full',
  })
})

onUnmounted(() => {
  ProxyLang.destroy()
})
</script>
```

---

## Excluding Content

### HTML Attributes

```html
<span data-proxylang-skip>Don't translate this</span>
<div class="proxylang-skip">Or this</div>
```

### HTML Comments

For larger sections:

```html
<!-- @proxylang-do-not-translate-start -->
<div>This entire section stays in the original language</div>
<ul>
  <li>日本語</li>
  <li>한국어</li>
</ul>
<!-- @proxylang-do-not-translate-end -->
```

### Config Exclusions

```javascript
ProxyLang.init({
  exclude: ['.brand-name', 'code', 'pre', '[data-no-translate]'],
})
```

---

## Supported Languages

ProxyLang supports **50+ languages** including:

- 🇺🇸 English, 🇪🇸 Spanish, 🇫🇷 French, 🇩🇪 German
- 🇯🇵 Japanese, 🇰🇷 Korean, 🇨🇳 Chinese (Simplified & Traditional)
- 🇸🇦 Arabic, 🇮🇱 Hebrew, 🇮🇳 Hindi
- And many more...

Full list at [proxylang.dev/languages](https://proxylang.dev/languages)

---

## Performance

- **Edge-cached** — Translations cached at edge for instant delivery
- **Deduplication** — Identical strings translated once
- **Batching** — All strings sent in a single request
- **Persistent cache** — LocalStorage caching for return visitors

---

## Pricing

| Tier | Included | Price |
|------|----------|-------|
| Free | 10,000 tokens | $0 |
| Starter | 100,000 tokens | $9/mo |
| Pro | 1M tokens | $49/mo |
| Business | 10M tokens | $199/mo |

Only cache misses count toward usage. Cached translations are free.

---

## Get Started

1. Sign up at [proxylang.dev](https://proxylang.dev)
2. Create an API key
3. Install the SDK or configure the proxy
4. Start translating!

---

## License

MIT © ProxyLang