How to Customize Hotkeys for Translation in FluentRead: A Complete Guide

FluentRead allows full customization of translation hotkeys through both preset options and custom key combinations, storing your preferences in config.hotkey and validating them via the hotkey.ts utility module.

FluentRead is an open-source browser extension that provides instant translation on mouse hover. Customizing hotkeys for translation in FluentRead enables you to trigger the translation feature using your preferred key combination, improving workflow efficiency and avoiding conflicts with existing browser shortcuts.

Understanding the Hotkey System Architecture

The hotkey system in FluentRead centers on a global config object defined in entrypoints/utils/model.ts. This object stores the current hotkey configuration, including the active hotkey string and any user-defined custom combination.

The actual processing of hotkey strings occurs in entrypoints/utils/hotkey.ts. This module provides the parseHotkey() function to convert string representations like "Ctrl+Alt+T" into structured objects, and the matchesHotkey() function to compare keyboard events against the configured shortcut.

Finally, entrypoints/content.ts registers the global keyboard listeners that use these utilities to detect when your configured hotkey is pressed, setting screen.hotkeyPressed = true to trigger the translation flow.

Default Translation Hotkey Configuration

By default, FluentRead uses platform-aware shortcuts to avoid conflicts with operating system commands. The default values are defined in entrypoints/utils/model.ts at lines 84-86:

  • Windows/Linux: Alt+T
  • macOS: Option+T (displayed as Alt+T internally but rendered as Option+T in the UI)

The configuration model includes three relevant fields:

  • config.hotkey: Stores the current active hotkey identifier (either a preset key like "Alt+T" or the string "custom")
  • config.customHotkey: Stores the user-defined custom hotkey string when config.hotkey is set to "custom"
  • config.floatingBallHotkey: Separate hotkey specifically for the floating ball feature, defaulting to "Alt+T"

How to Customize Your Translation Hotkey

FluentRead provides two methods for customizing your translation hotkey: selecting from preset combinations or recording a completely custom key sequence.

Using the Settings UI (Preset Hotkeys)

The main settings interface in components/Main.vue presents a dropdown menu populated by the PRESET_HOTKEYS array defined in entrypoints/utils/hotkey.ts (lines 331-347). This list includes commonly used combinations that avoid system conflicts:

  • Alt+T (default)
  • Ctrl+T
  • Shift+T
  • Alt+Shift+T
  • Ctrl+Shift+T

Selecting any of these presets immediately updates config.hotkey to the selected string value.

Setting a Custom Hotkey Combination

For key combinations not listed in the presets, click "自定义快捷键…" (Custom Hotkey) in the settings panel. This opens the CustomHotkeyInput.vue component, which provides a real-time key recording interface:

  1. The component captures raw keydown events and converts them to a normalized string representation
  2. It calls parseHotkey() to validate the syntax and ensure the combination includes at least one modifier key (preventing single-letter shortcuts that would interfere with typing)
  3. It checks for conflicts with common OS shortcuts (like Ctrl+C for copy) using the validateHotkeyConflicts function
  4. Upon confirmation, it sets config.hotkey = 'custom' and stores the raw string in config.customHotkey

The configuration is then persisted to local storage via config.ts.

Technical Implementation: Parsing and Matching Hotkeys

The entrypoints/utils/hotkey.ts file contains the core logic for processing hotkey strings and detecting when they are pressed.

The parseHotkey Function

The parseHotkey(hotkeyString) function transforms a human-readable shortcut like "Ctrl+Alt+T" into a structured ParsedHotkey object. This object contains:

  • modifiers: Array of modifier keys (ctrl, alt, shift, meta)
  • key: The normal key (e.g., t, F1, Enter)
  • isValid: Boolean indicating if the string follows valid syntax
  • displayName: Platform-aware string (e.g., Ctrl+Alt+T on Windows, Control+Option+T on macOS)

Key parsing rules implemented in hotkey.ts:

  • Supports ctrl, alt, shift, and meta (Windows key) as modifiers
  • Recognizes letters, numbers, function keys (F1–F12), navigation keys, and symbols
  • Explicitly disables the Meta/Cmd key on macOS (lines 47-55) to avoid conflicts with system shortcuts
  • Requires at least one modifier for single-letter keys to prevent blocking normal typing

Event Matching with matchesHotkey

When a keyboard event fires, the matchesHotkey(event, parsedHotkey) function (also in hotkey.ts) determines if the pressed keys match the configured shortcut:

  1. It verifies that all required modifiers in parsedHotkey.modifiers are currently active in the event
  2. It checks if the event's key or code matches the parsedHotkey.key, including special mappings for non-standard keys

In entrypoints/content.ts (around lines 46-55), when matchesHotkey returns true, FluentRead sets screen.hotkeyPressed = true. The actual translation triggers once all keys are released, ensuring the hotkey doesn't interfere with other shortcuts that might use the same modifiers.

Programmatic Hotkey Configuration

Developers and advanced users can manipulate hotkey settings programmatically using the FluentRead configuration API.

Setting a Custom Hotkey via Browser Console

