Don't have TanStack Hotkeys installed yet? See the Installation page for instructions.
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.
constructor() {
injectHotkey('Mod+S', () => save())
injectHotkey('Mod+Z', () => undo())
injectHotkey('Mod+Shift+Z', () => redo())
injectHotkey('Mod+F', () => openSearch())
injectHotkey('Escape', () => closeDialog())
}
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,
}))
}
}
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(),
}))
}
}
import { injectHotkeySequence } from '@tanstack/angular-hotkeys'
constructor() {
injectHotkeySequence(['G', 'G'], () => scrollToTop())
injectHotkeySequence(['G', 'Shift+G'], () => scrollToBottom())
}
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')
}
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())
}
}
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({
hotkey: { preventDefault: true },
hotkeySequence: { timeout: 1500 },
hotkeyRecorder: { onCancel: () => console.log('Recording cancelled') },
}),
],
}