PluginBench
Skill
Review
Audit score 70

hotkey

lobehub/lobehub

Add and manage keyboard shortcuts with scopes, conflict detection, and i18n support.

What is hotkey?

A framework for registering keyboard shortcuts in LobeHub applications. Use it to define new hotkeys with proper scoping, conflict checking, and localized tooltips across your UI components.

  • Define hotkey IDs and register default key combinations with scope constraints
  • Detect and warn about keyboard shortcut conflicts with system and browser shortcuts
  • Support platform-agnostic key modifiers (Ctrl/Cmd) via KeyEnum.Mod
  • Organize hotkeys into groups (System, Layout, Conversation) for better UX
  • Generate localized hotkey descriptions and titles via i18n
  • Attach hotkey tooltips to UI buttons and components

How to install hotkey

npx skills add https://github.com/lobehub/lobehub --skill hotkey
Prerequisites
  • Access to LobeHub monorepo structure (packages/types, packages/const, packages/locales, src/hooks)
  • Familiarity with TypeScript and React hooks
  • Understanding of i18n translation file structure
Claude Code
Cursor
Windsurf
Cline

How to use hotkey

  1. 1.Add the hotkey ID to the HotkeyId union type in packages/types/src/hotkey.ts
  2. 2.Register the hotkey with key combination and scope in packages/const/src/hotkeys.ts using HotkeyEnum and HOTKEYS_REGISTRATION
  3. 3.Add i18n translations for title and description in packages/locales/src/default/hotkey.ts
  4. 4.Create a custom hook (e.g., useSaveTopicHotkey) in src/hooks/useHotkeys/chatScope.ts that calls useHotkeyById with the action callback
  5. 5.Register the hook in useRegisterChatHotkeys so it activates in the correct scope
  6. 6.Optionally wrap UI components with Tooltip component passing the hotkey and title for user visibility

Use cases

Good for
  • Add a new save-topic shortcut (Alt+N) that only works in chat scope
  • Prevent accidental conflicts between app shortcuts and OS-level shortcuts
  • Display keyboard hints in tooltips so users discover available shortcuts
  • Organize conversation hotkeys separately from system-wide hotkeys
  • Support multiple languages for hotkey descriptions and UI labels
Who it's for
  • Frontend developers adding keyboard shortcuts to LobeHub
  • UI/UX designers defining interaction patterns with keyboard support
  • Localization teams translating hotkey descriptions
  • Application maintainers managing shortcut conflicts across features

hotkey FAQ

How do I prevent my hotkey from conflicting with browser shortcuts?

Use KeyEnum.Mod instead of hardcoded Ctrl or Cmd for cross-platform compatibility, choose an appropriate scope (e.g., chat-only), and test against common browser shortcuts. The HotkeyInput component shows conflict warnings.

What's the difference between global and chat scope?

Global scope makes the hotkey active everywhere in the app; chat scope restricts it to chat/conversation contexts. Choose based on where the action makes sense.

Do I need to add a tooltip for every hotkey?

No, tooltips are optional. Add them only when you want users to discover the shortcut in the UI. The hotkey still works without a tooltip.

How do I support multiple languages for hotkey descriptions?

Add translations to packages/locales/src/default/hotkey.ts for each language, then reference them in the Tooltip component using the i18n namespace 'hotkey'.

What if my hotkey isn't working after registration?

Check that the scope is activated (useRegisterChatHotkeys is called), verify the hotkey ID matches in all files, and ensure the callback function is correctly bound.

Full instructions (SKILL.md)

Source of truth, from lobehub/lobehub.


name: hotkey description: 'Use for keyboard shortcuts, registration, key combinations, scope, conflicts and shortcut tooltips.' user-invocable: false

Adding Keyboard Shortcuts Guide

Steps to Add a New Hotkey

1. Update Hotkey Constant

In packages/types/src/hotkey.ts, add the new id to the HotkeyId union — it's the source of truth HotkeyEnum is typed against:

export type HotkeyId =
  | 'addUserMessage'
  // existing...
  | 'saveTopic';

2. Register Default Hotkey

In packages/const/src/hotkeys.ts, KeyEnum and combineKeys are already defined locally in this file, so no import is needed — add the entry to HotkeyEnum and to HOTKEYS_REGISTRATION:

export const HotkeyEnum = {
  // existing...
  SaveTopic: 'saveTopic',
} as const satisfies Record<string, HotkeyId>;

export const HOTKEYS_REGISTRATION: HotkeyRegistration = [
  // existing...
  {
    group: HotkeyGroupEnum.Conversation,
    id: HotkeyEnum.SaveTopic,
    keys: combineKeys([KeyEnum.Alt, 'n']),
    scopes: [HotkeyScopeEnum.Chat],
  },
];

3. Add i18n Translation

In packages/locales/src/default/hotkey.ts:

const hotkey: HotkeyI18nTranslations = {
  saveTopic: {
    desc: '保存当前话题并新建一个话题',
    title: '保存话题',
  },
};

4. Create and Register Hook

In src/hooks/useHotkeys/chatScope.ts:

export const useSaveTopicHotkey = () => {
  const openNewTopicOrSaveTopic = useChatStore((s) => s.openNewTopicOrSaveTopic);
  return useHotkeyById(HotkeyEnum.SaveTopic, openNewTopicOrSaveTopic);
};

export const useRegisterChatHotkeys = () => {
  useSaveTopicHotkey();
  // ...other hotkeys
};

5. Add Tooltip (Optional)

const saveTopicHotkey = useUserStore(settingsSelectors.getHotkeyById(HotkeyEnum.SaveTopic));

<Tooltip hotkey={saveTopicHotkey} title={t('saveTopic.title', { ns: 'hotkey' })}>
  <Button icon={<SaveOutlined />} onClick={openNewTopicOrSaveTopic} />
</Tooltip>;

Best Practices

  1. Scope: Choose global or chat scope based on functionality
  2. Grouping: Place in appropriate group (System/Layout/Conversation)
  3. Conflict check: Ensure no conflict with system/browser shortcuts
  4. Platform: Use KeyEnum.Mod instead of hardcoded Ctrl or Cmd
  5. Clear description: Provide title and description for users

Troubleshooting

  • Not working: Check scope and RegisterHotkeys hook
  • Not in settings: Verify HOTKEYS_REGISTRATION config
  • Conflict: HotkeyInput component shows warnings
  • Page-specific: Ensure correct scope activation