Custom Event and Observer

Create Custom Event and Observer Programmatically Using events.xml

Magento 2 offers a powerful event-driven architecture that lets developers hook into core functionality without changing the core code. In this guide, you’ll learn how to:

  • Create and dispatch a custom event
  • Declare it in events.xml
  • Handle it using an Observer class

Updated for Magento 2.4.7 (2025), this tutorial is production-ready and includes helpful tips and best practices.

Deep Dive: Magento 2 Events and the Observer Pattern

Magento 2 events are a critical part of the Event-Observer Design Pattern, which allows developers to execute custom logic without changing the core code. It makes the system highly extensible, modular, and maintainable.

Events are dispatched by Magento at strategic execution points (like after a product is saved, an order is placed, etc.), and developers can attach custom functionality using observers.

What Is a Magento Event?

An event is simply a trigger or signal that Magento dispatches during the execution of specific actions. These can be system events (like sales_order_place_after) or custom events created by developers. Observers are classes that respond to these events and execute your code.

Events are defined and dispatched through Magento's event manager.

When Are Events Used?

Events are typically used in scenarios such as:

  • Logging actions (e.g., product save, customer login)
  • Custom notifications (e.g., on order success)
  • API integrations (triggering external service calls)
  • Auto-assigning values or flags to entities
  • Extending third-party modules without overriding

Syntax to Dispatch a Custom Event

To trigger your own event, use Magento's Event Manager. Here's how:

$this->_eventManager->dispatch(

    'your_custom_event_name',

    [ 'key1' => $value1, 'key2' => $value2 ]

);

If you're using dependency injection, inject \Magento\Framework\Event\ManagerInterface into your constructor.

Dispatch Method Breakdown

Method Signature:

public function dispatch($eventName, array $data = []);

Parameters Explained:

Parameter Description
$eventName A string identifier for your custom event (e.g., custom_event_trigger)
$data An associative array of key-value pairs passed to the observer

Key Differences: Magento Events vs Plugin Interception

Feature Magento Events Plugin Interception
Flexibility Can attach logic without affecting method flow Can change input/output of specific methods
Multiple Listeners Yes One plugin chain per method
Use Cases Side effects, async hooks, third-party triggers Method overrides and pre/post logic
Performance Impact Lightweight May impact performance if overused

Best Practices for Dispatching Events

  • Use namespaced event names to avoid conflicts (vendor_module_custom_event).
  • Always dispatch with contextual and minimal data.
  • Ensure events are only dispatched in relevant execution paths.
  • Document custom events well so they’re reusable across the codebase.

Use Cases of Custom Events

Scenario Example
Trigger webhook Notify third-party service when a customer signs up
Auto assign customer group On registration, assign to "Wholesale" if email matches domain
Send transactional emails Send a custom email when wishlist is shared
Track user activity Log time and IP of last login
Queue a background process Dispatch a job to process export or data sync

Debugging and Monitoring Events

  • Enable developer mode to log dispatched events.
  • Use Xdebug to step into dispatch() and track registered observers.
  • You can also temporarily log inside your observer to confirm execution.

Defining events.xml in Magento 2.4.x

Magento 2 uses the Observer Design Pattern to allow developers to hook into system processes without directly modifying core code. The events.xml file is the configuration file where custom event observers are defined.

You must declare this file in the correct area-specific directory depending on where your observer should respond.

Where to Place events.xml Based on Execution Area

Area Folder Path Description
Global etc/ Executes for both frontend and backend requests. Use this for events that are not area-specific (e.g., model save, order placement).
Frontend etc/frontend/ Used for customer-side events like login, add to cart, checkout, etc.
Adminhtml etc/adminhtml/ Applies only in the admin panel. Useful for events triggered from admin grids, forms, etc.
Web API (REST) etc/webapi_rest/ Events related specifically to REST API requests.
Web API (SOAP) etc/webapi_soap/ Events triggered via SOAP API requests.

Recommended Use Cases per Area

Area Example Use Case Example Event
Global Log after order is placed sales_order_place_after
Frontend Track product views catalog_controller_product_view
Adminhtml Send alert on admin login admin_user_authenticate_after
Web API (REST) Trigger sync after customer update customer_save_after_data_object
Web API (SOAP) Validate product import via SOAP catalog_product_save_after

Observer Class Placement and Structure

After defining your event in events.xml, you must create an Observer class that implements \Magento\Framework\Event\ObserverInterface.

Location Example:

app/code/Vendor/Module/Observer/CustomObserver.php

Key Elements:

  • Namespace must match module
  • Class must implement ObserverInterface
  • The execute() method must receive an instance of \Magento\Framework\Event\Observer

Sample events.xml Entry

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">

  <event name="customer_login">

    <observer name="custom_login_logger" instance="Vendor\Module\Observer\LoginObserver" />

  </event>

</config>

Best Practices for Managing events.xml

  • Keep event names unique across modules to avoid conflicts.
  • Do not attach heavy logic directly in observers—offload to services or queues when possible.
  • Use area-specific folders to limit unnecessary event dispatching.
  • Use di.xml to inject dependencies inside your observer class constructor.
  • Avoid creating multiple observers for the same task—consolidate logic where applicable.

Step-by-Step Guide to Create and Dispatch a Custom Event in Magento 2

In this tutorial, we will walk you through creating a custom event in Magento 2. The module we’ll build is called Emmo_CustomEvent.

Step 1: Dispatching an Event in a Controller

To start, you need to dispatch your custom event from a controller action. Here's how to do it

File: app/code/Emmo/CustomEvent/Controller/Index/Index.php

<?php

namespace Emmo\CustomEvent\Controller\Index;

use Magento\Framework\DataObject;

use Magento\Framework\App\Action\Action;

use Magento\Framework\App\Action\Context;

class Index extends Action

{

    public function __construct(Context $context)

    {

        parent::__construct($context);

    }

    public function execute()

    {

        // Custom data to pass to the observer

        $customData = new DataObject([

                    'record_id' => 10001,

                'name' => 'record_name'

        ]);

        // Dispatching the custom event

        $this->_eventManager->dispatch('jesadiya_custom_event_observer', [

                'record' => $customData

        ]);

    }

}

Action Explanation:

  • In the execute() method, we create a DataObject with custom data (record_id and name).
  • The _eventManager->dispatch() method is used to trigger the custom event jesadiya_custom_event_observer.

Step 2: Define the Event in events.xml

Next, you need to define the custom event and associate it with an observer. This is done in the events.xml file.

File:app/code/Emmo/CustomEvent/etc/events.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">

    <event name="jesadiya_custom_event_observer">

        <observer name="handle_custom_event"

                instance="Jesadiya\CustomEvent\Observer\GetRecord"/>

    </event>

</config>

Event Explanation:

  • The event name emmo_custom_event_observer is linked to the observer class Emmo\CustomEvent\Observer\GetRecord.

Step 3: Create the Observer Class

The observer listens for the event and processes the data passed with the event. Below is an example of an observer class.

File: app/code/Emmo/CustomEvent/Observer/GetRecord.php

namespace Emmo\CustomEvent\Observer;


use Magento\Framework\Event\Observer;

use Magento\Framework\Event\ObserverInterface;


class GetRecord implements ObserverInterface

{

    public function execute(Observer $observer)

    {

        // Get the custom data passed with the event

        $record = $observer->getEvent()->getRecord();

        $recordId = $record->getRecordId();

        $name = $record->getName();


        // Perform actions with the data

        // Example: logging the data or using it for further operations

        // $this->logger->info("Record ID: $recordId, Name: $name");


        return $this;

    }

}

Observer Explanation:

  • The execute() method gets the data (record_id and name) that was passed during the event dispatch.
  • You can process the data inside this method, such as logging, sending notifications, or updating records.

