Magento 2 display out of stock products at the end of the list page.

You can display out of stock product at end of catalog page in Magento 2 using just simple way. All the Out of stock product will be displayed at end of listing page.

You need to create module for display out of stock product at end of the page.

Create registration.php and module.xml file for creating a module. I hope you have created both file for define module,

For Collection of product generate from Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection file. We need to create a plugin for load() function. we need to set our custom condition for out of stock product to beforeLoad() function.

Create a di.xml file,

Path, app/code/Rbj/OutOfStock/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!--  out of stock product at end of list -->
    <type name="Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection">
        <plugin name="Rbj_OutOfStock::OutofstockEnd" type="Rbj\OutOfStock\Plugin\Product\ProductList\Toolbar"/>
    </type>
</config>

Need to override Stock.php file from Magento\CatalogInventory\Helper\Stock class.

Create Toolbar.php file, File Path, app/code/Rbj/OutOfStock/Plugin/Product/ProductList/Toolbar.php

<?php
/**
 * @author Rakesh Jesadiya
 * @package Rbj_OutOfStock
 */

namespace Rbj\OutOfStock\Plugin\Product\ProductList;

class Toolbar
{
    /**
     * @param \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $subject
     * @param bool $printQuery
     * @param bool $logQuery
     * @return array
     */
    public function beforeLoad(\Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $subject, $printQuery = false, $logQuery = false)
    {
        $orderBy = $subject->getSelect()->getPart(\Zend_Db_Select::ORDER);
        $outOfStockOrderBy = array('is_salable DESC');
        /* reset default product collection filter */
        $subject->getSelect()->reset(\Zend_Db_Select::ORDER);
        $subject->getSelect()->order($outOfStockOrderBy);

        return [$printQuery, $logQuery];
    }
}

Clear Cache and Check in front. All the Out of stock product will display at end of listing page.