Documents
Internationalization and Localization
Internationalization and Localization
Type
Document
Status
Published
Created
Aug 8, 2025
Updated
Mar 25, 2026
Updated by
Dosu Bot

Internationalization and Localization#

The project supports internationalization (i18n) and localization (l10n) for both the browser extension and website, enabling a scalable, maintainable multi-language UI.

Localized UI Elements and Content#

All UI elements, configuration options, provider descriptions, provider groupings, sidebar group labels, translation mode selectors, error recovery interfaces, context menu items, and blog content are localized using structured locale files. The browser extension uses YAML files (e.g., en.yml), while the website uses JSON files (e.g., en.json, zh.json).

Translations are organized hierarchically by UI section, such as popup dialogs, options pages, side panels, provider descriptions, sidebar navigation, error recovery, context menus, and blog pages. For example, the extension's locale files include keys for popup labels (autoLang, sourceLang, targetLang), configuration options (options.apiProviders.title, options.general.title), translation mode selector labels (options.translation.translationMode.title, options.translation.translationMode.description, and options.translation.translationMode.mode.<mode> for each mode), sidebar group labels (options.sidebar.settings, options.sidebar.product), command palette UI (options.commandPalette.placeholder, options.commandPalette.noResults), error recovery UI (errorRecovery.title, errorRecovery.description), context menu items (contextMenu.translate, contextMenu.translateSelection), and provider descriptions under options.apiProviders.description for each supported provider.

Model Selector UI Keys#

The model selector UI uses several i18n keys under options.apiProviders.form.models, including:

  • selectModel: Label for the model selection button
  • noModels: Message when no models are available
  • apiKeyRequired: Prompt to add an API key before fetching models
  • searchModels: Placeholder for the model search input (added for the searchable combobox)
  • noModelsFound: Message shown when no models match the search (added for the searchable combobox)

Connection Option Labels#

Provider configuration forms include connection option fields for provider-specific settings. These labels are localized under options.apiProviders.form.connectionOptionLabels:

  • region: Label for the region selection field (used for providers like Bedrock)

Example:

options:
  apiProviders:
    form:
      connectionOptionLabels:
        region: Region

This structure was added to all 8 supported locale files (en, ja, ko, ru, tr, vi, zh-CN, zh-TW) to support provider connection options.

Provider Options Recommendation Keys#

Provider configuration forms include a recommendation feature for model-specific provider options. These keys appear next to the model selector and enable users to preview and manually apply recommended options. The keys are under options.apiProviders.form:

  • providerOptionsRecommendationTrigger: Tooltip for the sparkles button that opens the recommendation popover (appears next to model selector)
  • providerOptionsRecommendationTitle: Title of the recommendation dialog/popover
  • providerOptionsRecommendationDescription: Description text explaining what the recommended options are for
  • providerOptionsRecommendationApply: Label for the "Apply" button to apply recommended options
  • providerOptionsRecommendationApplied: Label for the button after recommendations have been applied (applied state)

Example:

options:
  apiProviders:
    form:
      providerOptionsRecommendationTrigger: View recommended provider options
      providerOptionsRecommendationTitle: Recommended provider options detected
      providerOptionsRecommendationDescription: Review and manually apply the recommended configuration.
      providerOptionsRecommendationApply: Apply
      providerOptionsRecommendationApplied: Applied

These keys support the manual provider options recommendation feature introduced in PR #1152, which replaced automatic runtime application with a user-controlled preview and apply workflow.

When adding a new translation mode, add a new key under options.translation.translationMode.mode in every locale file, with a localized label for each mode.

Command Palette Keys#

The Settings command palette enables quick search and navigation to any settings section. It can be accessed through:

  • Global keyboard shortcut: ⌘K (macOS) or Ctrl+K (Windows/Linux)
  • Sidebar search input: Clicking the search input in the sidebar opens the command palette

Functionality:

  • Allows fuzzy search through all configuration sections
  • Results are grouped by settings page (General, Translation, API Providers, etc.)
  • Selecting a result navigates to that page and deep-links to the specific section using ?section=<sectionId> query parameters
  • Implements reliable auto-scroll to the selected section (waits for the section to mount if necessary, then smooth-scrolls into view)

i18n Keys:
The command palette uses the following i18n keys under options.commandPalette:

  • placeholder: Used for the search input placeholder, dialog title, and dialog description
  • noResults: Message displayed when no search results match the query

Example:

options:
  commandPalette:
    placeholder: Search settings...
    noResults: No settings found

Implementation Details:

  • All searchable sections require an id prop on their ConfigCard or PromptConfigurator components to enable deep-linking support
  • Search items are defined in search-items.ts, with each item containing:
    • sectionId: The HTML element ID for scrolling
    • route: The page route path
    • titleKey: i18n key for the section title (used for display and search)
    • descriptionKey (optional): i18n key for additional searchable text
    • pageKey: i18n key for the group heading in search results

Provider Group Titles and Descriptions#

In the "Add Provider" dialog, providers are grouped, and each group now includes both a localized title and a description. These are defined in all supported languages using a nested structure under options.apiProviders.dialog.groups:

groups:
  builtInProviders:
    title: Built-in LLM Providers
    description: Built-in large language model providers, no need to fill in most configurations like Base URL
  openaiCompatibleProviders:
    title: OpenAI Compatible Custom Providers
    description: If you can't find your desired AI provider, select Custom Provider to configure any OpenAI-compatible provider, such as Zhipu AI
  pureTranslationProviders:
    title: Pure Translation Providers
    description: Providers focused on translation features without large language model capabilities

Equivalent nested structures exist in all locale files (English, Japanese, Korean, Simplified Chinese, Traditional Chinese). The dialog-level description has been removed; only group titles and descriptions are shown.

Adding or Updating Provider Groups#

When adding or updating a provider group, ensure you use the canonical provider keys as defined in the codebase. Recent updates have renamed several provider keys for consistency:

  • 'gemini' is now 'google'
  • 'grok' is now 'xai'
  • 'amazonBedrock' is now 'bedrock'
  • 'openaiCompatible' is now 'openai-compatible'
  • 'google' (for translation) is now 'google-translate'
  • 'microsoft' (for translation) is now 'microsoft-translate'

Always use these updated keys in your locale files under options.apiProviders.dialog.groups and for provider descriptions. For example, to add a new group for Google Gemini models, use the key google (not gemini). For Google Translate, use google-translate.

This ensures that localization entries match the provider keys expected by the application and migration scripts.

Provider Descriptions#

Each provider has a localized description under options.apiProviders.description in all supported languages. When adding a new provider, add its description to this section in every locale file.

The following providers have localized descriptions across all 8 supported languages (en, ja, ko, ru, tr, vi, zh-CN, zh-TW):

  • alibaba: Alibaba Cloud's Qwen model series with advanced reasoning and multilingual capabilities
  • moonshotai: Moonshot AI's Kimi model series with strong reasoning and long-context capabilities
  • huggingface: Hugging Face Inference API providing access to thousands of open-source models
  • All other supported LLM and translation providers (openai, deepseek, google, anthropic, xai, etc.)

Example:

options:
  apiProviders:
    providers:
      description:
        alibaba: Alibaba Cloud's Qwen model series with advanced reasoning and multilingual capabilities
        moonshotai: Moonshot AI's Kimi model series with strong reasoning and long-context capabilities
        huggingface: Hugging Face Inference API providing access to thousands of open-source models
        openai: OpenAI's GPT models for translation and analysis
        # ... other providers

TTS (Text-to-Speech)#