You can dynamically change the hotkey from the browser console using the config module:

import { config } from '@/entrypoints/utils/config';
import { parseHotkey } from '@/entrypoints/utils/hotkey';

// Validate the desired combination first
const parsed = parseHotkey('Ctrl+Alt+T');
if (parsed.isValid) {
  // Set to custom mode and store the validated string
  config.hotkey = 'custom';
  config.customHotkey = parsed.displayName; // "Ctrl+Alt+T"
}

Detecting the Hotkey in Custom Scripts

To listen for the configured hotkey in your own extension scripts:

import { parseHotkey, matchesHotkey } from '@/entrypoints/utils/hotkey';
import { config } from '@/entrypoints/utils/config';

// Retrieve the current hotkey configuration
const hotkeyString = config.hotkey === 'custom' ? config.customHotkey : config.hotkey;
const hotkeyInfo = parseHotkey(hotkeyString);

window.addEventListener('keydown', e => {
  if (matchesHotkey(e, hotkeyInfo)) {
    console.log('Translation hotkey pressed!');
    // Execute custom translation logic here
  }
});

Vue Component Integration

When building custom settings interfaces, you can integrate the hotkey input component:

<template>
  <CustomHotkeyInput
    v-model="dialogVisible"
    :currentValue="config.hotkey === 'custom' ? config.customHotkey : ''"
    @confirm="onHotkeyConfirmed"
    @cancel="dialogVisible = false"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import CustomHotkeyInput from '@/components/CustomHotkeyInput.vue';
import { config } from '@/entrypoints/utils/config';

const dialogVisible = ref(false);

function onHotkeyConfirmed(newHotkey: string) {
  config.hotkey = 'custom';
  config.customHotkey = newHotkey;
  dialogVisible.value = false;
}
</script>

Platform-Specific Considerations

FluentRead implements platform-aware hotkey handling to ensure compatibility across operating systems.

macOS Restrictions

The parseHotkey function in entrypoints/utils/hotkey.ts explicitly disables the Meta (Command) key on macOS (lines 47-55). This prevents conflicts with system-level shortcuts like Cmd+C (copy) and Cmd+V (paste). macOS users must use Ctrl, Option (Alt), Shift, or function keys for their translation shortcuts.

Display Name Localization

The system generates platform-appropriate display names for hotkeys. For example, the same internal representation renders as:

  • Windows/Linux: Ctrl+Alt+T
  • macOS: Control+Option+T

This localization occurs in hotkey.ts (lines 75-85) and ensures the settings UI displays familiar key names to users on each platform.

Summary

  • FluentRead stores hotkey preferences in the global config object (config.hotkey and config.customHotkey) defined in entrypoints/utils/model.ts.
  • The default translation hotkey is Alt+T (Windows/Linux) or Option+T (macOS).
  • Users can select from preset hotkeys in components/Main.vue or define custom combinations via CustomHotkeyInput.vue.
  • The parseHotkey() function in entrypoints/utils/hotkey.ts validates syntax and requires at least one modifier key to prevent typing interference.
  • The matchesHotkey() function checks keyboard events against the parsed configuration in entrypoints/content.ts.
  • macOS users cannot use the Command (Meta) key due to explicit restrictions in the hotkey parser (lines 47-55 of hotkey.ts).
  • Configuration persists to local storage via entrypoints/utils/config.ts.

Frequently Asked Questions

Can I use the Command key on macOS for FluentRead hotkeys?

No, FluentRead explicitly disables the Meta (Command) key on macOS to prevent conflicts with system shortcuts. According to the source code in entrypoints/utils/hotkey.ts (lines 47-55), the parser rejects any hotkey containing the Meta modifier on macOS platforms. You must use Control, Option, Shift, or function keys instead.

Where are custom hotkeys stored in FluentRead?

Custom hotkeys are stored in the browser's local storage via the config object managed by entrypoints/utils/config.ts. Specifically, when you set a custom hotkey, the system sets config.hotkey to the string "custom" and stores the actual key combination in config.customHotkey. The loadConfig() function in config.ts (lines 16-30) rehydrates these settings when the extension initializes.

How do I reset the hotkey to default in FluentRead?

To reset to the default hotkey, open the FluentRead settings panel (components/Main.vue) and select the default option from the preset dropdown, which sets config.hotkey back to "Alt+T" (or "Option+T" on macOS). Alternatively, you can programmatically reset it by setting config.hotkey = 'Alt+T' and config.customHotkey = '' using the browser console with the config module imported from @/entrypoints/utils/config.

Can I disable the hotkey entirely and use only the floating ball?

While the raw source analysis focuses on hotkey customization, FluentRead does support a floating ball feature with its own separate hotkey configuration (config.floatingBallHotkey). To effectively disable the main translation hotkey while keeping the floating ball, you would need to set the main hotkey to an unused combination or modify the configuration to bypass the matchesHotkey check in entrypoints/content.ts. However, the standard UI does not provide a "disable" toggle; you would need to clear the hotkey configuration programmatically by setting config.hotkey = '' and ensuring your content.ts logic handles empty strings appropriately.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →