The Magento 2 CMS enables easy page management, with the advantage of using widgets that can be added through the page builder. ScandiPWA uses Magento CMS pages and modifies them to incorporate React components.
The Html
component is responsible for parsing certain content on the page into valid React components, including widgets processed as <widget>
tags into the WidgetFactory
component that allows rendering a custom component for it.
To implement a new widget, changes are necessary both in Magento and ScandiPWA. To access custom attributes defined in the widget tag within the component, additional changes are required.
ScandiPWA also has a custom extension for Layout Updates that allows for the use of widgets in a similar way to Magento.
The Magento 2 content management system enables you to easily add and edit pages, and also manage blocks, widgets, and templates.
One of the biggest advantages of using Magento CMS is the use of Widgets on the pages. Magento widgets are an extension of HTML syntax that allows embedding and configuring interactive elements, dynamic content, and custom functionality in HTML. These widgets can contain content such as product lists, image sliders, videos, or CMS blocks.
There are two ways to add widgets in Magento admin: through the widgets tab or through the page builder while editing a page. Widgets added through the widgets tab are placed in the page layout, which is not supported by default in ScandiPWA. However, there is a custom extension that enables this functionality.
As a result, ScandiPWA by default only supports widgets added through the page builder of a CMS page(How to implement a widget?).
Magento needs to process the widget as HTML, for example, in the page builder you could define a widget of type link to the About us page:
{{widget type="Magento\\Cms\\Block\\Widget\\Page\\Link" template="widget/link/link_block.phtml" page_id="5"}}
Normally Magento processes it as:
<div class="widget block block-cms-link">
<a href="<http://localhost:81/about-us>" title="About us">
<span>About us</span>
</a>
</div>
<aside>
⚠️ Implementing this widget as a ScandiPWA component would require updating the Magento to process the widget as a <widget>
tag, rather than normal HTML. For example, it would look like:
<widget type="pageLink" pageId="5">
</aside>
ScandiPWA uses Magento CMS pages, but not in their original form. Instead, ScandiPWA uses the Html
component to read the source CMS page and modifies it to incorporate React components.
The CmsPage
component is rendered by the UrlRewrite
component when the page type is identified as CMS_PAGE
(how to work with routes?).
The CmsPage
component is responsible for making a GraphQL request to get the page content and passing it as a prop to the Html
component.
CmsPage
component.<aside>
✅ The Html
component is also used on the CmsBlock
component. The CmsBlock
receives an identifier and makes a GraphQL request for the content related to the identifier and passes it to the Html
component. One example of use is on the ContactPage
component.
</aside>
<aside>
➡️ If the widget is not processed as a <widget>
tag in Magento, it will be rendered as normal HTML, like in this example.
</aside>
The Html
component is responsible for parsing certain content on the page into valid React components. It defines a set of rules for parsing content based on the used tag. This is important for maximizing the benefits of client-side rendering application features.
In general, the Html
component is responsible for converting:
<a>
into <Link>
component to ensure they work properly with react-router
.<img>
elements into <Image>
component, making them consistent with the rest of the app.<widget>
elements into the <WidgetFactory>
and enables ScandiPWA to process the CMS widgets.The Html
component not only replaces these tags. You can see a list of the rules defined in the component.
WidgetFactory
component determine what to render for the widget?The WidgetFactory
component is rendered with some props that will determine the component to be rendered. For example:
<widget type="test" foo="foo text" title="widget title"></widget>
The Html
component identifies the tag specified and replaces it with the WidgetFactory
component, passing the attributes as props.
The WidgetFactory
component checks for a prop type
and tries to match it with an associated component.
For example, ScandiPWA by default has 4 widget components defined in the renderMap:
HomeSlider
will match if the type is Slider
.NewProducts
will match if the type is NewProducts
.ProductListWidget
will match if the type is CatalogProductList
.RecentlyViewedWidget
will match if the type is RecentlyViewed
.WidgetFactory
renders the associated component and passes some props (What can be accessed in the widget component?). To implement a new widget, you can either create a plugin to the WidgetFactory
component and update the renderMap
variable or override the component (although the latter is not preferred). (how to implement a new widget component?)
<aside>
⚠️ The widget will only be recognized if the GraphQL request for the page content includes a <widget>
tag with a defined attribute type
and a matching component in the WidgetFactory
. Hence, if you add a widget to a page and it is not being rendered as a widget tag, it will be rendered as normal HTML.
</aside>
Remember that there are two ways to add widgets in Magento admin:
Using the page builder while editing a page - which is implemented by default in ScandiPWA.
Using the widgets tab which makes use of the layout feature of Magento, and is not implemented by default in ScandiPWA.
The Scandiweb Layout Updates Extension adds a layout feature that is similar to Magento. And one of its advantages is to allow the use of widgets from the widget tab in Magento in most of its types of pages(not limited to CMS_PAGE
type) and block references.
<aside> ℹ️ You can acquire the Scandiweb Layout Updates extension on the marketplace page. The page also provides a comprehensive list of supported display locations, page handlers, and block references.
</aside>
When working with the Layout Updates Extension, it is recommended to implement the widget in both the WidgetFactory
and Widget
components. By doing so, they will complement each other.
<aside> ✅ In this tutorial, you can follow step-by-step how to implement a widget using the Layout Updates Extension! Check it out: Tutorial: How to implement a new widget using the Layout Updates extension?
</aside>
Tutorial: How to implement a new widget?
Tutorial: How to implement a new widget using the Layout Updates extension?
Tutorial: Creating a Magento Widget
Html