The project uses Edge TTS as the built-in, free Text-to-Speech provider. Edge TTS uses Microsoft Edge's online TTS service and does not require an API key or external provider configuration. It supports a wide range of languages with high-quality neural voices.

Firefox Availability: TTS features are currently unavailable on Firefox builds due to a browser-specific issue. The Speak button in the selection toolbar, the TTS settings page, sidebar navigation item, and command palette entry are hidden on Firefox. These features remain available on other browsers (Chrome, Edge, etc.).

TTS Configuration Localization Keys#

TTS settings use the following i18n keys under options.tts (not visible on Firefox builds):

  • title: Section title ("Text to Speech")
  • description: Brief description of TTS settings
  • voice.label: Label for the voice selector
  • voice.fallback: Label indicating fallback/default voice ("Fallback")
  • voice.selectPlaceholder: Placeholder text for voice selection
  • voice.preview: Label for the preview button
  • voice.previewSample: Sample text used for voice preview
  • languageVoice.label: Label for language-specific voice configuration ("Language Voice")
  • languageVoice.reset: Label for reset button ("Reset to Default")
  • languageVoice.description: Description explaining language-voice mapping
  • rate.label: Label for rate control ("Rate (%)")
  • rate.hint: Hint text for rate control ("Accepts integer values between -100 and 100")
  • pitch.label: Label for pitch control ("Pitch (Hz)")
  • pitch.hint: Hint text for pitch control ("Accepts integer values between -100 and 100")
  • volume.label: Label for volume control ("Volume (%)")
  • volume.hint: Hint text for volume control ("Accepts integer values between -100 and 100")

Example:

options:
  tts:
    title: Text to Speech
    description: Use Edge TTS voice settings for the Speak button.
    voice:
      label: Voice
      fallback: Fallback
      selectPlaceholder: Select a voice
      preview: Preview
      previewSample: Hello from Read Frog! This is how I will sound when reading aloud.
    languageVoice:
      label: Language Voice
      reset: Reset to Default
      description: Select a language and assign a voice used when TTS detects that language.
    rate:
      label: Rate (%)
      hint: Accepts integer values between -100 and 100
    pitch:
      label: Pitch (Hz)
      hint: Accepts integer values between -100 and 100
    volume:
      label: Volume (%)
      hint: Accepts integer values between -100 and 100

These replace the previous OpenAI-specific keys: options.tts.provider.*, options.tts.model.label, options.tts.model.hint, and options.tts.speed.*.

Note: Language detection settings for TTS have been moved to the centralized Language Detection configuration in General settings (see Language Detection Configuration section below).

Per-Language Voice Configuration#

TTS supports per-language voice mappings through the languageVoices configuration field. Users can assign different Edge TTS voices for different detected languages. The configuration includes:

  • defaultVoice: Fallback voice used when no language-specific voice is configured
  • languageVoices: A record mapping ISO 639-3 language codes to Edge TTS voice names (e.g., {"eng": "en-US-GuyNeural", "cmn": "zh-CN-YunxiNeural"})

Edge TTS automatically detects the language of the input text and selects the appropriate voice from the languageVoices mapping. If no mapping exists for the detected language, it falls back to the defaultVoice. Language detection uses the centralized Language Detection configuration from General settings (see Language Detection Configuration section below).

TTS Configuration Schema#

The TTS configuration object includes the following fields:

  • defaultVoice (string): The fallback Edge TTS voice name
  • languageVoices (Record<LangCodeISO6393, string>): Per-language voice mappings
  • rate (integer, -100 to 100): Speech rate adjustment
  • pitch (integer, -100 to 100): Speech pitch adjustment
  • volume (integer, -100 to 100): Speech volume adjustment

Note: The detectLanguageMode field has been removed. Language detection is now configured centrally in General settings (see Language Detection Configuration section below).

TTS Error Messages#

TTS error handling uses localized error messages. The key speak.failedToGenerateSpeech is used in the use-text-to-speech hook to display localized error messages when speech synthesis fails.

Example:

speak:
  failedToGenerateSpeech: Failed to generate speech

Custom AI Actions#

The project supports user-defined custom AI actions for the selection toolbar, introduced in PR #1020. These actions allow users to create personalized AI-powered tools that appear alongside built-in buttons when text is selected.

Custom Actions i18n Structure#

Custom AI actions introduce comprehensive localization across all 8 supported languages (en, zh-CN, zh-TW, ja, ko, ru, tr, vi) under the key path options.floatingButtonAndToolbar.selectionToolbar.customActions. The localization covers:

Configuration Page UI:

  • title: Section title ("Custom AI Actions")
  • description: Brief description of the action feature
  • add: Button label for adding a new action
  • edit: Button label for editing an existing action
  • empty: Message shown when no custom actions exist
  • noEnabledLlmProvider: Error message when no LLM provider is enabled

Table Labels:
These labels are used for the custom actions management UI in the settings sidebar:

  • table.name: Column header for action name
  • table.provider: Column header for provider
  • table.fields: Column header for field count
  • table.actions: Column header for actions

Custom action cards in the settings sidebar support drag-and-drop reordering. Users can reorder custom actions using the implicit drag handles on each card, and the order is persisted to the configuration.

Form Fields:

  • form.name: Label for the name field
  • form.icon: Label for the icon field (Iconify icon string)
  • form.provider: Label for the provider selector
  • form.selectProvider: Placeholder text for provider selection
  • form.systemPrompt: Label for system prompt field
  • form.prompt: Label for prompt field
  • form.outputSchema: Label for output schema configuration
  • form.addField: Button to add a new output field
  • form.fieldName: Label for field name input
  • form.fieldType: Label for field type selector
  • form.fieldDescription: Label for field description input
  • form.fieldDescriptionPlaceholder: Placeholder text for field description input
  • form.actions: Label for action buttons
  • form.cancel: Cancel button label
  • form.save: Save button label
  • form.defaultFieldName: Default name for new fields
  • form.fieldNamePlaceholder: Placeholder for field name input
  • form.autoFieldPrefix: Prefix for auto-generated field names

Output Schema Field Management:
The output schema is displayed as a sortable list with drag-and-drop reordering support. Each field is shown as a compact card displaying the field name, type badge, and description inline. Field editing uses dialog-based UI for better user experience:

  • form.addFieldDialog.title: Title for the add field dialog ("Add Output Field")
  • form.editFieldDialog.title: Title for the edit field dialog ("Edit Output Field")
  • form.editFieldDialog.save: Save button text in the edit dialog
  • form.deleteFieldDialog.title: Title for the delete confirmation dialog ("Delete Output Field?")
  • form.deleteFieldDialog.description: Warning message in the delete dialog
  • form.deleteFieldDialog.confirm: Confirm button label for deletion
  • form.deleteFieldDialog.cancel: Cancel button label for deletion
  • form.fieldSpeaking: Label for the "Enable speaking" checkbox on output fields

Users can reorder output schema fields via drag-and-drop using the grip handle on each field card. The field order is persisted to the configuration. Field descriptions are included in the structured output contract sent to the AI and support token interpolation ({{selection}}, {{paragraphs}}, {{targetLanguage}}, {{webTitle}}, {{webSummary}}). The system prompt documents fields in YAML-like format with descriptions to guide the AI's response structure.

