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

> Customize translation hotkeys in FluentRead with ease. Learn how to set preset or custom key combinations for a seamless translation experience. Get started with our complete guide.

- Repository: [ThinkStu/fluentread](https://github.com/bistutu/fluentread)
- Tags: how-to-guide
- Published: 2026-02-26

---

**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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/components/Main.vue) presents a dropdown menu populated by the **`PRESET_HOTKEYS`** array defined in [`entrypoints/utils/hotkey.ts`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/config.ts).

## Technical Implementation: Parsing and Matching Hotkeys

The [`entrypoints/utils/hotkey.ts`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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:

```typescript
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:

```typescript
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:

```vue
<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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/components/Main.vue) or define custom combinations via [`CustomHotkeyInput.vue`](https://github.com/bistutu/fluentread/blob/main/CustomHotkeyInput.vue).
- The `parseHotkey()` function in [`entrypoints/utils/hotkey.ts`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/hotkey.ts)).
- Configuration persists to local storage via [`entrypoints/utils/config.ts`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/content.ts) logic handles empty strings appropriately.