Working with Magento 2 Plugins: A Complete Guide

A plugin is a class that intercepts method calls in Magento 2. It gives you the ability to:

  • Run logic before a method is executed.
  • Run logic after a method returns a result.
  • Wrap around a method call, controlling if and when it executes.

In other words, plugins let you extend functionality without touching the original code.

Why Use Plugins?

Plugins are one of Magento’s most powerful customization tools because they:

  • Preserve Core Code – No need to modify or copy Magento classes.
  • Upgrade-Safe – Your changes won’t break when Magento updates.
  • Granular Control – Target only specific methods instead of entire classes.
  • Lightweight – Add functionality with minimal impact on performance.

Types of Plugins

Magento supports three types of method interception:

1. Before Plugins

Executed before the original method. Useful for changing arguments or applying pre-logic.

public function beforeMethodName(SubjectType $subject, $arg1, $arg2 /* ... */)
{
    // Return an array ONLY if you want to replace arguments:
    return [$newArg1, $newArg2 /* ... */];
}
  • Return nothing to keep original arguments.
  • Return array to replace arguments (must match the full arg list order).
2. After Plugins

Executed after the original method. Useful for modifying the returned result.

public function afterMethodName(SubjectType $subject, $result /* , $arg1, ... optional */)
{
    // Must return the (possibly modified) result
    return $result;
}
3. Around Plugins

Wrap around the original method. You can control whether to execute the original method or completely replace its behavior.

public function aroundMethodName(SubjectType $subject, callable $proceed, $arg1, $arg2 /* ... */)
{
    // Pre-logic
    $result = $proceed($arg1, $arg2 /* ... */);  // Call next in chain / original
    // Post-logic
    return $result;
}

Create the Plugin Class

Suppose you want to append “(Special Edition)” to product names on the storefront. Instead of rewriting Magento\Catalog\Model\Product, you can use a plugin.

Step 1: Register Plugin in di.xml

File: Ecommet\HelloWorld/etc/di.xml

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

    <type name="Magento\Catalog\Model\Product">
        <plugin name="custom_product_name"
                type="Ecommet\HelloWorld\Plugin\ProductPlugin" />
    </type>
</config>

Here’s what’s happening:

  • Magento\Catalog\Model\Product is the class being intercepted.
  • Ecommet\HelloWorld\Plugin\ProductPlugin is your plugin class.
  • custom_product_name is the unique plugin identifier.
Step 2: Create the Plugin Class

File: Ecommet\HelloWorld/Plugin/ProductPlugin.php

<?php
namespace Ecommet\HelloWorld\Plugin;

class ProductPlugin
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return $result . ' (Special Edition)';
    }
}
  • The plugin intercepts the getName() method.
  • The original product name ($result) is modified by appending text.

So, instead of showing “T-Shirt”, Magento will display “T-Shirt (Special Edition)”.

When to Avoid Plugins

While plugins are powerful, they are not always the right choice. Avoid using plugins when:

  • The method is marked as final, private, static, or is a constructor (__construct). Plugins cannot intercept these.
  • You need to add logic triggered by system-wide events (use observers instead).
  • The customization significantly changes the class behavior (a preference or rewrite may be more suitable).