Speaking Field:
Output schema fields include an optional speaking boolean flag (added in PR #1111). When enabled for a field, a Speak button appears next to that field's value in the structured output results popover, allowing users to read the field value aloud using TTS. This is particularly useful for dictionary-style custom actions where fields like "Term" or "Context" can be spoken to hear pronunciation. The feature uses the centralized Language Detection configuration from General settings to automatically select the appropriate voice.

Notebase Connection:
Custom AI actions support saving structured output to a remote notebase (introduced in PR #1215, requires beta experience toggle). The notebase connection settings are localized under options.floatingButtonAndToolbar.selectionToolbar.customActions.form.notebase:

  • title: Section title ("Notebase Connection")
  • description: Brief description of the notebase integration
  • loginRequiredTitle: Title shown when user is not authenticated
  • loginRequiredDescription: Description prompting user to log in
  • loginAction: Label for the login button
  • tableLabel: Label for the notebase selector ("Notebase")
  • tablePlaceholder: Placeholder text for notebase selection
  • tableClearOption: Label for disconnecting a notebase ("Disconnect notebase")
  • refreshAction: Label for the refresh button
  • emptyTitle: Title shown when no notebases exist
  • emptyDescription: Description prompting user to create a notebase
  • openNotebaseAction: Label for the button to open notebase website
  • betaLockedTitle: Title shown when user is not enrolled in Notebase beta ("This account is not in the Notebase beta")
  • betaLockedDescription: Description explaining beta limitation and directing users to enroll
  • tableUnavailableTitle: Title shown when selected notebase is no longer available
  • tableUnavailableDescription: Description for unavailable notebase
  • tableUnavailableOption: Label suffix for unavailable notebase in dropdown ("unavailable")
  • schemaErrorTitle: Title shown when schema loading fails
  • schemaErrorDescription: Description for schema loading errors
  • schemaLoading: Loading message while fetching schema
  • mappingsLabel: Label for the field mappings section ("Field Mappings")
  • mappingsEmpty: Message shown when no mappings exist
  • addMappingAction: Label for the button to add a mapping ("Add Mapping")
  • removeMappingAction: Aria-label for the button to remove a mapping
  • localFieldLabel: Label for the action field selector ("Action field")
  • localFieldPlaceholder: Placeholder text for action field selection
  • remoteFieldLabel: Label for the notebase field selector ("Notebase field")
  • remoteFieldPlaceholder: Placeholder text for notebase field selection
  • columnUnavailableOption: Label suffix for removed notebase columns ("removed")
  • invalidMappingsTitle: Title for alert when mappings are invalid
  • invalidMappingsDescription: Description explaining invalid mappings
  • mappingMissingLocal: Error message when mapped action field no longer exists
  • mappingMissingRemote: Error message when mapped notebase field no longer exists
  • mappingMissingSchema: Error message prompting user to refresh schema
  • mappingIncompatible: Error message when field types no longer match

Users can select a notebase, map custom action output fields to notebase columns, and save results using the "Save to Notebase" button in the selection toolbar. Invalid mappings are preserved but disable saving until fixed. The UI validates mapping compatibility based on field types and provides clear feedback for authentication, beta access limitations, missing notebases, schema errors, and invalid mappings.

Example:

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      customActions:
        form:
          notebase:
            title: Notebase Connection
            description: Save this action's structured results to a remote notebase.
            tableLabel: Notebase
            tablePlaceholder: Select a notebase
            mappingsLabel: Field Mappings
            addMappingAction: Add Mapping
            localFieldLabel: Action field
            remoteFieldLabel: Notebase field

Prompt Tokens:
Custom AI actions support dynamic token substitution in prompts. The following tokens are documented under form.tokens:

  • selection: Selected text content
  • paragraphs: Paragraph text where the selection appears
  • targetLanguage: User's target language
  • webTitle: Webpage title
  • webSummary: Webpage summary

Note: In v064, prompt tokens were renamed for improved clarity and consistency: contextparagraphs, targetLangtargetLanguage, titlewebTitle, and summarywebSummary. Configuration migration scripts automatically update existing custom actions.

Delete Action Dialog:

  • form.deleteDialog.title: Dialog title for confirming action deletion
  • form.deleteDialog.description: Warning message
  • form.deleteDialog.confirm: Confirm button label
  • form.deleteDialog.cancel: Cancel button label

Error Messages:
Validation errors for the configuration form are localized under errors:

  • nameRequired: Error when name is empty
  • duplicateName: Error for duplicate action names (uses $1 placeholder)
  • invalidIcon: Error for invalid Iconify icon string
  • providerRequired: Error when no provider is selected
  • outputSchemaRequired: Error when no output fields are defined
  • fieldKeyRequired: Error when field name is empty
  • duplicateFieldKey: Error for duplicate field names

Example (English):

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      customActions:
        title: Custom AI Actions
        description: Add your own structured AI actions for selected text
        add: Add AI Action
        form:
          name: Name
          icon: Icon (Iconify)
          provider: Provider (requires structured output support)
          prompt: Prompt
          outputSchema: Output Schema
          tokens:
            selection: Selected text content
            context: Paragraph text where the selection appears
            targetLang: "User's target language"
            title: Webpage title
        errors:
          duplicateName: 'Duplicate action name "$1"'

Example (Simplified Chinese):

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      customActions:
        title: 自定义 AI 操作
        description: 为划词添加你自己的结构化 AI 操作
        add: 添加 AI 操作
        form:
          name: 名称
          icon: 图标 (Iconify)
          provider: 提供商(需支持结构化输出)
          prompt: 提示词
          outputSchema: 输出 Schema
          tokens:
            selection: 选中的文本内容
            context: 选中文本所在段落内容
            targetLang: 用户的目标语言
            title: 网页标题
        errors:
          duplicateName: '重复的操作名称 "$1"'

Custom Action Templates#

The UI supports template-based action creation to help users get started quickly with common use cases. When adding a new custom action, users are first presented with a template selection dialog. Templates are localized under customActions.templates:

Template Selection Dialog:

  • templates.dialogTitle: Title for the template selection dialog ("Choose a Template")
  • templates.dialogDescription: Description text explaining template selection

Built-in Templates:
Each template includes localized names, descriptions, system prompts, prompts, and output field definitions. The template keys are structured under customActions.templates:

  1. Dictionary Template (dictionary):

    • name: Template name ("Dictionary")
    • description: Template description ("Look up words with definitions, phonetics, and context translations")
    • systemPrompt: Pre-configured system prompt for dictionary lookups with comprehensive instructions and examples
    • prompt: Pre-configured user prompt template using token placeholders
    • Output field labels and descriptions (7 fields total):
      • fieldTerm, fieldTermDescription - Base/canonical lemma of the selected term
      • fieldPhonetic, fieldPhoneticDescription - Standard phonetic transcription (IPA, pinyin, romaji)
      • fieldPartOfSpeech, fieldPartOfSpeechDescription - Grammatical category
      • fieldDefinition, fieldDefinitionDescription - Concise definition for the contextual sense
      • fieldContext, fieldContextDescription - The context from the prompt (unchanged)
      • fieldContextTranslation, fieldContextTranslationDescription - Translation of the context
      • fieldDifficulty, fieldDifficultyDescription - CEFR difficulty level (A1-C2)
  2. Improve Writing Template (improveWriting):

    • name: Template name ("Improve Writing")
    • description: Template description ("Analyze writing errors and suggest improvements")
    • systemPrompt: Pre-configured system prompt for writing improvement with language policy instructions
    • prompt: Pre-configured user prompt template
    • Output field labels and descriptions (2 fields total):
      • fieldErrorAnalysis, fieldErrorAnalysisDescription - Grammar, spelling, punctuation, and word-choice issues
      • fieldImprovedVersion, fieldImprovedVersionDescription - Corrected version in original language

    Language Policy in Improve Writing Template:
    The system prompt includes a 4-point Language Policy section:

    1. Detect the original language of Selection as {{originLanguage}}
    2. The "Error Analysis" field must be written in {{targetLanguage}}
    3. The "Improved Version" field must stay in {{originLanguage}}
    4. Never translate "Improved Version" into {{targetLanguage}} unless {{originLanguage}} is already {{targetLanguage}}

    Example Format:
    Both examples follow this structure:

    • Selection: [the selected text without language designation in parentheses]
    • Detected {{originLanguage}}: [language name]
    • {{targetLanguage}}: [language name]
    • Error Analysis ([language] — {{targetLanguage}}): [analysis in target language]
    • Improved Version ([language] — {{originLanguage}}): [corrected text in original language]

    Example A (English original, Chinese target):
    Selection is "He go to school yesterday, and he don't finish his homework." The Error Analysis is written in Chinese ({{targetLanguage}}), explaining subject-verb agreement and tense errors. The Improved Version provides the corrected English text ({{originLanguage}}): "He went to school yesterday, and he didn't finish his homework."

    Example B (Japanese original, English target):
    Selection is "昨日私は友達に会いて、一緒に映画を見るました。" (Japanese text with verb conjugation errors). The Error Analysis is written in English ({{targetLanguage}}), explaining that "会いて" should be "会って" (te-form of 会う) and "見るました" should be "見ました" (past tense masu-form). The Improved Version provides the corrected Japanese text: "昨日私は友達に会って、一緒に映画を見ました。" ({{originLanguage}}).

  3. Blank Template (blank):

    • name: Template name ("Blank")
    • description: Template description ("Start from scratch with an empty action")

Example Excerpt from Dictionary Template (English):

customActions:
  templates:
    dialogTitle: Choose a Template
    dialogDescription: Select a template to quickly create a new AI action, or start from scratch.
    dictionary:
      name: Dictionary
      description: Look up words with definitions, phonetics, and context translations
      systemPrompt: |-
        You are a dictionary assistant for language learners.

        ## Goal
        Given a term and its surrounding context, produce a concise dictionary entry that matches the required output object.

        ## Rules
        1. Focus on the meaning that best matches the provided context.
        2. Normalize Term to its base/canonical form.
        3. Keep Definition precise and learner-friendly.
        4. Keep Context short and directly tied to the selected text.
        5. Phonetic must use the standard notation for the term's language (e.g., IPA for English, pinyin for Mandarin, romaji for Japanese).
        6. Part of Speech in English (noun, verb, adjective, etc.).
        7. Difficulty must be a CEFR level (A1, A2, B1, B2, C1, or C2).
        8. If a field is unknown, return an empty string instead of guessing.
        9. Respond in {{targetLang}} for all textual fields unless source-form text is required for clarity.

        ## Examples

        ### Example 1
        Input: Selection="blossoms", Context="The ephemeral beauty of cherry blossoms reminds us to cherish each moment.", Target language=Chinese

        Output:
        - Term: blossom
        - Phonetic: /ˈblɒs.əm/
        - Part of Speech: noun
        - Context: The ephemeral beauty of cherry blossoms reminds us to cherish each moment.
        - Definition: 花;花朵(尤指果树的花)
        - Context Translation: 樱花短暂的美丽提醒我们珍惜每一刻。
        - Difficulty: B2
      prompt: |-
        ## Input
        Selection: {{selection}}
        Context: {{context}}
        Target language: {{targetLang}}
      fieldTerm: Term
      fieldTermDescription: Base/canonical lemma of the selected term.
      fieldPhonetic: Phonetic
      fieldPhoneticDescription: Standard phonetic transcription for the term's language (e.g., IPA for English, pinyin for Mandarin, romaji for Japanese).
      # ... additional field labels and descriptions

Templates provide pre-configured prompts and output schemas that users can customize after creation. The dictionary template includes detailed examples showing how the AI should format responses. All template content, including the extensive system prompts with examples, is fully localized across the 8 supported languages.

Data Type Localization#

Custom AI actions define output schemas with typed fields. Field types are localized under the top-level dataTypes key:

  • string: Label for text/string type
  • number: Label for numeric type

Example:

dataTypes:
  string: Text
  number: Number

Provider Validation and Deletion#

When deleting a provider that is in use by custom AI actions, validation prevents deletion if no alternative provider is available. The i18n key options.apiProviders.form.providerInUseCannotDisable displays an error message with dynamic placeholders:

  • $1: Provider name
  • $2: Number of affected actions

Example:

providerInUseCannotDisable: 'Cannot disable "$1" because it is currently used by $2 action(s).'

When deleting a provider used by custom AI actions, a confirmation dialog appears using keys under options.apiProviders.form.deleteDialog:

  • title: Dialog title ("Delete Provider?")
  • description: Warning message explaining automatic action reassignment
  • confirm: Confirm button label
  • cancel: Cancel button label

Custom AI actions are automatically reassigned to the next available enabled LLM provider when their assigned provider is deleted.

Feature Provider Integration#

Custom AI actions integrate with the feature providers system. The feature label is localized under options.general.featureProviders.customActions:

options:
  general:
    featureProviders:
      customActions: Custom AI Actions

Selection Toolbar Integration#

Custom AI action buttons appear in the selection toolbar with their configured icon and name. When activated, they display a popover with:

  • The selected text and paragraph context
  • Streaming AI-generated structured output rendered as key-value cards
  • Inline error alerts for failed requests (see Selection Toolbar Error Handling)

These UI elements use inline text or rely on the structured output schema field names defined by the user.

Selection Toolbar Feature Toggles#

The selection toolbar configuration includes individual enable/disable toggles for each built-in feature. These toggles are localized under options.floatingButtonAndToolbar.selectionToolbar.featureToggles:

Feature Toggle Keys:

  • title: Section title ("Feature Toggles")
  • description: Description explaining the feature toggles functionality ("Choose which built-in features to show in the selection toolbar")
  • translate: Label for the translate feature toggle ("Translate")
  • speak: Label for the speak feature toggle ("Speak")

Each built-in feature (translate, speak) can be individually toggled on/off in the options page. When all features (built-in + custom actions) are disabled, the toolbar is not mounted on text selection. The speak toggle is hidden on Firefox where TTS is not supported.

Example:

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      featureToggles:
        title: Feature Toggles
        description: Choose which built-in features to show in the selection toolbar
        translate: Translate
        speak: Speak

These keys were added across all 8 supported locale files (en, ja, ko, ru, tr, vi, zh-CN, zh-TW) in PR #1115 to support granular control over which selection toolbar features appear to users.

Selection Toolbar Opacity#

The selection toolbar configuration includes an opacity setting that controls the transparency of the toolbar and its popovers. The opacity keys are localized under options.floatingButtonAndToolbar.selectionToolbar.opacity:

Opacity Keys:

  • title: Section title ("Opacity")
  • description: Description explaining the opacity setting ("Adjust the opacity of the selection toolbar and the expanded window opened from it")

The opacity setting accepts values from 1% to 100%, with 100% being fully opaque (the default). This setting applies to both the selection toolbar and all popover content opened from it, including translation results and custom AI actions.

Example:

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      opacity:
        title: Opacity
        description: Adjust the opacity of the selection toolbar and the expanded window opened from it

These keys were added across all 8 supported locale files (en, ja, ko, ru, tr, vi, zh-CN, zh-TW) in PR #1126 to allow users to customize the visual appearance of the selection toolbar and improve readability when the toolbar overlays web content.

Selection Toolbar Error Handling#

The selection toolbar displays inline error alerts within popovers for both Translation and Custom AI Actions. Error handling includes precheck validation (before making requests) and runtime error handling (during execution). Error messages are localized under options.floatingButtonAndToolbar.selectionToolbar.errors:

Error Keys:

  • customActionFailed: Error title when a custom action fails ("Custom Action Failed")
  • customActionFailedFallback: Fallback error description for custom action failures ("Custom action request failed")
  • actionUnavailable: Error message when an action is unavailable ("Selected action is unavailable")
  • missingSelection: Error when no text is selected ("No selected text available")
  • providerDisabled: Error message when the provider is disabled ("Selected provider is disabled")
  • providerUnavailable: Error message when the provider is unavailable ("Selected provider is unavailable")

Translation errors reuse existing keys from the Translation Hub namespace (translationHub.translationFailed, translationHub.translationFailedFallback) for consistency.

Example:

options:
  floatingButtonAndToolbar:
    selectionToolbar:
      errors:
        customActionFailed: Custom Action Failed
        customActionFailedFallback: Custom action request failed
        actionUnavailable: Selected action is unavailable
        missingSelection: No selected text available
        providerDisabled: Selected provider is disabled
        providerUnavailable: Selected provider is unavailable

Error Types:

  • Precheck errors: Validation errors that occur before making a request (e.g., provider disabled, missing selection, action unavailable)
  • Runtime errors: Errors that occur during request execution (e.g., API errors, network failures, AI SDK errors)

Inline error alerts replace toast notifications for selection toolbar actions, providing contextual error feedback within the popover UI. Errors are cleared automatically when a user successfully reruns the action or closes the popover.

Selection Toolbar Popover Actions#

The selection toolbar uses a refactored SelectionPopover compound component to display translation results and custom AI actions. Each popover includes a footer with common action buttons that are localized under the action namespace:

Action Button Keys:

  • action.copy: Label for the copy button ("Copy")
  • action.copied: Label shown after copying ("Copied")
  • action.regenerate: Label for the regenerate button ("Regenerate")
  • action.speak: Label for the speak button ("Speak")
  • action.playing: Label shown while audio is playing ("Playing")
  • action.translation: Tooltip label for the translation button in the selection toolbar ("Translation")
  • action.saveToNotebase: Label for the save to notebase button ("Save to Notebase")
  • action.saveToNotebaseSaving: Label shown while saving ("Saving...")
  • action.saveToNotebaseSuccess: Success message after saving ("Saved to Notebase")
  • action.saveToNotebaseFailed: Error message when save fails ("Failed to save to Notebase")
  • action.saveToNotebaseLoginRequired: Error message when user is not authenticated
  • action.saveToNotebaseBetaRequired: Error message when user is not enrolled in Notebase beta
  • action.saveToNotebaseTableUnavailable: Error message when selected notebase is unavailable
  • action.saveToNotebaseConnectionInvalid: Error message when notebase connection is invalid
  • action.saveToNotebaseNoMappings: Error message when no valid mappings exist

These action buttons appear in popover footers with tooltip support. The copy button displays a success state after copying text to the clipboard, while the speak button integrates with the TTS system and shows different states (speak, playing, loading). The translation key is used for the toolbar button tooltip to provide an accessible label. The "Save to Notebase" button (added in PR #1215) validates mappings and saves structured output to the configured notebase, with clear error feedback for authentication, beta access limitations, unavailable notebases, invalid connections, and missing mappings.

Example:

action:
  copy: Copy
  copied: Copied
  regenerate: Regenerate
  translation: Translation
  speak: Speak
  playing: Playing
  saveToNotebase: Save to Notebase
  saveToNotebaseSaving: Saving...
  saveToNotebaseSuccess: Saved to Notebase
  saveToNotebaseFailed: Failed to save to Notebase

Target Language Selector#

The translation popover in the selection toolbar includes an inline target language selector that allows users to change the translation target language without navigating to the settings page. The selector is a searchable combobox that uses existing language-related i18n keys:

Language Selector Keys:
The target language selector reuses keys from other parts of the UI:

  • side.targetLang: Label for the target language selector ("Target Language")
  • translationHub.searchLanguages: Placeholder for the language search input
  • translationHub.noLanguagesFound: Message shown when no languages match the search

The selector displays the currently selected target language as a button with a dropdown arrow. Clicking opens a searchable list of available target languages. When a user selects a new language, the configuration is updated and the translation is automatically regenerated with the new target language.

Example:

side:
  targetLang: Target Language

translationHub:
  searchLanguages: Search languages
  noLanguagesFound: No languages found

The target language selector integrates seamlessly with the selection popover's compound component architecture, using the useSelectionPopoverOverlayProps hook to ensure dropdown overlays render in the correct z-index layer within the shadow DOM.

Thinking Indicator#

The selection toolbar includes a real-time thinking indicator that displays AI processing status and reasoning steps during streaming responses. The thinking indicator appears in Translation and Custom AI Action popovers, providing localized feedback while AI responses stream. The indicator is implemented as a collapsible component that shows the AI's reasoning process.

Thinking Indicator Keys:
The thinking indicator uses the following i18n keys under the thinking namespace:

  • thinking.label: Label displayed during active thinking/processing ("Thinking...")
  • thinking.complete: Label shown when thinking is complete ("Thinking complete")
  • thinking.expand: Aria-label for the expand action button ("Expand thinking")
  • thinking.collapse: Aria-label for the collapse action button ("Collapse thinking")

The thinking indicator supports both active ("thinking") and complete ("complete") states. When content is available, the indicator becomes collapsible, allowing users to expand or collapse the reasoning text. The component includes auto-scroll functionality that follows new content as it streams, with manual scroll detection to preserve user intent.

Example:

thinking:
  label: Thinking
  complete: Thinking complete
  expand: Expand thinking
  collapse: Collapse thinking

The thinking indicator integrates with the background streaming infrastructure, consuming ThinkingSnapshot objects that include status and text content. This feature was introduced in PR #1107 to provide clearer feedback during LLM-based operations.

Adding Custom Actions i18n#

When extending custom AI actions functionality:

  1. Add new keys under options.floatingButtonAndToolbar.selectionToolbar.customActions in en.yml
  2. Propagate to all 8 supported locale files with appropriate translations
  3. For error messages using placeholders, use the $1 format for positional arguments
  4. If adding new data types, add them under the top-level dataTypes key

The refactored custom AI actions UI includes improved field management with dialog-based editing and template-based creation workflow. These enhancements introduce new i18n keys for field descriptions, add/edit/delete dialogs, and template content, all of which have been localized across all supported languages (en, ja, ko, ru, tr, vi, zh-CN, zh-TW).

Custom AI actions serve as a case study for comprehensive i18n support across a complex user-defined feature, including configuration UI, runtime interaction, validation, and error handling.

Translation Hub#

The Translation Hub provides a dedicated interface for comparing translations from multiple providers side-by-side. The hub includes card expansion/collapse controls for managing the display of translation results.

Translation Hub i18n Keys#

Translation Hub UI elements are localized under the translationHub namespace:

Card Expansion Controls:

  • expandCard: Tooltip/aria-label for the expand button on individual cards ("Expand card")
  • collapseCard: Tooltip/aria-label for the collapse button on individual cards ("Collapse card")
  • expandAllCards: Tooltip/aria-label for the expand all button in the toolbar ("Expand all")
  • collapseAllCards: Tooltip/aria-label for the collapse all button in the toolbar ("Collapse all")

These keys enable users to expand or collapse individual translation cards to view or hide their content. The toolbar provides bulk actions to expand all cards or collapse all cards at once for efficient space management when comparing multiple provider results.

Other Translation Hub Keys:

  • translate: Button label for initiating translation
  • copiedToClipboard: Success message when translation is copied
  • copyTranslation: Button label for copying translation
  • deleteCard: Button label for removing a provider card
  • translationFailed: Error title when translation fails
  • translationFailedFallback: Fallback error message

Example:

translationHub:
  translate: Translate
  copiedToClipboard: Translation copied to clipboard!
  copyTranslation: Copy translation
  expandCard: Expand card
  collapseCard: Collapse card
  expandAllCards: Expand all
  collapseAllCards: Collapse all
  deleteCard: Delete card
  translationFailed: Translation Failed
  translationFailedFallback: Translation failed

The expansion state is tracked per provider and persists during the session. Cards default to expanded state, and the expansion state is cleared when a provider is removed from the hub.

Error Recovery Interface#

The extension includes a recovery boundary component that displays when critical errors occur, such as during initialization or configuration loading. This interface is localized under the errorRecovery namespace:

Main UI:

  • title: Error screen title ("Something went wrong")
  • description: Explanation of recovery mode
  • errorDetails: Label for error message display
  • backupTitle: Section header for export actions
  • recoveryTitle: Section header for recovery options (replaces resetTitle)
  • refreshPage: Button text for refreshing the page

Export Actions:

  • exportWithApiKeys: Button label for full export including sensitive data
  • exportWithoutApiKeys: Button label for export without API keys

Reset Actions:

  • resetAction: Button label for resetting settings
  • resetSuccess: Success message after reset
  • resetFailed: Error message if reset fails

Reset Confirmation Dialog:

  • resetDialog.title: Dialog title ("Reset settings?")
  • resetDialog.description: Warning about replacing current settings
  • resetDialog.confirm: Confirm button label
  • resetDialog.cancel: Cancel button label

Example:

errorRecovery:
  title: Something went wrong
  description: Recovery mode is active. You can export your current settings as a backup, then reset settings and try again.
  backupTitle: Backup current settings first (recommended)
  exportWithApiKeys: Export with API Keys
  exportWithoutApiKeys: Export without API Keys
  recoveryTitle: Recovery options
  refreshPage: Refresh the page
  resetAction: Reset to default settings
  resetSuccess: Recovery completed. Settings have been reset
  resetFailed: Recovery failed. Unable to reset settings
  errorDetails: Error details
  resetDialog:
    title: Reset settings?
    description: This will replace your current settings with the default values.
    confirm: Reset
    cancel: Cancel

The recovery boundary is used in both the popup and options pages to provide graceful degradation when the extension encounters unrecoverable errors.

Sidebar group labels are localized under options.sidebar.settings and options.sidebar.product. The survey navigation item is localized under options.survey.title in all locale files.

The sidebar includes a "What's New" footer component that displays the latest blog post preview in a popover. This feature has moved from the product navigation to a dedicated WhatsNewFooter component located in the sidebar footer.

i18n Key:

  • options.whatsNew.title: Label for the "What's New" footer button (displays an RSS icon)

The footer button uses the key options.whatsNew.title to label the RSS icon button. When clicked, it opens a popover at the bottom of the sidebar displaying:

  • Blog post title (as a clickable external link to the full post)
  • Blog post description
  • Optional embedded video preview (Bilibili videos when available)

The popover automatically opens when a new blog post is detected (comparing the latest blog post date with the user's last viewed date). Once opened, the post is marked as viewed. The feature tracks unread status using blog storage utilities and does not sync popover state through configuration.

Example:

options:
  whatsNew:
    title: What's New

This footer component replaced the previous "What's New" entry in the product navigation section, providing a richer preview experience with inline blog content and video embeds.

Blog Locale Resolution:
Blog content is locale-aware and automatically fetched based on the user's UI language. The extension detects the UI locale using getBlogLocaleFromUILanguage(), which maps UI locales to blog API locales:

  • Chinese locales (those starting with "zh", like zh-CN, zh-TW) map to "zh"
  • All other locales default to "en"

This locale resolution is performed by resolveBlogLocale(), which normalizes the UI locale and returns either "en" or "zh" as the blog locale. The resolution applies to both the popup blog notification component and the What's New footer in the options sidebar, ensuring users see blog content in their preferred language when available.

Blog System Localization#

The website's blog system uses the blog namespace in locale files for all blog-related UI strings, including titles, descriptions, navigation, author/date labels, sharing, and minimum extension version requirements. To add or update blog UI strings, add new keys under blog in each locale file.

Example:

"blog": {
  "title": "Read Frog Blog",
  "description": "Latest updates, guides, and insights about Read Frog",
  "extensionVersion": "Extension Version"
}

Feature Providers Configuration#

The Feature Providers section (options.general.featureProviders) allows users to select which provider should be used for each feature. This section includes:

  • title: "Feature Providers"
  • description: "Choose which provider to use for each feature"
  • customActions: Label for the custom AI actions subsection
  • features: A subsection containing localized labels for each feature:
    • translate: "Page Translation"
    • selectionToolbar_translate: "Selection Toolbar Translation"
    • inputTranslation: "Input Translation"
    • videoSubtitles: "Video Subtitles"

Example:

options:
  general:
    featureProviders:
      title: Feature Providers
      description: Choose which provider to use for each feature
      customActions: Custom AI Actions
      features:
        translate: Page Translation
        selectionToolbar_translate: Selection Toolbar Translation
        inputTranslation: Input Translation
        videoSubtitles: Video Subtitles

Note: TTS is no longer a configurable feature provider. Edge TTS is now the built-in provider for text-to-speech functionality.

Custom AI actions appear in this section alongside built-in features. Each custom action displays its user-defined name and allows provider selection from enabled LLM providers. Provider assignments for custom AI actions can also be managed in the Feature Providers section of individual provider configuration forms.

Feature Key to i18n Key Mapping#

Feature keys in the codebase use dot notation (e.g., selectionToolbar.translate), but YAML does not support dots in keys. To maintain YAML compatibility, feature keys are mapped to underscore notation for i18n lookup using the FEATURE_KEY_I18N_MAP:

  • translatetranslate
  • videoSubtitlesvideoSubtitles
  • selectionToolbar.translateselectionToolbar_translate
  • inputTranslationinputTranslation

This mapping ensures that feature labels can be retrieved from locale files using underscore-based keys while maintaining dot notation in the application code.

Provider Badges#

Provider cards display a badge showing how many features are assigned to that provider. The badge uses the i18n key options.apiProviders.badges.featureCount with a placeholder for the count (e.g., "$1 features"). When hovered, a tooltip displays the list of assigned features using the feature labels from options.general.featureProviders.features. Custom AI actions use their user-defined names in the tooltip.

Note: The previous badge key options.apiProviders.badges.translate has been replaced by options.apiProviders.badges.featureCount.

Feature Provider Section in Provider Form#

When configuring a provider, a collapsible "Feature Providers" section appears if the provider is compatible with any features. This section is labeled using the key options.apiProviders.form.featureProviders and allows users to assign features to the provider. For LLM providers, custom AI actions also appear in this section, allowing users to reassign them to different providers.

API Providers Test Connection and Clear Cache#

  • Test Connection: Keys under options.apiProviders.testConnection for the "Test Connection" button and loading state.
  • Clear Cache: Keys under options.general.clearCache for the clear cache action and dialog.
  • Duplicate Name Error: The key options.apiProviders.duplicateProviderName displays an error when a provider name conflicts with an existing one, using the $1 placeholder for the duplicate name.

Example:

duplicateProviderName: 'Duplicate provider name "$1"'

Theme Mode Configuration#

The extension supports manual theme mode switching with three options: system (follows OS preference), light, and dark. Theme settings appear in both the popup and options page. Localization keys for theme mode are organized under the popup and options.general.appearance namespaces.

Popup Keys:

  • popup.theme: "Theme" - Label for the theme selector in the popup

Settings Page Keys:
Under options.general.appearance:

  • title: "Appearance" - Section title
  • theme: "Theme" - Label for the theme dropdown
  • system: "System" - Label for system mode option (follows OS preference)
  • light: "Light" - Label for light mode option
  • dark: "Dark" - Label for dark mode option

The theme mode setting uses a dropdown selector in the options page, with each option displaying an icon (desktop for system, sun for light, moon for dark). The setting persists independently from the main configuration to avoid unnecessary re-renders.

Example:

popup:
  theme: Theme

options:
  general:
    appearance:
      title: Appearance
      theme: Theme
      system: System
      light: Light
      dark: Dark

These keys were added consistently across all 8 supported language files (en.yml, ja.yml, ko.yml, ru.yml, tr.yml, vi.yml, zh-CN.yml, zh-TW.yml) in PR #1065. When adding new UI settings that appear in multiple contexts (popup and options page), ensure all related keys are added consistently across all language files.

Site Control Localization#

The site control feature allows users to control where the extension is active using two modes: blacklist (disable on specific sites) and whitelist (enable only on specific sites). Localization keys for site control are organized under both the popup and options.siteControl namespaces.

Popup Keys:

  • popup.addToWhitelist: "Enable extension on this site" - Toggle label shown in the popup when whitelist mode is active
  • popup.addToBlacklist: "Disable extension on this site" - Toggle label shown in the popup when blacklist mode is active

Settings Page Keys:
Under options.siteControl.mode:

  • title: "Extension Activation Mode"
  • description: Explains both blacklist and whitelist modes
  • blacklist: "Only disable on listed sites" - Label for blacklist mode option
  • whitelist: "Only run on listed sites" - Label for whitelist mode option

Under options.siteControl.patterns:

  • enterUrlPattern: Placeholder text for URL pattern input
  • urlPattern: Column header for the patterns table

Configuration Structure:
The site control configuration uses two separate pattern arrays:

  • blacklistPatterns: Array of URL patterns where the extension is disabled (used when mode is "blacklist")
  • whitelistPatterns: Array of URL patterns where the extension is enabled (used when mode is "whitelist")

The default mode is "blacklist". Each mode displays and edits its corresponding pattern array in the settings UI.

Example:

popup:
  addToWhitelist: Enable extension on this site
  addToBlacklist: Disable extension on this site

options:
  siteControl:
    title: Site Control
    mode:
      title: Extension Activation Mode
      description: Use blacklist mode to disable the extension on specific sites, or whitelist mode to limit it to specific sites only.
      blacklist: Only disable on listed sites
      whitelist: Only run on listed sites
    patterns:
      enterUrlPattern: Enter URL pattern (e.g., example.com)
      urlPattern: URL Pattern

Key Changes in PR #1061:

  • Added popup.addToBlacklist for the new blacklist mode toggle in the popup
  • Updated options.siteControl.mode.description to explain both blacklist and whitelist modes
  • Added options.siteControl.mode.blacklist to replace the removed mode.all option
  • Removed options.siteControl.patterns.title and options.siteControl.patterns.description as the patterns UI is now mode-agnostic (displays for both blacklist and whitelist)
  • Split configuration from single patterns array into separate blacklistPatterns and whitelistPatterns arrays
  • Changed default mode from "all" to "blacklist"
  • Migration script (v058 to v059) automatically converts old "all" mode to "blacklist" and migrates existing patterns to whitelistPatterns

These changes were applied consistently across all 8 supported language files (en.yml, ja.yml, ko.yml, ru.yml, tr.yml, vi.yml, zh-CN.yml, zh-TW.yml). When adding new modes or removing old ones, all related keys must be added/removed consistently across all language files to maintain UI coherence.

Supported Languages#

The extension supports English, Japanese, Korean, Simplified Chinese, Traditional Chinese, Russian, Vietnamese, and Turkish. The website currently supports English and Simplified Chinese. Language display names are mapped in the language section of each locale file.

Internationalization Frameworks#

  • Website: Uses next-intl for i18n, with locale configuration and routing in TypeScript. Translations are accessed via hooks like useTranslations.
  • Extension: Loads YAML locale files and retrieves translations by key.

Updating Locale Entries#

When adding new features or providers:

  1. Add new translation keys and values to the canonical (usually English) locale file.
  2. Propagate these keys to all other supported locale files, providing translations for each.
  3. For provider groups, ensure both title and description are present for each group in every language.

Major i18n updates:

  • PR #993: Updated TTS-related keys across all locale files
  • PR #1020: Added comprehensive custom AI actions localization with 74+ new keys across all 8 supported languages (en, ja, ko, ru, tr, vi, zh-CN, zh-TW)
  • PR #1051: Refactored custom AI actions with template-based creation and dialog-based field management, adding 100+ new template keys including extensive system prompts with examples for dictionary and improve writing templates
  • PR #1061: Added blacklist mode for site control, updating mode-related keys across all locale files
  • PR #1065: Added theme mode configuration keys for popup and options page appearance settings across all locale files
  • PR #1075: Added translation hub card expansion/collapse controls with 4 new i18n keys
  • PR #1105: Refactored selection toolbar with SelectionPopover compound component, added inline target language selector, and introduced action.* keys for popover action buttons (copy, regenerate, speak)
  • PR #1107: Added thinking indicator with 4 new thinking.* keys, and selection toolbar tooltip key (action.translation) for improved accessibility
  • PR #1108: Renamed "Custom AI Features" to "Custom AI Actions" across all localization keys (customFeaturescustomActions)
  • PR #1109: Added selection toolbar inline error handling with 6 new error keys under options.floatingButtonAndToolbar.selectionToolbar.errors
  • PR #1111: Added centralized language detection configuration with 9 new keys under options.general.languageDetection, added customActions.form.fieldSpeaking for TTS dictionary support, and added languageDetection.llmFailed error key; removed per-feature detection keys (translate.page.enableLLMDetection, translate.page.enableSkipLanguagesLLMDetection, tts.detectLanguageMode)
  • PR #1115: Added selection toolbar feature toggles with 4 new keys under options.floatingButtonAndToolbar.selectionToolbar.featureToggles to enable individual control over built-in features (translate, speak)
  • PR #1117: Added drag-and-drop reordering support for custom action cards in the settings sidebar and output schema fields within custom actions using the SortableList component
  • PR #1121: Updated improve writing template prompt with {{originLanguage}} detection, 4-point language policy (previously 3 points), and revised example format with language annotations; replaced Example B with Japanese original text demonstrating verb conjugation errors
  • PR #1127: Added localized provider descriptions for three new AI providers (alibaba, moonshotai, huggingface) across all 8 supported languages
  • PR #1126: Added selection toolbar opacity configuration with 2 new keys under options.floatingButtonAndToolbar.selectionToolbar.opacity to control transparency of the toolbar and popovers
  • PR #1152: Added provider options recommendation keys with 5 new keys under options.apiProviders.form.providerOptionsRecommendation* to support manual preview and application of recommended provider options
  • PR #1171: Added context menu selection translation and custom action support with 1 new key (contextMenu.translateSelection) and updated context menu configuration description
  • PR #1215: Added notebase integration for custom AI actions with 34+ new keys under options.floatingButtonAndToolbar.selectionToolbar.customActions.form.notebase for connection configuration and field mapping, plus 8 new keys under action.saveToNotebase* for the save button and error handling
  • PR #1230: Added Notebase beta access gating with 3 new keys (form.notebase.betaLockedTitle, form.notebase.betaLockedDescription, action.saveToNotebaseBetaRequired) to handle non-beta accounts attempting to use Notebase features

Context Menu Localization#

The browser context menu (right-click menu) supports page translation, selection translation, and custom AI actions. Context menu entries are localized under the contextMenu namespace:

Context Menu Keys:

  • contextMenu.translate: Label for page translation ("Translate")
  • contextMenu.translateSelection: Label for selection translation with selected text placeholder ("Translate "%s"")

When the context menu translate option is enabled in settings (options.general.contextMenu.translate.title), users will see different context menu entries depending on the context:

  • "Translate" option when right-clicking on the page (for full page translation)
  • "Translate "%s"" option when right-clicking on selected text (for selection translation via the selection toolbar)
  • Custom action entries when right-clicking on selected text (if custom actions are configured and enabled)

Custom AI actions appear as individual entries in the browser's context menu when text is selected. These entries use the user-defined action names and trigger the same popover UI and execution flow as the selection toolbar. The context menu integration allows users to access both built-in translation and custom AI actions directly from the right-click menu.

Context Menu Configuration:
The context menu translate feature is configured under options.general.contextMenu.translate:

  • title: "Enable Context Menu Translate"
  • description: "Add translate options to the browser right-click menu for quick page and selection translation"

Example:

contextMenu:
  translate: Translate
  translateSelection: Translate "%s"

options:
  general:
    contextMenu:
      title: Context Menu
      translate:
        title: Enable Context Menu Translate
        description: Add translate options to the browser right-click menu for quick page and selection translation

The context menu entries are dynamically updated when configuration changes. Selection translation and custom actions share the same selection snapshot and recovery mechanism, allowing seamless interaction between the context menu and selection toolbar.

Example: Adding a New Provider Group#

English:

options:
  apiProviders:
    dialog:
      groups:
        newGroup:
          title: New Group Title
          description: Description for the new provider group

Simplified Chinese:

options:
  apiProviders:
    dialog:
      groups:
        newGroup:
          title: 新分组标题
          description: 新提供商分组的描述

Language Detection Configuration#

Language detection is configured centrally in the General settings page under options.general.languageDetection. This centralized configuration affects auto-translate language detection, skip-language detection, and TTS voice selection accuracy across all features.

Language Detection i18n Keys:
Under options.general.languageDetection:

  • title: Section title ("Language Detection")
  • description: Brief description explaining what features are affected by this setting
  • mode.basic: Label for basic (browser-based) detection mode
  • mode.llm: Label for LLM-based detection mode
  • provider.label: Label for the provider selector ("Detection Provider")
  • provider.placeholder: Placeholder text for provider selection
  • status.noProviders: Status message when no LLM providers are configured
  • status.basicRecommend: Status message recommending LLM when in basic mode
  • status.llmEnabled: Status message when LLM detection is enabled

Error Messages:
Under the top-level languageDetection namespace:

  • llmFailed: Error message displayed when LLM detection fails and falls back to basic detection

Example:

options:
  general:
    languageDetection:
      title: Language Detection
      description: Affects auto-translate language detection, skip-language detection, and Speaking voice selection accuracy.
      mode:
        basic: Basic
        llm: LLM
      provider:
        label: Detection Provider
        placeholder: Select a provider
      status:
        noProviders: Configure an LLM provider first
        basicRecommend: Recommend enabling LLM
        llmEnabled: LLM detection enabled

languageDetection:
  llmFailed: LLM language detection failed, fell back to basic detection

Configuration Structure:
The language detection configuration uses the following schema:

  • mode ('basic' | 'llm'): Detection mode
  • providerId (string, optional): ID of the LLM provider to use for detection (required when mode is 'llm')

The UI displays a status indicator with different colors and messages:

  • Orange: No LLM providers configured
  • Blue: Basic mode active, LLM recommended
  • Green: LLM detection enabled

Feature Integration:
This centralized configuration replaces the previous per-feature detection settings:

  • translate.page.enableLLMDetection (removed)
  • translate.page.enableSkipLanguagesLLMDetection (removed)
  • tts.detectLanguageMode (removed)

All features that require language detection (auto-translate, skip-languages, TTS voice selection) use the centralized configuration. Migration scripts (v061 to v062) automatically convert old per-feature settings to the unified configuration.

Note: When LLM detection mode is enabled but fails at runtime, the system automatically falls back to basic detection and displays the languageDetection.llmFailed error message.

Language Detection Configuration (Legacy)#

For reference, the previous per-feature language detection settings used nested locale keys under options.translation.autoTranslateLanguages.detection and options.translation.skipLanguages.detection:

autoTranslateLanguages:
  title: Auto Translate Based on Language
  description: Automatically translate page content when specific languages are detected
  selectLanguages: Select languages
  detection:
    label: Language Detection
    basic: Basic
    llm: LLM
    description: Basic detection is fast and free. LLM detection is more accurate but adds latency and API costs. Requires configured auto-translate languages.

The detection object includes:

  • label: Section label for the detection toggle
  • basic: Label for basic detection mode
  • llm: Label for LLM-based detection mode
  • description: Explanatory text describing both modes

Deprecation Notice: These per-feature detection keys have been replaced by the centralized Language Detection configuration in PR #1111. The above structure is preserved for reference only.

LLM Provider Status Messages#

LLM provider status messages include a feature name parameter for context. The keys options.translation.llmProviderConfigured and options.translation.llmProviderNotConfigured use the $1 placeholder for feature name interpolation:

  • llmProviderConfigured: "LLM provider selected for $1"
  • llmProviderNotConfigured: "No LLM provider selected for $1"

At runtime, $1 is replaced with the feature name (e.g., "Page Translation").

Translate Range Configuration#

The translate range setting has moved from options.general.translationConfig.translateRange to options.translation.translateRange. This top-level section includes:

  • title: "Translate Range"
  • description: "Select whether to translate only the main content or all content on the page."
  • range.main: "Main Content"
  • range.all: "All Content"

Example:

options:
  translation:
    translateRange:
      title: Translate Range
      description: Select whether to translate only the main content or all content on the page.
      range:
        main: Main Content
        all: All Content

Dynamic Content and Placeholders#

Locale entries can include placeholders (e.g., {year}, {name}, $1, $2) for dynamic substitution at runtime. The $1, $2 placeholder format is used for positional arguments in various contexts:

  • Feature count badges: options.apiProviders.badges.featureCount displays the number of assigned features using $1
  • LLM provider status: Status messages include the feature name via $1 placeholder
  • Error messages: Validation errors for duplicate names, provider-in-use warnings, etc. use $1 and $2 for dynamic values
  • Custom AI actions: duplicateName and other validation errors interpolate values using $1

Examples:

# Single placeholder
duplicateName: 'Duplicate action name "$1"'
badges:
  featureCount: $1 features

# Multiple placeholders
providerInUseCannotDisable: 'Cannot disable "$1" because it is currently used by $2 action(s).'

Extensibility#

To add a new language, create a new locale file with the same structure as the canonical file and provide translations for all keys.

References#

This structure ensures all UI elements, provider groups, and navigation items are fully localized and easy to maintain as the project evolves.