tongues.80x24.ai — 설치 없이 바로 쓰는 호스티드 버전. 무료 티어 제공.
Zero-config website translation. One script tag, any language — powered by Claude AI.
Request → Memory Cache (L1) → SQLite (L2) → Claude API (L3) → Cache & Return
- Add a script tag to your site
- tongues scans the page for translatable text
- Translations are cached at three levels for instant subsequent loads
- New content is automatically detected via MutationObserver
npm install open-tonguesimport { Hono } from 'hono'
import { createHandler } from 'open-tongues'
const app = new Hono()
app.route('/tongues', createHandler({
apiKey: process.env.ANTHROPIC_API_KEY!,
}))
export default appThen add the client script to your HTML:
<script src="/tongues/t.js" defer></script>git clone https://github.com/80x24/open-tongues.git
cd open-tongues
bun install
cp .env.example .env
# Edit .env — add your ANTHROPIC_API_KEY
bun dev<script src="http://localhost:3000/t.js" defer></script>Factory that returns a Hono app you can mount as a sub-router.
import { createHandler } from 'open-tongues'
app.route('/tongues', createHandler({
apiKey: 'sk-ant-...', // required
dbPath: './tongues.db', // default: ./tongues.db
model: 'claude-haiku-4-5-20251001', // default
cacheSize: 10_000, // L1 max entries (default: 10000)
cacheTTL: 86_400_000, // L1 TTL in ms (default: 24h)
rateLimit: 100, // per domain per minute (default: 100, 0 = disabled)
corsOrigin: '*', // CORS origin (default: *)
}))Standalone translation engine — use without Hono if you only need the translation logic.
import { createTranslator } from 'open-tongues'
const translator = createTranslator({
apiKey: process.env.ANTHROPIC_API_KEY!,
})
const result = await translator.translateTexts(
['Hello', 'Welcome'],
'ko',
'example.com'
)
// { "Hello": "안녕하세요", "Welcome": "환영합니다" }When mounted via createHandler(), the following endpoints are available:
{
"texts": ["Hello", "Welcome to our site"],
"to": "ko",
"domain": "example.com",
"pageTitle": "My Site",
"preprompt": "This is a food menu"
}Response:
{
"translations": {
"Hello": "안녕하세요",
"Welcome to our site": "저희 사이트에 오신 것을 환영합니다"
}
}Server-side rendered translation for SEO crawlers.
Clear cached translations for a domain and language.
Health check with cache statistics.
<!-- Auto-translate on load (default) -->
<script src="https://YOUR_HOST/t.js" defer></script>
<!-- Manual mode — call window.t.setLocale("ko") to start -->
<script src="https://YOUR_HOST/t.js" data-manual defer></script>
<!-- Custom context for better translations -->
<script src="https://YOUR_HOST/t.js" data-preprompt="This is a food menu" defer></script>t.setLocale("ko")— translate the page to a languaget.restore()— revert to original textt.translateEl(target)— translate specific elements (bypasses root'stranslate="no")t.translateEl(target, { to: "ko" })— translate specific elements to a locale without changing global statet.locale— current locale (read-only)t.sourceLocale— source language (read-only)
Use translateEl with { to } to translate specific sections independently — no setLocale needed:
<nav>UI stays in original language</nav>
<main translate="no">Content translated on demand</main>// Translate only the content area to Korean
await t.translateEl("main", { to: "ko" });
// Switch to English — only main changes, UI untouched
await t.translateEl("main", { to: "en" });
// Restore to original — no API call
await t.translateEl("main", { to: t.sourceLocale });This is useful when you want to translate content independently from UI, or when different sections need different languages.
<span translate="no">Brand Name</span>
<span class="notranslate">Keep Original</span>If you're bundling the client yourself:
import 'open-tongues/client'docker build -t tongues .
docker run -p 3000:3000 -e ANTHROPIC_API_KEY=sk-ant-... tongues| Variable | Required | Default | Description |
|---|---|---|---|
ANTHROPIC_API_KEY |
Yes | — | Claude API key |
PORT |
No | 3000 |
Server port |
DB_PATH |
No | ./tongues.db |
SQLite database path |
MIT