Category Landing Page is a special type of Category Page. In Magento, Merchants are able to set special content for a specific category. Check how to implement this cool feature in PWA Studio.
A Category Landing Page is a special type of Category Page. In Magento, a Merchant can set unique content for a specific category. Take a look at this sample Magento Luma Category Landing Page:
How does it work
In the Magento category page configuration, there is a config field called Display Mode and there are three available options:
-
Products only
-
Static block only
-
Static block and products
If you select the ‘Static block only’ option and set up a static block for the category, you will see your static block on the frontend for the Category, and this is precisely what the Category Landing Page means.
Does PWA Studio support Category Landing Pages?
No.
No.
No.
Is it possible to add support for CLP in PWA Studio?
If you read my blog….
Definitely YES.
Let’s do this!
Install PWA Studio
The very first thing that we need to do is create a new instance of PWA Studio.
Also, we need to have our own Magento 2 instance. This time I am using Magento 2.4.2 with sample data installed. If you don’t have your own local Magento 2 installation, I recommend using Mark Shust’s Magento Docker.
People often ask me:
What is the best way to install Magento in the local environment?
Then I tell them:
Use Mark’s Docker – it’s the best
The Idea
To achieve our goal, we are going to use the PWA Studio Extensibility framework. We will create an improvedCategoryContent component which will be a wrapper for CategoryContent PWA Studio’s component. We will add additional logic there and display Category Landing page content instead of an empty page.
Implementation
Create theme
Before we start coding, let’s create a directory to keep all modifications related to the Category Landing Page.
First, create @theme/category folder in pwa_studio_root/src directory.
Second, let’s link this folder as a package in the package.json
Add improvedCategoryContent component
Create file src / @theme / category / components / ImprovedCategoryContent / ImprovedCategoryContent.js with the following content:
The purpose of this component is to check if the category page is a category landing page. All logic related to checking that is in useImprovedCategoryContent hook that we will create in the next step.
If the category is a landing page, the CategoryLandingPage component is rendered. Otherwise, native PWA Studio’s CategoryContent will be rendered.
Next, create the src / @theme / category / components / ImprovedCategoryContent / index.js file with following content:
Add GET_CATEGORY_LANDING_PAGE query Before implementing the hook, let’s create a GraphQL query that will get information about category display mode and a Static Block ID used for a category’s content.
Create a src/@theme/category/queries.gql.js file:
The query is really straightforward. One important thing here is the ID field in results. Thanks to that ID, Apollo Client can merge these query results with other queries by ID.
Records are merged by ID, and if you have three queries for a category with the same ID, results will be stored in Apollo cache and available without querying to the server. How powerful is that?
Add useImprovedCategoryContent hook
Create a src / @theme / category / talons / useImprovedCategoryContent.js file:
Note: Because I want to keep this example simple, I do not handle errors here. If you would to take a look at how error handling can be done, check this article, please.
That hook receives one parameter - categoryId, and it gets data from the Magento backend using the already declared GET_CATEGORY_LANDING_PAGE query.
Hook returns three fields:
-
isLandingPage - this flag determines category is a landing page or not. Each category that has set up Display Mode equals Page is a landing page.
-
isLoading - determines state of data loading
-
staticBlockId - ID of static block set up for Category landing page.
Update local-intercept.js
It’s time to inject our component into Storefront. Take a look at the code below. If you are not familiar with PWA Studio extensibility framework, check this article.
File src/local-intercept.js:
To insert the ImprovedCategoryContent component, we added import to the Category root component. We used the replaceJSX method to insert the component to the JSX (replace the native component with our new one). We passed all props from the native component to ours.
Add CategoryLandingPage component
First, create a file src / @theme / category / components / CategoryLandingPage / CategoryLandingPage.js with the following content:
Keep in mind the component is rendered if a category has display mode equals Page set up. The component receives staticBlockId prop and uses it to get content for a specific category.
Content is rendered using PlainHtmlRenderer. If something went wrong, an error message is rendered.
Second, create a file src / @theme / category / components / CategoryLandingPage / index.js:
Lastly, create a CSS module src /@theme / category / components / CategoryLandingPage / CategoryLandingPage.module.css
Add useCategoryLandingPage hook
The last thing needed to display the Category landing page’s content is the hook that collects content from Magento.
Create a file src / @theme / category / talons / useCategoryLandingPage.js:
The component returns three fields, and the most important for us is content, which contains the Category Landing page’s content!
Take a look at the results of our fantastic work!
After the modifications, I can see the working category landing page in PWA Studio!
As you can see, the Page works but there are missing styles. A new content renderer is probably needed here, and I think this is quite a good subject for the next article.
Summary
This time we added support for Category Landing Pages to PWA Studio Storefront. As you can see, the PWA Studio Extensibility framework is really powerful, and thanks to this we can easily extend PWA Studio with new features.
You may also like:
Source code
The source code for this tutorial is available on my Github.