Get 15% off Mageplaza extensions & subscriptions! Use code HIMAY at checkout.

Magento 2 custom product collection with layered navigation

Vinh Jacker | 10-09-2019

The Most Popular Extension Builder for Magento 2

With a big catalog of 224+ extensions for your online store

The digital age has revolutionized the ways for business operation and when the website is used streamingly as a powerful tool for its success. The more advanced technologies are, the more convenience store owners are supposed to offer their customers. Of course, no one wants to challenge their client’s patience and make them find it hard to look up for some of their favorite items in millions. As a result, they will immediately abandon shopping carts as their online purchasing is time-consuming and unsatisfying.

Coming as the most updated and best versatile solution for every business, Layered Navigation for Magento 2 not only helps the online site have better SEO performance but also provides customers a fantastic navigation tool by minimizing the unnecessary time for shopping time and increasing user’s filtering experience. Among its attractive features, Layered Navigation Ultimate also allows the store admin to custom their product collection at the product page with ease. With this smart feature, the path to get the most conversion rate have never been easier.

Layered Navigation

Layered Navigation for Magento 2

Simplify your shopping experience with our advanced search and filter options

Check it out!

Default Magento limitations

Confuse customers with too many items

When it comes to filters for product navigation, Magento 2 default has its limitations. A site with a bunch of items with various attributes makes people overwhelmed when it lacks a smart navigation tool for quick searching. And the case is much more difficult when the shoppers are looking for items without knowing exactly what category they belong to. For example, it is challenging for them to filter their desired jacket which costs around 100-200 USD and has red color on just one page.

Navigation tool for quick searching

Poor user experience

Besides, by default, Magento 2 requires users to reload the whole page, even products that are in the same collection after they add other filters. Not mention another drawback that SEO performance can not be fully prioritized to enhance your website position on search engines.

Solutions with Layered Navigation for Magento 2

When it comes to smart searching, all of Magento 2 default disadvantages can be effectively solved by Layered Navigation. Here are outstanding advantages this excellent extension can provide with custom product page features.

Best user-experience

Although online purchasing has integrated into our modern life since the robust development of technology, an E-commerce site is not always a familiar place to the shoppers, in particular on their first visit. In such a case, they may feel confused to get their favorite items as a hundred attributes are displayed at the same time. With unprofessional skills for searching, they may end up with stopping shopping right away.

For Layered Navigation Ultimate, shoppers don’t need to find the precise category page somewhere. With just a few mouse clicks, the client’s favorite items of all kinds are well displayed in just one page. That will be a delightful experience for all online buyers as they can shop with excellent assistance from the latest technology.

Consequently, the shoppers will fall in love with your store and prefer to visit for future purchases.

Marketing your product

When potential customers visit your store, they are likely to be attracted to items on the top of categories naturally. Therefore, it is entirely useful for any marketing strategy if new coming attributes are displayed first by default. It is a big chance that a potential product may get its fame and generate considerable revenue when launching. If you are running an online cloth store, do not hesitate to introduce the most attractive styles to boost sales.

Enhance the SEO performance

SEO performance

Besides the excellent custom product page to filter attributes, Mageplaza Layered Navigation also offers intelligent tools to optimize your site ranking. SEO-friendly URL composes of your site’s agenda which supports you on search engines and reminds customers for the next search.

Furthermore, by proper configuration for Meta Keywords, Meta Titles, and Meta Descriptions, store owners can increase the site rank in the search engine result pages. Don’t make your customers tired of shopping in your store with an amateur site. Taking advantage of Layered Navigation significantly to improve SEO performance as well as enhance customers’ experience and increase conversion rate.

How to manage Custom Product Collection

To meet the requirement of classifying a hundred kinds of products, Magento 2 Layered Navigation Ultimate will allow you to create as many Custom product pages as you want.

Adding a new product page and editing the existing product page, follow this structure Admin Panels > Mageplaza > Layered Navigation > Custom Product Pages. The configuration includes two sections:

Page information

After choosing/creating a specific Product page, select Page Information and scroll down to see some essential information:

Page information configuration

There are three fields related to SEO performance.

Configure meta title meta keywords meta discription

Default attribute

This outstanding feature allows you to set the default attribute for the all products page. That means when the shoppers open the all products page, you can decide which products will be displayed first. For example, if you set the option Cool and Cold of the attribute Climateas the Default Attributes, the items which have Cool and Cold will be displayed first when the shoppers go to the Custom Product Pages.

Custom products page information

How to create layered navigation on a custom page in Magento 2?

1. Create di.xml with the following code under Mageplaza/LayeredNavigation/etc/ folder

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\Layer\ContextInterface" type="Magento\Catalog\Model\Layer\Context" />
    <preference for="Magento\Catalog\Model\Layer\ItemCollectionProviderInterface" type="Magento\Catalog\Model\Layer\Category\ItemCollectionProvider" />
    <preference for="Magento\Catalog\Model\Layer\StateKeyInterface" type="Magento\Catalog\Model\Layer\Category\StateKey" />
    <preference for="Magento\Catalog\Model\Layer\CollectionFilterInterface" type="Magento\Catalog\Model\Layer\Category\CollectionFilter" />
    <preference for="Magento\Catalog\Model\Layer\FilterableAttributeListInterface" type="Magento\Catalog\Model\Layer\Category\FilterableAttributeList" />
    <preference for="Magento\Catalog\Model\Layer\AvailabilityFlagInterface" type="Magento\Catalog\Model\Layer\Category\AvailabilityFlag" />
    <preference for="Magento\Catalog\Model\ResourceModel\Layer\Filter\Price" type="Mageplaza\LayeredNavigation\Model\ResourceModel\Layer\Filter\Price" />

2. Add the following in the layout file which in my case is layerednavigation_index_index.xml under Mageplaza/LayeredNavigation/view/frontend/layout/ folder

<?xml version="1.0"?>
<page xmlns:xsi="" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <attribute name="class" value="page-products"/>
        <referenceContainer name="content">
            <block class="Mageplaza\LayeredNavigation\Block\Product\ListProduct" name="layerednavigation_index_index" as="product_list" template="Magento_Catalog::product/list.phtml">
                <container name="category.product.list.additional" as="additional" />
                <block class="Magento\Framework\View\Element\RendererList" name="category.product.type.details.renderers" as="details.renderers">
                    <block class="Magento\Framework\View\Element\Template" name="category.product.type.details.renderers.default" as="default"/>
                <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="category.product.addto" as="addto">
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                        name="" as="compare"
                <block class="Magento\Catalog\Block\Product\ProductList\Toolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml">
                    <block class="Magento\Theme\Block\Html\Pager" name="product_list_toolbar_pager"/>
                <action method="setToolbarBlockName">
                    <argument name="name" xsi:type="string">product_list_toolbar</argument>
        <referenceContainer name="sidebar.main">
            <block class="Mageplaza\LayeredNavigation\Block\Navigation" name="catalog.leftnav" as="navigation" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
                <block class="Mageplaza\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" template="Magento_LayeredNavigation::layer/state.phtml" />
                <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml">
                      <argument name="product_layer_view_model" xsi:type="object">Magento\LayeredNavigation\ViewModel\Layer\Filter</argument>
        <referenceBlock name="layerednavigation_index_index">
                  <argument name="viewModel" xsi:type="object">Magento\Catalog\ViewModel\Product\OptionsData</argument>

In the above code, we have added class page-products to the body tag to inherit the default styling.

3. Then, we will override the model files to get required data. Create Layer.php under Mageplaza/LayeredNavigation/Model/ folder with following code

namespace Mageplaza\LayeredNavigation\Model;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;

class Layer extends \Magento\Catalog\Model\Layer
    public function __construct(
        \Magento\Catalog\Model\Layer\ContextInterface $context,
        \Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
        AttributeCollectionFactory $attributeCollectionFactory,
        \Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Registry $registry,
        CategoryRepositoryInterface $categoryRepository,
        CollectionFactory $productCollectionFactory,
        array $data = []
    ) {
        $this->productCollectionFactory = $productCollectionFactory;

    public function getProductCollection()
        if (isset($this->_productCollections['mageplaza_custom'])) {
            $collection = $this->_productCollections['mageplaza_custom'];
        } else {
            //here you assign your own custom collection of products
            $collection = $this->productCollectionFactory->create();
            $this->_productCollections['mageplaza_custom'] = $collection;
        return $collection;


4. After that, create Resolver.php under Mageplaza/LayeredNavigation/Model/Layer/ folder with following code

namespace Mageplaza\LayeredNavigation\Model\Layer;

class Resolver extends \Magento\Catalog\Model\Layer\Resolver
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Mageplaza\LayeredNavigation\Model\Layer $layer,
        array $layersPool
    ) {
        $this->layer = $layer;
        parent::__construct($objectManager, $layersPool);

    public function create($layerType)

5. Then under Mageplaza/LayeredNavigation/Model/ResourceModel/Layer/Filter/ folder create Price.php file

namespace Mageplaza\LayeredNavigation\Model\ResourceModel\Layer\Filter;

use Magento\Framework\App\Http\Context;
use Magento\Framework\Indexer\DimensionFactory;
use Magento\Framework\Search\Request\IndexScopeResolverInterface;

class Price extends \Magento\Catalog\Model\ResourceModel\Layer\Filter\Price 
    public function __construct(
        \Magento\Framework\Model\ResourceModel\Db\Context $context,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Mageplaza\LayeredNavigation\Model\Layer\Resolver $layerResolver,
        \Magento\Customer\Model\Session $session,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        $connectionName = null,
        IndexScopeResolverInterface $priceTableResolver = null,
        Context $httpContext = null,
        DimensionFactory $dimensionFactory = null
    ) {
        parent::__construct($context, $eventManager, $layerResolver, $session, $storeManager, $connectionName, $priceTableResolver, $httpContext, $dimensionFactory);

So, we are done with the model and we will override the block to show proper data.

6. Now create Navigation.php file under Mageplaza/LayeredNavigation/Block/ folder with following content

namespace Mageplaza\LayeredNavigation\Block;

class Navigation extends \Magento\LayeredNavigation\Block\Navigation
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Mageplaza\LayeredNavigation\Model\Layer\Resolver $layerResolver,
        \Magento\Catalog\Model\Layer\FilterList $filterList,
        \Magento\Catalog\Model\Layer\AvailabilityFlagInterface $visibilityFlag,
        array $data = []
    ) {
        parent::__construct($context, $layerResolver, $filterList,

7. Create State.php file under Mageplaza/LayeredNavigation/Block/Navigation/ folder with following code

namespace Mageplaza\LayeredNavigation\Block\Navigation;

class State extends \Magento\LayeredNavigation\Block\Navigation\State
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Mageplaza\LayeredNavigation\Model\Layer\Resolver $layerResolver,
        array $data = []
    ) {
        parent::__construct($context, $layerResolver, $data);

8. Then under Mageplaza/LayeredNavigation/Block/Product/ folder create ListProduct.php and add following code

namespace Mageplaza\LayeredNavigation\Block\Product;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
        \Mageplaza\LayeredNavigation\Model\Layer\Resolver $layerResolver,
        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
        \Magento\Framework\Url\Helper\Data $urlHelper,
        array $data = []
    ) {
        parent::__construct($context, $postDataHelper, $layerResolver,
            $categoryRepository, $urlHelper, $data);

That’s all, we have overridden all the required files.

Final words

In summary, customer product collection is a great feature for e-commerce stores. Incorporating Magento 2 custom product collection with layered navigation helps to enhance smart navigation and improve your e-commerce store’s performance. By providing a streamlined and personalized shopping experience, you can boost customer satisfaction, increase sales, and enhance SEO. Follow this guide to set up your custom collections and layered navigation properly, and monitor their performance to ensure your e-commerce store gets success in marketing.


Hello, I'm the Chief Technology Officer of Mageplaza, and I am thrilled to share my story with you. My deep love and passion for technology have fueled my journey as a professional coder and an ultra-marathon runner. Over the past decade, I have accumulated extensive experience and honed my expertise in PHP development.

Related Post

Website Support & Maintenance Services

mageplaza services

Make sure your store is not only in good shape but also thriving with a professional team yet at an affordable price.