Magento PWA Studio: Routing and Root Components

Related Inchoo Services

Routing in React is quite complex, and trying to adapt it to work with Magento 2 can be a very challenging task, considering how many URL-related functionalities (like URL rewrites) Magento 2 offers. Luckily, Magento PWA Studio comes with a built-in solution for handling Magento 2 URL-s which is very flexible. In this article, we are going to take a look at the Magento PWA Studio routing and Root Components concept.

Please note that at the time of writing this article, Magento PWA Studio is still in early development, so some details may be out of date depending on the time you’re reading the article.

Magento PWA Studio Peregrine package comes with a MagentoRouter component which is a wrapper around the React Router and is extended with Magento-specific route-handling functionalities. MagentoRouter compontent is located on the following path inside the folder where pwa studio is located:

packages/peregrine/src/Router/Router.js

Currently, MagentoRouter supports only 3 types of page URL-s:

  • CMS Pages
  • Category Pages
  • Product pages

How Routing in Magento PWA Studio works

React Router is extended with Magento Router functionality which, basically, asks Magento 2 (using GraphQL) to return a page type variable based on the received URL. When Magento 2 returns a page type, Magento Router renders a Root Component that has been assigned to the respective page type.

This is how routing in Magento PWA Studio works step-by-step:

  1. MagentoRouter passes the URL to the MagentoRouteHandler component
  2. MagentoRouteHandler resolves the route by querying Magento 2 using GraphQL and then it receives page type from the query. Currently, those page types are: CMS_PAGE, CATEGORY and PRODUCT.
  3. If the URL doesn’t exist, Magento 2 will send out a 404 error (temporary until proper 404 page type has been implemented). If the URL exists, MagentoRouter will render a RootComponent which is assigned to the received page type.

How to specify a Root Component for a specific page type

All Root Component folders must be placed in the following path in Magento PWA studio theme:

src/RootComponents/

One of the interesting features of Magento PWA studio is that the Root Components are not specified by file type, so you can name the page-specific Root Component folder however you like. For example, for CMS_PAGE type, we can create a following subfolder:

src/RootComponents/MyCMS/

In the subfolder, we then create the index.js entry point file with the following content and this is where it gets interesting:

/**
 * @RootComponent
 * description = 'Basic CMS Page'
 * pageTypes = CMS_PAGE
 */
 
export { default } from './path/to/cms/main/component;

As you can see, the commented section in index.js defines the RootComponent for a specific page type. If we change pageTypes variable value to PRODUCT (webpack restart is required to perform code-splitting again), this component will be used for Product page, and not for CMS page as specified previously.

Where to look for page type value for a specific page

Since Magento PWA Studio is still in development, page types are limited to the three types mentioned in the article (CMS, category and product). Memorizing all page type variables when Magento PWA Studio is fully released would be really hard, not to mention custom page type values, in case we add some custom-created pages or pages created by an extension. Luckily, we can see the page type values from the GraphQL schema.

Magento 2.3 Magento core comes with some modules adapted for GraphQL. And each module containing GraphQL comes with a GraphQL schema which is basically a very detailed and accessible documentation for GraphQL queries. It specifies which GraphQL queries are available, types, interfaces, etc. For example, let’s open up the following file:

Magento/CatalogUrlRewriteGraphQl/etc/schema.graphqls

We can see the following line:

enum UrlRewriteEntityTypeEnum @doc(description: "This enumeration defines the entity type.") {
    PRODUCT
    CATEGORY
}

These are our page types for product page and category page which can be used in our RootComponents assignment. Now we know where to look for GraphQL schema data. Following the path and naming pattern, you can easily find the page type variable for CMS page in:

Magento/CmsUrlRewriteGraphQl/etc/schema.graphqls
enum UrlRewriteEntityTypeEnum {
    CMS_PAGE
}

This is the value that we have used in our example in this article. So you can know which page type value to use either by opening a schema.graphqls file of the module you are using, or by searching UrlRewriteEntityTypeEnum string to list all possible values.

Conclusion

Peregrine package, which is the part of Magento PWA studio, comes with a Magento Router wrapper for React Router which adapts React Router to work with Magento 2 URL logic. Magento Router offers a flexible way of defining Root Components for each page type and an easy way of finding page type variable value for each module. It will be interesting to see how Magento PWA Studio will handle other Magento 2 specific functionalities like layout updates. Expect more articles from Inchoo as we keep playing around with the development version of Magento PWA Studio.

You made it all the way down here so you must have enjoyed this post! You may also like:

Magento PWA Studio: General Overview Adrian Bece
, | 2

Magento PWA Studio: General Overview

Mladen Lotar will be joining us on #MM18HR stage with “Production grade PWA” Borna Kraljevic
, | 0

Mladen Lotar will be joining us on #MM18HR stage with “Production grade PWA”

Jisse Reitsma will be sharing his knowledge on “Connecting GraphQL to your own React project” – MM18HR will be burning from hot PWA topics! Maja Kardum
, | 1

Jisse Reitsma will be sharing his knowledge on “Connecting GraphQL to your own React project” – MM18HR will be burning from hot PWA topics!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.