Bonus: Dispatching a Custom Event Using Plugin

If you prefer to dispatch a custom event within a plugin instead of a controller, here's how to do it:

use Magento\Framework\Event\ManagerInterface as EventManager;


private $_eventManager;


public function __construct(EventManager $eventManager)

{

    $this->_eventManager = $eventManager;

}


public function aroundExecute($subject, callable $proceed)

{

    // Custom data to dispatch with the event

    $customData = new \Magento\Framework\DataObject([

        'record_id' => 9999,

        'name' => 'via_plugin'

    ]);


    // Dispatching the event

    $this->_eventManager->dispatch('jesadiya_custom_event_observer', [

        'record' => $customData

    ]);


    // Proceed with the original method

    return $proceed();

}

Plugin Explanation:

  • In the aroundExecute() method, we create custom data (record_id and name).
  • We dispatch the event emmo_custom_event_observer with this custom data before proceeding with the original method logic.

Key Takeaways

  • Custom events in Magento allow you to decouple different pieces of logic in your application.
  • Observers listen to these events and execute actions when an event is triggered.
  • Plugins can also be used to dispatch events, providing more flexibility in how and where you trigger custom logic.

Practical Use Cases of Custom Events in Magento 2.4.7

Magento’s event-driven architecture allows developers to execute logic without altering core functionality. Custom events are especially powerful in complex business scenarios, helping to keep your code modular, flexible, and upgrade-safe.

Why Use Custom Events?

Custom events are best when you want to:

  • Extend core behavior without overriding classes.
  • Decouple features into reusable modules.
  • Trigger external services (e.g., CRMs, APIs).
  • Collect analytics or track specific behavior.
  • Customize notification flows or automate user segmentation.

Common Business Scenarios for Custom Events

Here’s a detailed table showing practical use cases, the event naming convention, and what the observer typically handles.

Use Case Custom Event Name Observer Responsibility
Logging custom activity custom_activity_log Collect user or system actions and write them to logs or custom tables for auditing
Triggering email workflows custom_email_trigger Send transactional or marketing emails when certain triggers occur
Third-party API synchronization custom_thirdparty_sync Push or pull data from third-party systems like CRMs, ERPs, or external apps
Assigning customer segments auto_customer_segment_event Automatically assign users to specific customer groups based on custom rules
Inventory alert or restock logic custom_stock_notification Notify users or trigger workflows when inventory thresholds are hit
Custom cache clear on condition conditional_cache_clear Flush or refresh cache sections programmatically based on user actions
Generating admin alerts custom_admin_alert Send alerts to admin users when thresholds or business rules are violated
Activity tracking for analytics custom_user_analytics Record login, search, wishlist, or order history for analytics tools
Loyalty program integration loyalty_points_trigger Add loyalty points or rewards based on order or action triggers
Background job queuing background_task_dispatch Dispatch a task to be handled later using Magento’s message queue system
Scheduled data export custom_export_trigger Launch an export of customer, order, or product data when specific events are triggered
Custom pricing adjustments dynamic_price_event Adjust prices dynamically based on rules, customer group, or time-based logic
Custom validation during checkout checkout_validation_event Add custom logic to validate user data before order placement

Event Naming Best Practices

When defining custom events, follow clear and meaningful naming conventions:

  • Use lowercase with underscores (snake_case)
  • Prefix your event name with your module or company name to avoid collisions (e.g., mycompany_order_validate)
  • Keep it action-oriented and descriptive (e.g., customer_profile_updated, custom_export_trigger)

When Should You Use Events Instead of Plugins?

Criteria Use Custom Event Use Plugin
Decoupled logic Yes Limited
Multiple logic handlers Supports multiple observers Only one plugin chain per method
Modifying input/output Not ideal Ideal
Intercepting specific methods Only reacts to global events Works best on class methods
System-wide action triggers Excellent for global or async hooks Not recommended for global events

Custom events in Magento 2 are essential for building scalable, modular, and flexible code. Whether you’re logging activities, triggering APIs, or dispatching emails, events let you hook into Magento’s processes without risking conflicts or upgrade issues.

If you're working with Magento 2.4.7 or newer, always register your events in the appropriate events.xml file based on the desired area (etc, etc/frontend, etc/adminhtml, etc.), and consider asynchronous handling via message queues for large-scale integrations.

Tip

To enhance your eCommerce store’s performance with Magento, focus on optimizing site speed by utilizing Emmo themes and extensions. These tools are designed for efficiency, ensuring your website loads quickly and provides a smooth user experience. Start leveraging Emmo's powerful solutions today to boost customer satisfaction and drive sales!

Conclusion

Custom events and observers are essential tools in a Magento developer’s toolbox—allowing you to build robust, modular, and scalable solutions without altering the core code. With Magento 2.4.7, these features remain critical to extending native functionality, integrating third-party systems, and automating business logic at key interaction points.

By understanding how to properly dispatch events, configure events.xml, and implement observer classes, you unlock the full potential of Magento's event-driven system. Whether you're logging user activity, syncing with external APIs, or triggering custom workflows—this pattern empowers your store to respond intelligently to user and system actions.

Always follow Magento’s best practices:

  • Keep logic out of observers when possible
  • Use services for complex processes
  • Scope your events correctly (frontend, adminhtml, REST, etc.)

In a rapidly evolving eCommerce world, the ability to listen and respond is everything. Mastering custom events is how you keep Magento responsive, powerful, and future-proof.

FAQs

What is a custom event in Magento 2?

A custom event in Magento 2 is a developer-defined trigger used to execute additional logic by dispatching data through the event/observer system without changing core files.

How do I dispatch a custom event in Magento 2?

You can dispatch a custom event using the `$this->_eventManager->dispatch('event_name', ['data' => $data])` method in your controller, model, or plugin.

Where should I define events.xml for global event scope?

Define `events.xml` inside the `etc/` directory of your module for global (both frontend and adminhtml) event handling.

What is the purpose of the Observer class in Magento 2?

The Observer class is responsible for handling the dispatched event logic using the `execute()` method where data can be processed.

Which interface must an Observer implement?

An Observer class must implement the `\Magento\Framework\Event\ObserverInterface` to handle event logic.

Can I pass multiple data parameters in dispatch?

Yes, you can pass multiple key-value pairs in the second argument (array) of the `dispatch()` method.

How can I access data in the Observer class?

You can access the dispatched data using `$observer->getEvent()->getData('key')` or by getting the specific object directly if passed with a key.

What are the different areas for events.xml placement?

You can place `events.xml` in `etc/`, `etc/frontend/`, `etc/adminhtml/`, `etc/webapi_rest/`, and `etc/webapi_soap/` depending on the area where your event should trigger.

Is it possible to use custom events in Plugins?

Yes, you can dispatch custom events inside a plugin method using the `Magento\Framework\Event\ManagerInterface` instance.

Can I use custom events for REST or SOAP APIs?

Yes, define `events.xml` in `etc/webapi_rest/` or `etc/webapi_soap/` to handle custom events in respective API calls.

What command should I run after creating an observer?

Run `bin/magento cache:clean` and `bin/magento setup:upgrade` to register and activate new observers or event configurations.

Can I listen to native Magento events using the same approach?

Yes, simply subscribe to Magento's built-in events using your module’s `events.xml` and provide an appropriate observer class.

What’s the difference between Observer and Plugin?

Observers respond to dispatched events. Plugins modify the behavior of existing public methods using before/after/around logic.

Can I dispatch an event without sending data?

Yes, the data array in `dispatch()` is optional. If you don’t need to pass data, you can just provide the event name.

What are best practices for creating custom observers?

Keep observer logic clean and lightweight, offload heavy operations to services, avoid core overrides, and ensure your event is uniquely named to avoid conflicts.