Quick Start
Installation#
Don't have TanStack Hotkeys installed yet? See the Installation page for instructions.
Your first hotkey#
The injectHotkey API is the primary way to register keyboard shortcuts in Angular:
import { Component } from '@angular/core'
import { injectHotkey } from '@tanstack/angular-hotkeys'
@Component({
selector: 'app-root',
standalone: true,
template: `<div>Press Cmd+S (Mac) or Ctrl+S (Windows) to save</div>`,
})
export class AppComponent {
constructor() {
injectHotkey('Mod+S', () => {
saveDocument()
})
}
}The Mod modifier automatically resolves to Meta (Command) on macOS and Control on Windows/Linux, so your shortcuts work across platforms without extra logic.
Common patterns#
Multiple hotkeys#
constructor() {
injectHotkey('Mod+S', () => save())
injectHotkey('Mod+Z', () => undo())
injectHotkey('Mod+Shift+Z', () => redo())
injectHotkey('Mod+F', () => openSearch())
injectHotkey('Escape', () => closeDialog())
}Scoped hotkeys with viewChild#
import { Component, ElementRef, viewChild } from '@angular/core'
import { injectHotkey } from '@tanstack/angular-hotkeys'
@Component({
standalone: true,
template: `
<div #panel tabindex="0">
<p>Press Escape while focused here to close</p>
</div>
`,
})
export class PanelComponent {
private readonly panel = viewChild<ElementRef<HTMLDivElement>>('panel')
constructor() {
injectHotkey('Escape', () => closePanel(), () => ({
target: this.panel()?.nativeElement ?? null,
}))
}
}Conditional hotkeys#
import { Component, signal } from '@angular/core'
import { injectHotkey } from '@tanstack/angular-hotkeys'
@Component({ standalone: true, template: `` })
export class ModalComponent {
readonly isOpen = signal(true)
constructor() {
injectHotkey('Escape', () => this.isOpen.set(false), () => ({
enabled: this.isOpen(),
}))
}
}Multi-key sequences#
import { injectHotkey } from '@tanstack/angular-hotkeys'
constructor() {
// An array of chords registers a sequence
injectHotkey(['G', 'G'], () => scrollToTop())
injectHotkey(['G', 'Shift+G'], () => scrollToBottom())
}Tracking held keys#
import { Component } from '@angular/core'
import { injectHeldKeys, injectKeyHold } from '@tanstack/angular-hotkeys'
@Component({
standalone: true,
template: `
<div class="status-bar">
@if (isShiftHeld()) {
<span>Shift mode active</span>
}
@if (heldKeys().length > 0) {
<span>Keys: {{ heldKeys().join('+') }}</span>
}
</div>
`,
})
export class StatusBarComponent {
readonly heldKeys = injectHeldKeys()
readonly isShiftHeld = injectKeyHold('Shift')
}Displaying hotkeys in the UI#
import { Component } from '@angular/core'
import { formatForDisplay, injectHotkey } from '@tanstack/angular-hotkeys'
@Component({
standalone: true,
template: `<button>Save <kbd>{{ saveLabel }}</kbd></button>`,
})
export class SaveButtonComponent {
readonly saveLabel = formatForDisplay('Mod+S')
constructor() {
injectHotkey('Mod+S', () => save())
}
}Default options provider#
Use provideHotkeys to configure default options for your Angular app:
import { ApplicationConfig } from '@angular/core'
import { provideHotkeys } from '@tanstack/angular-hotkeys'
export const appConfig: ApplicationConfig = {
providers: [
provideHotkeys({
defaultOptions: {
hotkey: { preventDefault: true, timeout: 1500 },
hotkeyRecorder: { onCancel: () => console.log('Recording cancelled') },
},
}),
],
}Declaring app hotkeys#
To list every hotkey in a cheat sheet, including hotkeys whose components haven't mounted, and to let users customize them, declare them once with defineAppHotkeys and provide them with provideHotkeys. See the App Hotkeys Guide.
Next steps#
- Hotkeys Guide
- Sequences Guide
- Hotkey Recording Guide
- App Hotkeys Guide
- Key State Tracking Guide
- Formatting & Display Guide
Devtools#
Install the optional devtools packages to inspect registrations, held keys, and trigger counts:
npm install @tanstack/angular-devtools @tanstack/angular-hotkeys-devtoolsThe Angular devtools integration requires Angular 21 or newer. Follow the devtools setup guide to add the dock to your application.