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 asAlt+Tinternally but rendered asOption+Tin 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 whenconfig.hotkeyis 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+TShift+TAlt+Shift+TCtrl+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:
- The component captures raw
keydownevents and converts them to a normalized string representation - 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) - It checks for conflicts with common OS shortcuts (like
Ctrl+Cfor copy) using thevalidateHotkeyConflictsfunction - Upon confirmation, it sets
config.hotkey = 'custom'and stores the raw string inconfig.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 syntaxdisplayName: Platform-aware string (e.g.,Ctrl+Alt+Ton Windows,Control+Option+Ton macOS)
Key parsing rules implemented in hotkey.ts:
- Supports
ctrl,alt,shift, andmeta(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:
- It verifies that all required modifiers in
parsedHotkey.modifiersare currently active in the event - It checks if the event's
keyorcodematches theparsedHotkey.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
configobject (config.hotkeyandconfig.customHotkey) defined inentrypoints/utils/model.ts. - The default translation hotkey is
Alt+T(Windows/Linux) orOption+T(macOS). - Users can select from preset hotkeys in
components/Main.vueor define custom combinations viaCustomHotkeyInput.vue. - The
parseHotkey()function inentrypoints/utils/hotkey.tsvalidates syntax and requires at least one modifier key to prevent typing interference. - The
matchesHotkey()function checks keyboard events against the parsed configuration inentrypoints/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →