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 (outside of basic configuration is required).

But what about the headless configurations that are becoming popular due to the lightning speed results they offer users? Different storefront vendors provide their own headless solutions and tailored approaches in addressing 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 already reflected on the extensibility of JS-based applications. You may have come up with similar concepts that are more or less trivial to integrate for most applications: an event-based model or extensibility on 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.

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:

  • BuildPack targets you may add environment variables, transform system modules, modify compiler behavior;
  • 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; 
  • 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 and an additional layer of framework utilities that provide 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. It’s 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. If you have any questions or suggestions, please share in the comment section. Thank you for reading.

Case Studies

Meet our clients

From startups backed by Mark Cuban and Sir Richard Branson, to some of the biggest eCommerce operations in the world, Atwix helps our clients deliver unparalleled eСommerce experiences. We’re proud to work with the following companies: