ベトナム語🇻🇳↔日本語🇯🇵に特化した、シンプルな翻訳MVPです。
トップページでそのまま翻訳でき、言い換え・ニュアンス・返信例まで確認できます。
入力欄で音声入力と読み上げ、翻訳結果の各セクションで読み上げを利用できます。
- Astro + TypeScript
- Cloudflare Pages (
@astrojs/cloudflare) - Astro API routes (
/api/translate,/api/reply) - Provider abstraction (
mock/openai)
- Install dependencies:
npm install- Create local env file:
cp .env.example .env- (Optional) enable a real provider in
.env:
TRANSLATION_PROVIDER=openai
OPENAI_API_KEY=your_api_key
# Optional
OPENAI_MODEL=gpt-4.1-mini
OPENAI_BASE_URL=https://api.openai.com/v1OpenAI-compatible API を openai provider のまま使う場合:
TRANSLATION_PROVIDER=openai
OPENAI_API_KEY=your_compatible_api_key
OPENAI_MODEL=MiniMax-M1
OPENAI_BASE_URL=https://api.minimax.io/v1- Run:
npm run dev- Open:
http://localhost:4321
.env を以下のように設定すると、実際の OpenAI 翻訳を使えます。
TRANSLATION_PROVIDER=openai
OPENAI_API_KEY=your_api_key
OPENAI_MODEL=gpt-4.1-mini
OPENAI_BASE_URL=https://api.openai.com/v1その後 npm run dev を起動し、トップページから翻訳を実行してください。
TRANSLATION_PROVIDER を mock に戻すと、即座にモック動作へ切り替わります。
MiniMax を openai provider のまま使う場合は次の設定です。
TRANSLATION_PROVIDER=openai
OPENAI_API_KEY=your_minimax_api_key
OPENAI_MODEL=MiniMax-M1
OPENAI_BASE_URL=https://api.minimax.io/v1For Astro local development, use .env.
TRANSLATION_PROVIDER=mock(default)OPENAI_API_KEY=(required whenTRANSLATION_PROVIDER=openai)OPENAI_MODEL=gpt-4.1-mini(optional)OPENAI_BASE_URL=https://api.openai.com/v1(optional)
For Cloudflare Pages runtime, set the same variables in Pages project settings.
If you use Wrangler local runtime, .dev.vars is also supported.
This project is configured for Cloudflare Pages Functions.
wrangler.jsonc includes:
pages_build_output_dir: "./dist"compatibility_flags: ["nodejs_compat"]SESSIONKV binding for Astro sessionsenv.previewuses the sameSESSIONKV namespace as production by default- No
mainfield, because this repository deploys to Cloudflare Pages, not a standalone Worker
If you need Preview and Production to be isolated, add a separate Preview KV namespace later.
npx wrangler kv namespace create SESSIONCopy the returned ID into wrangler.jsonc:
If you later want a separate Preview KV, add another namespace and override it under env.preview.
In Cloudflare Pages:
- Connect this GitHub repository
- Build command:
npm run build - Build output directory:
dist - Node.js version:
22
In Pages project settings, add the same runtime variables you use locally in .env.
Examples:
TRANSLATION_PROVIDER=mockTRANSLATION_PROVIDER=openaiwithOPENAI_API_KEYTRANSLATION_PROVIDER=openaiwithOPENAI_BASE_URL=https://api.minimax.io/v1
In Pages project settings, add a KV binding:
- Variable name:
SESSION - KV namespace: the same namespace used in
wrangler.jsonc
Request:
{
"sourceLang": "ja",
"targetLang": "vi",
"text": "こんにちは",
"mode": "daily",
"tone": "normal"
}Response:
{
"mainTranslation": "...",
"alternatives": ["..."],
"nuanceNotes": ["..."],
"suggestedReplies": ["..."],
"context": {
"sourceLang": "ja",
"targetLang": "vi",
"mode": "daily",
"tone": "normal"
}
}Request:
{
"sourceLang": "ja",
"targetLang": "vi",
"originalText": "こんにちは",
"mainTranslation": "...",
"mode": "daily",
"tone": "normal"
}Response:
{
"suggestedReplies": ["..."]
}src/lib/translate.ts provides a service abstraction:
mockprovider: always available fallbackopenaiprovider: callsPOST https://api.openai.com/v1/responsesOPENAI_BASE_URLを OpenAI-compatible endpoint に切り替えた場合は、その backend に応じてresponsesまたはchat/completionsを自動選択
API route contracts are unchanged. /api/translate and /api/reply stay thin and delegate to the service layer.
The homepage uses a single /api/translate request so translation and suggested replies are generated in one provider call. /api/reply remains available as a separate endpoint for compatibility.
For Cloudflare Pages CI, the build script removes generated _worker.js/wrangler.json, _worker.js/.dev.vars, and .wrangler/deploy/config.json after astro build. It also copies _worker.js/entry.mjs to _worker.js/index.js because the current Pages uploader expects that filename during deployment.
開発サーバー起動後に、以下で API の疎通確認ができます。
curl -s -X POST http://localhost:4321/api/translate \
-H "content-type: application/json" \
-d '{
"sourceLang":"ja",
"targetLang":"vi",
"text":"こんにちは",
"mode":"daily",
"tone":"normal"
}'curl -s -X POST http://localhost:4321/api/reply \
-H "content-type: application/json" \
-d '{
"sourceLang":"ja",
"targetLang":"vi",
"originalText":"こんにちは",
"mainTranslation":"Xin chào",
"mode":"daily",
"tone":"normal"
}'- 音声入力ボタンが無効になっている
SpeechRecognition/webkitSpeechRecognitionが必要です。主に Chrome 系ブラウザで利用できます。
- 読み上げが期待した声で再生されない
- 利用できる音声はブラウザと OS に依存します。日本語は
ja-JP、ベトナム語はvi-VNを優先して選択します。
- 利用できる音声はブラウザと OS に依存します。日本語は
OPENAI_API_KEY is required when TRANSLATION_PROVIDER=openai..envにOPENAI_API_KEYが設定されているか確認してください。
- MiniMax を
openaiprovider で使いたいOPENAI_BASE_URL=https://api.minimax.io/v1とOPENAI_MODEL=MiniMax-M1を設定してください。
- OpenAI 側エラーで
json_object関連メッセージが出る- 実装側で
json指示を入力に含める対応済みです。古い dev サーバープロセスを停止して再起動してください。
- 実装側で
npm run checkで@rollup/rollup-linux-x64-gnu欠落エラー- npm の optional dependency 問題です。
npm iを再実行してください。
- npm の optional dependency 問題です。
npm run devnpm run buildnpm run previewnpm run check
