diff --git a/lib/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json
index 241c837..5fc1ac3 100644
--- a/lib/i18n/dictionaries/en.json
+++ b/lib/i18n/dictionaries/en.json
@@ -150,6 +150,7 @@
"tokenLimit": "Daily Token Limit Reached",
"tpmLimit": "Rate Limit",
"tpmMessage": "Too many requests. Please wait a moment.",
+ "tpmMessageDetailed": "Rate limit reached ({limit} tokens/min). Please wait {seconds} seconds before sending another request.",
"messageApi": "Oops — you've reached the daily API limit for this demo! As an indie developer covering all the API costs myself, I have to set these limits to keep things sustainable.",
"messageToken": "Oops — you've reached the daily token limit for this demo! As an indie developer covering all the API costs myself, I have to set these limits to keep things sustainable.",
"tip": "Tip: You can use your own API key (click the Settings icon) or self-host the project to bypass these limits.",
diff --git a/lib/i18n/dictionaries/ja.json b/lib/i18n/dictionaries/ja.json
index f16b047..d622337 100644
--- a/lib/i18n/dictionaries/ja.json
+++ b/lib/i18n/dictionaries/ja.json
@@ -150,6 +150,7 @@
"tokenLimit": "1日のトークン制限に達しました",
"tpmLimit": "レート制限",
"tpmMessage": "リクエストが多すぎます。しばらくお待ちください。",
+ "tpmMessageDetailed": "レート制限に達しました({limit}トークン/分)。{seconds}秒待ってからもう一度リクエストしてください。",
"messageApi": "おっと — このデモの1日の API 制限に達しました!個人開発者として API コストをすべて負担しているため、持続可能性を保つためにこれらの制限を設定する必要があります。",
"messageToken": "おっと — このデモの1日のトークン制限に達しました!個人開発者として API コストをすべて負担しているため、持続可能性を保つためにこれらの制限を設定する必要があります。",
"tip": "ヒント:独自の API キーを使用する(設定アイコンをクリック)か、プロジェクトをセルフホストしてこれらの制限を回避できます。",
diff --git a/lib/i18n/dictionaries/zh.json b/lib/i18n/dictionaries/zh.json
index f287f7d..eec9836 100644
--- a/lib/i18n/dictionaries/zh.json
+++ b/lib/i18n/dictionaries/zh.json
@@ -150,6 +150,7 @@
"tokenLimit": "已达每日令牌限制",
"tpmLimit": "速率限制",
"tpmMessage": "请求过多。请稍等片刻。",
+ "tpmMessageDetailed": "达到速率限制({limit} 令牌/分钟)。请等待 {seconds} 秒后再发送请求。",
"messageApi": "糟糕 — 您已达到此演示的每日 API 限制!作为一名独立开发者,我自己承担所有 API 费用,因此必须设置这些限制以保持可持续性。",
"messageToken": "糟糕 — 您已达到此演示的每日令牌限制!作为一名独立开发者,我自己承担所有 API 费用,因此必须设置这些限制以保持可持续性。",
"tip": "提示:您可以使用自己的 API 密钥(点击设置图标)或自托管项目来绕过这些限制。",
diff --git a/lib/use-quota-manager.tsx b/lib/use-quota-manager.tsx
index f13d51e..687b864 100644
--- a/lib/use-quota-manager.tsx
+++ b/lib/use-quota-manager.tsx
@@ -3,6 +3,8 @@
import { useCallback, useMemo } from "react"
import { toast } from "sonner"
import { QuotaLimitToast } from "@/components/quota-limit-toast"
+import { useDictionary } from "@/hooks/use-dictionary"
+import { formatMessage } from "@/lib/i18n/utils"
import { STORAGE_KEYS } from "@/lib/storage"
export interface QuotaConfig {
@@ -40,6 +42,8 @@ export function useQuotaManager(config: QuotaConfig): {
} {
const { dailyRequestLimit, dailyTokenLimit, tpmLimit } = config
+ const dict = useDictionary()
+
// Check if user has their own API key configured (bypass limits)
const hasOwnApiKey = useCallback((): boolean => {
const provider = localStorage.getItem(STORAGE_KEYS.aiProvider)
@@ -221,11 +225,12 @@ export function useQuotaManager(config: QuotaConfig): {
const showTPMLimitToast = useCallback(() => {
const limitDisplay =
tpmLimit >= 1000 ? `${tpmLimit / 1000}k` : String(tpmLimit)
- toast.error(
- `Rate limit reached (${limitDisplay} tokens/min). Please wait 60 seconds before sending another request.`,
- { duration: 8000 },
- )
- }, [tpmLimit])
+ const message = formatMessage(dict.quota.tpmMessageDetailed, {
+ limit: limitDisplay,
+ seconds: 60,
+ })
+ toast.error(message, { duration: 8000 })
+ }, [tpmLimit, dict])
return {
// Check functions