Since when our article “How to display best seller products in Magento 2” was launched on Jan 16, 2018, we’ve gotten various qualified feedback and requested the same title on Magento 2 as well.
Today we would love to guide you on how to show best seller products in Magento 2.
How to Display Best Seller Products in Magento 2: Step-by-Step
Table of Contents
#1: Create module
First of all, we need to create a module to list bestseller products.
- Step 1: Create Block file with the path app/code/Bss/Bestsellerwidget/Block/Widget/Bestsellerdproduct.php
<?php namespace Bss\Bestsellerwidget\Block\Widget; class Bestsellerdproduct extends \Magento\Framework\View\Element\Template implements \Magento\Widget\Block\BlockInterface { protected $_template = 'widget/bestsellerdproduct.phtml'; /** * Default value for products count that will be shown */ const DEFAULT_PRODUCTS_COUNT = 10; const DEFAULT_IMAGE_WIDTH = 150; const DEFAULT_IMAGE_HEIGHT = 150; /** * Products count * * @var int */ protected $productsCount; /** * @var \Magento\Framework\App\Http\Context */ protected $httpContext; protected $resourceCollection; protected $productloader; protected $resourceFactory; /** * Catalog product visibility * * @var \Magento\Catalog\Model\Product\Visibility */ protected $catalogProductVisibility; /** * Product collection factory * * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory */ protected $productCollectionFactory; /** * Image helper * * @var Magento\Catalog\Helper\Image */ protected $imageHelper; /** * @var \Magento\Checkout\Helper\Cart */ protected $cartHelper; /** * @param Context $context * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory * @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility * @param \Magento\Framework\App\Http\Context $httpContext * @param array $data */ public function __construct( \Magento\Catalog\Block\Product\Context $context, \Magento\Reports\Model\ResourceModel\Report\Collection\Factory $resourceFactory, \Magento\Reports\Model\Grouped\CollectionFactory $collectionFactory, \Magento\Reports\Helper\Data $reportsData, \Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory $resourceCollection, \Magento\Catalog\Model\ProductFactory $productloader, array $data = [] ) { $this->resourceFactory = $resourceFactory; $this->_collectionFactory = $collectionFactory; $this->_reportsData = $reportsData; $this->imageHelper = $context->getImageHelper(); $this->productloader = $productloader; $this->cartHelper = $context->getCartHelper(); $this->resourceCollection = $resourceCollection; parent::__construct($context, $data); } /** * Image helper Object */ public function imageHelperObj(){ return $this->imageHelper; } /** * get featured product collection */ public function getBestsellerProduct(){ $limit = $this->getProductLimit(); $resourceCollection = $this->resourceCollection->create(); $resourceCollection->setPageSize($limit); return $resourceCollection; } /** * Get the configured limit of products * @return int */ public function getProductLimit() { if($this->getData('productcount')==''){ return DEFAULT_PRODUCTS_COUNT; } return $this->getData('productcount'); } /** * Get the widht of product image * @return int */ public function getProductimagewidth() { if($this->getData('imagewidth')==''){ return DEFAULT_IMAGE_WIDTH; } return $this->getData('imagewidth'); } /** * Get the height of product image * @return int */ public function getProductimageheight() { if($this->getData('imageheight')==''){ return DEFAULT_IMAGE_HEIGHT; } return $this->getData('imageheight'); } /** * Get the add to cart url * @return string */ public function getAddToCartUrl($product, $additional = []) { return $this->cartHelper->getAddUrl($product, $additional); } /** * Return HTML block with price * * @param \Magento\Catalog\Model\Product $product * @param string $priceType * @param string $renderZone * @param array $arguments * @return string * @SuppressWarnings(PHPMD.NPathComplexity) */ public function getProductPriceHtml( \Magento\Catalog\Model\Product $product, $priceType = null, $renderZone = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST, array $arguments = [] ) { if (!isset($arguments['zone'])) { $arguments['zone'] = $renderZone; } $arguments['zone'] = isset($arguments['zone']) ? $arguments['zone'] : $renderZone; $arguments['price_id'] = isset($arguments['price_id']) ? $arguments['price_id'] : 'old-price-' . $product->getId() . '-' . $priceType; $arguments['include_container'] = isset($arguments['include_container']) ? $arguments['include_container'] : true; $arguments['display_minimal_price'] = isset($arguments['display_minimal_price']) ? $arguments['display_minimal_price'] : true; /** @var \Magento\Framework\Pricing\Render $priceRender */ $priceRender = $this->getLayout()->getBlock('product.price.render.default'); $price = ''; if ($priceRender) { $price = $priceRender->render( \Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE, $product, $arguments ); } return $price; } public function loadProduct($id) { return $this->productloader->create()->load($id); } }
- Step 2: Create file app/code/Bss/Bestsellerwidget/etc/module.xml to declare module.
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Bss_Bestsellerwidget" setup_version="1.0.0"> <sequence> <module name="Magento_Sales"/> </sequence> </module> </config>
- Step 2: Create file app/code/Bss/Bestsellerwidget/etc/widget.xml to add a widget using in CMS block/page.
<?xml version="1.0" encoding="UTF-8"?> <widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Magento/Widget/etc/widget.xsd"> <widget id="bss_bestsellerwidget" class="Bss\Bestsellerwidget\Block\Widget\Bestsellerdproduct"> <label translate="true">Bestseller Product Widget</label> <description>Bss Bestseller Product Widget</description> <parameters> <parameter name="productcount" xsi:type="text" visible="true" sort_order="1" > <label translate="true">Product Count</label> </parameter> <parameter name="imagewidth" xsi:type="text" visible="true" sort_order="2" > <label translate="true">Image Width</label> </parameter> <parameter name="imageheight" xsi:type="text" visible="true" sort_order="3" > <label translate="true">Image Height</label> </parameter> </parameters> </widget> </widgets>
- Step 3: Create file app/code/Bss/Bestsellerwidget/view/frontend/templates/widget/bestsellerdproduct.phtml to display template at the frontend.
<?php if ($exist = ($this->getBestsellerProduct() && $this->getBestsellerProduct()->getPageSize())) { $fetProdCollection = $this->getBestsellerProduct(); $productcount = $this->getProductLimit(); $imagewidth = $this->getProductimagewidth(); $imageheight = $this->getProductimageheight(); $mode = 'grid'; $title = __('Bestseller Products'); $type = 'widget-bestseller-grid'; $image = 'bestseller_products_content_widget_grid'; } ?> <?php if ($exist):?> <div class="block widget block-bestseller-products <?php /* @escapeNotVerified */ echo $mode; ?>"> <div class="block-title"> <strong role="heading" aria-level="2"><?php /* @escapeNotVerified */ echo $title; ?></strong> </div> <div class="block-content"> <?php /* @escapeNotVerified */ echo '<!-- ' . $image . '-->' ?> <div class="products-<?php /* @escapeNotVerified */ echo $mode; ?> <?php /* @escapeNotVerified */ echo $mode; ?>"> <ol class="product-items <?php /* @escapeNotVerified */ echo $type; ?>"> <?php $iterator = 1; ?> <?php foreach ($fetProdCollection as $item): $prod = $block->loadProduct($item->getProductId()); ?> <?php /* @escapeNotVerified */ echo($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?> <div class="product-item-info"> <?php $imageUrl = $block->imageHelperObj()->init($prod, 'product_page_image_small') ->setImageFile($prod->getFile()) ->resize($imagewidth,$imageheight) ->getUrl(); ?> <a href="<?php /* @escapeNotVerified */ echo $prod->getProductUrl() ?>" class="product-item-photo"> <img src="<?php echo $imageUrl;?>" alt="<?php echo $this->escapeHtml($prod->getName()) ?>" /> </a> <div class="product-item-details"> <strong class="product-item-name"> <a title="<?php echo $block->escapeHtml($prod->getName()) ?>" href="<?php /* @escapeNotVerified */ echo $prod->getProductUrl() ?>" class="product-item-link"> <?php echo $block->escapeHtml($prod->getName()) ?> </a> </strong> <?php echo $this->getProductPriceHtml($prod, $type); ?> <div class="product-item-actions"> <div class="actions-primary"> <?php if ($prod->isSaleable()): ?> <?php if ($prod->getTypeInstance()->hasRequiredOptions($prod)): ?> <button class="action tocart primary" data-mage-init='{"redirectUrl":{"url":"<?php /* @escapeNotVerified */ echo $block->getAddToCartUrl($prod) ?>"}}' type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>"> <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> <?php else: ?> <?php $postDataHelper = $this->helper('Magento\Framework\Data\Helper\PostHelper'); $postData = $postDataHelper->getPostData($block->getAddToCartUrl($prod), ['product' => $prod->getId()]); ?> <button class="action tocart primary" data-post='<?php /* @escapeNotVerified */ echo $postData; ?>' type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart')>"> <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> <?php endif; ?> <?php else: ?> <?php if ($prod->getIsSalable()): ?> <div class="stock available"><span><?php /* @escapeNotVerified */ echo __('In stock') ?></span></div> <?php else: ?> <div class="stock unavailable"><span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span></div> <?php endif; ?> <?php endif; ?> </div> </div> </div> </div> <?php echo($iterator == count($fetProdCollection)+1) ? '</li>' : '' ?> <?php endforeach ?> </ol> </div> <?php endif;?>
- Step 4: Now we need to run command setup:upgrade and deploy (if need).
>>> Learn more: How to Create Module in Magento 2 in 4 Simple Steps
#2. Frontend Configuration
After creating the module already, we need to display bestseller products on the Magento 2 frontend. We will create a widget by going to “Content -> Widget -> Add Widget”.
In the field “Type”, please select “Bestseller Product Widget”.
We could place the bestseller product box in everywhere we want.
For example, if we would like to place at homepage, we could select “Content -> Pages -> select Homepage” then add code: {{widget type=”Bss\Bestsellerwidget\Block\Widget\Bestsellerdproduct” productcount=”10″ imagewidth=”170″ imageheight=”170″}}.
>>> Looking for more guidance on Magento 2? Check out our Ultimate Magento 2 Tutorial for Beginners to master the essentials and confidently grow your store!
The result
Below is the full guide on how to display best seller products in Magento 2. Now we could see the bestseller product which we just created at the frontend.
Conclusion
In conclusion, displaying best seller products in Magento 2 is a powerful way to boost customer engagement and sales. Whether done through the admin panel or programmatically, the process is straightforward with the right approach. For any assistance or to enhance your Magento store with expert solutions, BSS Commerce is here to help. Feel free to reach out to us for any Magento-related challenges!