Magento PWA Plugins – Beginner’s How-to

Adobe’s eCommerce platform, Magento, is one of the most popular if not most powerful solutions on the market. There are many reasons this platform is unique in its ability to scale B2B and B2C organizations without sacrificing or degrading performance or security.

Extensibility, for example.

Magento allows you to augment native system functionality with preset modules available at the Magento Marketplace or via approved 3rd party vendor websites. When using standard Magento with server-side rendering (Luma-based theme or similar approach), there is no need for additional development (beyond basic configuration).

But what about the headless configurations that are becoming popular due to the lightning speed results they offer users? Different storefront vendors offer their own headless solutions and tailored approaches to address extensibility. For example, ScandiPWA has its own marketplace, where you may find an extension you need. Magento offers its own solution, PWA Studio. Look to the Magento marketplace for PWA Studio storefront plug-in and other related extensions.

Suppose you have already reflected on the extensibility of JS-based applications. You may have identified similar concepts that are more or less straightforward to integrate into most applications, such as an event-based model or extensibility at the compilation level. Currently, we have both of these concepts considered in Magento 2: the event → observer system and plugins. If you are familiar with Magento plugins (not extensions provided by vendors but plugin classes), the PWA Studio plugins concept has a very similar basis. Moreover, integrating an ERP system for Magento further enhances the extensibility and functionality of your eCommerce platform by automating business processes, streamlining operations, and providing comprehensive insights into inventory, orders, and customer data.

Magento PWA Studio plugins are injected into the codebase on the compilation (build) level by the webpack. In your plugin, you provide a change that you will make and instructions for the webpack on where your changes should be injected. There are a set of targets in the PWA Studio components: Peregrine targets, VeniaUI targets, and BuildPack targets.

Some of the above target’s purposes are:

  • With BuildPack targets, you can add environment variables, transform system modules, and modify compiler behavior;
  • With VeniaUI targets you may add your rich content renderers (the Page Builder plugin uses this target for injecting its renderer), add new routes to the system, manipulate with payment methods to some extent; 
  • With Peregrine targets you may wrap the system talons and hooks in a very similar way as you do with Magento plugins. The Pergerine targets provide a suitable space for extending the system functionality and changing the system behavior.

All the mentioned targets are built on top of the Webpack plugins concept, supplemented by an additional layer of framework utilities that define the targets. To explain how the extensibility system works in detail, let’s review a simple example. The following example will extend the basic system behavior by adding the store name to a page title.

At first, the plugin needs to be declared in the system. This is achievable by providing the valid package.json file.

// packages/extensions/venia-extend-cms-meta/intercept.js
  "name": "@atwix/venia-extend-cms-meta",
  "version": "1.0.0",
  "publishConfig": {
    "access": "public"
  "description": "Provides demo of extending meta tags for PWA Studio.",
  "main": "./intercept.js",
  "scripts": {
    "clean": " "
  "license": "(OSL-3.0 OR AFL-3.0)",
  "peerDependencies": {
    "@magento/pwa-buildpack": "~7.0.0",
    "@magento/venia-ui": "~5.0.0"
  "pwa-studio": {
    "targets": {
      "intercept": "./intercept"

In the pwa-studio section of the example above, there’s a mention of the ./intercept entry point. This file is the plugin definition and looks in the following way.

// packages/extensions/venia-extend-cms-meta/intercept.js

module.exports = targets => {
   const peregrineTargets = targets.of('@magento/peregrine');
   const buildPackTargets = targets.of('@magento/pwa-buildpack');
   const talonsTarget = peregrineTargets.talons;

    buildPackTargets.specialFeatures.tap(features => {
        features[] = { esModule: true };

    talonsTarget.tap(talonWrapperConfig => {

This plugin definition does two things: 

  1. Provides instructions for WebPack, where to inject our logic – wrap useCmsPage talon by our plugin. 
  2. Provides a path to the plugin logic @atwix/venia-extend-cms-meta/plugins/addStoreNameToMetaTitle.

Finally, the plugin logic adds the store title to the page meta title.

// packages/extensions/venia-extend-cms-meta/plugins/addStoreNameToMetaTitle.js

module.exports = function wrapUseCmsPage(original) {
    return function useCmsPage(...args) {

         * This value is hardcoded but ideally should be retrieved using GraphQL (and cached)
        const STORE_NAME = 'MyHeadlessStore';

        const { cmsPage, hasContent, error, shouldShowLoadingIndicator } = original(...args);
        const cmsPageExtended = Object.assign({}, cmsPage, { meta_title: `${STORE_NAME} : ${cmsPage.meta_title}` });

        return { cmsPage: cmsPageExtended, hasContent, error, shouldShowLoadingIndicator }

That’s it. After implementation of this PWA Studio Extension, the system will prefix every page’s meta title with “MyHeadlessStore”.

In the same manner, you may wrap almost any other talon in the system and extend/modify its logic. You may also do the same with the hooks. Take a look at the targets documentation to learn more.

To sum up, adding a Magento 2 PWA Studio extension is as simple as choosing where it should be injected, synching the required information to webpack, and putting together the plugin logic that extends the system.

We hope this material will begin to help you to understand how the Magento extensibility system works. Don’t forget to check the best Magento ERP extensions in our article too. If you have any questions or suggestions, please share in the comment section. Thank you for reading.