DEV Community

Cover image for Exploring @HostListener in Angular — Decorator series -2 🔍
vetriselvan Panneerselvam
vetriselvan Panneerselvam

Posted on

2 2

Exploring @HostListener in Angular — Decorator series -2 🔍

Hey developers! 👋

Welcome back to our series on Angular decorators. In this post, we're diving into one of the lesser-discussed but incredibly powerful decorators in Angular: @HostListener. We’ll explore how to use it, how it gets compiled under the hood, and a few interesting use cases you may not have tried before.

🎯 What is @HostListener?

The @HostListener decorator allows you to listen to DOM events on the host element of a directive or component and run custom logic in response. It’s a clean way to bind events without touching the template.

🧠 Syntax

@HostListener(eventName: string, [args: string[]])
Enter fullscreen mode Exit fullscreen mode

🧪 Use Case 1: Listening to DOM Events on Host Element

Let’s start with a basic example where we listen to native DOM events like mouseover and mouseleave to dynamically apply styles.

We’ll create a directive that zooms in text when hovered.

✅ Step 1: The Directive

import { Directive, ElementRef, HostListener, inject, Renderer2 } from '@angular/core';

@Directive({
  selector: 'strong', // Applies to all <strong> elements
})
export class ZoomIn {
  private _el = inject(ElementRef);
  private renderer = inject(Renderer2);

  @HostListener('mouseover', ['$event'])
  mouseOver(event: MouseEvent) {
    this.renderer.addClass(this._el.nativeElement, 'zoom');
  }

  @HostListener('mouseleave', ['$event'])
  mouseLeave(event: MouseEvent) {
    this.renderer.removeClass(this._el.nativeElement, 'zoom');
  }
}
Enter fullscreen mode Exit fullscreen mode

✅ Step 2: The Component

import { Component } from '@angular/core';
import { ZoomIn } from '../../directive/zoom-in';

@Component({
  selector: 'app-about',
  standalone: true,
  imports: [ZoomIn],
  template: `
    <section>
      <h2>About Me</h2>
      <p>
        I’m a <strong>frontend developer</strong> with a strong focus on
        <strong>Angular</strong>, currently working with
        <strong>Angular 20</strong> and exploring advanced UI effects to enhance
        user experience.
      </p>
    </section>
  `,
  styleUrls: ['./about.scss'],
})
export class About {}
Enter fullscreen mode Exit fullscreen mode

✅ Step 3: Styles (about.scss)

.zoom {
  transition: transform 1s;
}

.zoom:hover {
  font-size: 20px;
  color: #81E7AF;
}
Enter fullscreen mode Exit fullscreen mode

🎉 Result: When a user hovers over any <strong> tag, the zoom effect kicks in!

Image description

🌐 Use Case 2: Listening to Global Events (Window, Document, etc.)

@HostListener isn’t limited to the host element. Angular also allows you to bind global events like window:resize.

Example:

@HostListener('window:resize', ['$event'])
onResize(event: Event) {
  console.log('Window resized', event);
}
Enter fullscreen mode Exit fullscreen mode

You can also listen to other global targets like document or body:

@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent) {
  console.log('Document clicked', event);
}
Enter fullscreen mode Exit fullscreen mode

🎹 Use Case 3: Listening to Specific Key Combinations

You can use @HostListener to capture specific key events—just like in plain JavaScript!

Example: Show an alert when Shift + I is pressed

@HostListener('window:keydown.shift.i', ['$event'])
onShortcut(event: KeyboardEvent) {
  alert('Info shortcut triggered!');
}
Enter fullscreen mode Exit fullscreen mode

This is super useful for building shortcuts or accessibility features directly into your components.

🧩 How @HostListener Works Under the Hood

Under the hood, @HostListener is just syntactic sugar provided by Angular. It’s implemented via Angular’s makePropDecorator function:

export const HostListener: HostListenerDecorator = makePropDecorator(
  'HostListener',
  (eventName?: string, args?: string[]) => ({ eventName, args }),
);
Enter fullscreen mode Exit fullscreen mode

When compiled by Angular (Ivy), your decorator gets transformed into low-level host bindings like:

hostBindings: function About_HostBindings(rf, ctx) {
  if (rf & 1) {
    ɵɵlistener("resize", function About_resize($event) {
      return ctx.onResize($event);
    }, ɵɵresolveWindow);

    ɵɵlistener("keydown.shift.i", function About_shortcut($event) {
      return ctx.onShortcut($event);
    }, ɵɵresolveWindow);
  }
}
Enter fullscreen mode Exit fullscreen mode

That’s how Angular internally registers the event listeners during render.

🧠 Final Thoughts

The @HostListener decorator is a clean, Angular-idiomatic way to handle DOM and global events. It:

  • Keeps event handling logic close to the component or directive class
  • Works seamlessly with Angular's DI and change detection
  • Helps encapsulate behavior without touching templates

Whether you're creating reusable directives or handling responsive layouts, @HostListener can significantly streamline your codebase.

💬 Got questions or use cases you want to share? Drop a comment below! Let's discuss more Angular magic. ✨

✍️ Author: Vetriselvan

👨‍💻 Frontend Developer | Code Lover | Exploring Angular’s future

Embedded BI Dashboards are 💩 Building them yourself is 💩

Embedded BI Dashboards are 💩 Building them yourself is 💩

Use our developer toolkit to build fast-loading, native-feeling dashboards for your customers (without the sh*t).

Get early access

Top comments (0)

Runner H image

Forgot Again? Let Runner H Fix It For You

From booking the restaurant to sending the invite and apology message — Runner H makes it up for you. Yes, even your mess-ups are now automated.

Try Runner H

👋 Kindness is contagious

Take a moment to explore this thoughtful article, beloved by the supportive DEV Community. Coders of every background are invited to share and elevate our collective know-how.

A heartfelt "thank you" can brighten someone's day—leave your appreciation below!

On DEV, sharing knowledge smooths our journey and tightens our community bonds. Enjoyed this? A quick thank you to the author is hugely appreciated.

Okay