How to get category tree in Magento 2?

The question:

I need to show category tree, just like in admin section, in my custom page. I viewed this solution in It was good but limited to 2 levels of category. I need all the categories. How can it be done?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I searched over internet for solution to this but got nothing useful. Then I diverted my research towards Magento core where I found MagentoCatalogBlockAdminhtmlCategoryTree class where I found a function getTree(). Then I tried to observed it’s return value in my custom template file. The effort became fruitful as I got the desired result.

I created a block file where I have injected the above class as:

namespace VendorModuleBlock;

class CategoriesColle extends MagentoFrameworkViewElementTemplate

    protected $adminCategoryTree;

     * @param MagentoFrameworkViewElementTemplateContext $context
     * @param MagentoCatalogHelperCategory $categoryHelper
     * @param array $data
    public function __construct(

        MagentoCatalogBlockAdminhtmlCategoryTree $adminCategoryTree

        $this->adminCategoryTree = $adminCategoryTree;

    public function getTree()
        return $this->adminCategoryTree->getTree(); 


The return value of the getTree() is the desired array of the category tree which can be verified by dumping the value in template file.

Method 2

You can create your own tree with custom collection as follows:
Firstly add a field in your ui-form:

<field name="custom" component="Namespce_Modulename/js/select-category" sortOrder="20" formElement="select">
<argument name="data" xsi:type="array">
    <item name="config" xsi:type="array">
        <item name="filterOptions" xsi:type="boolean">true</item>//to add filter in select-ui
        <item name="multiple" xsi:type="boolean">false</item>//select multiple or not
        <item name="showCheckbox" xsi:type="boolean">true</item>//to show checkboxes
        <item name="disableLabel" xsi:type="boolean">true</item>
        <rule name="required-entry" xsi:type="boolean">true</rule>
    <label translate="true">Select Category</label>//label to Field
    <dataScope>data.custom</dataScope>//To map
        <link name="${ $.namespace }.${ $.namespace }:responseData">setParsed</link>
            <options class="NamespaceModuleNameUiComponentFormCategoryOptions"/>

Now create Js file to map the field’s value:


], function (Select) {
'use strict';
return Select.extend({
     * Parse data and set it to options.
     * @param {Object} data - Response data object.
     * @returns {Object}
    setParsed: function (data) {
        var option = this.parseData(data);
        if (data.error) {
            return this;
        this.set('newOption', option);
     * Normalize option object.
     * @param {Object} data - Option object.
     * @returns {Object}
    parseData: function (data) {
        return {
            value: data.category.entity_id,

Create a file to get options to display:


namespace NamespaceModuleNameUiComponentFormCategory;

use MagentoFrameworkDataOptionSourceInterface;
use MagentoCategoryModelResourceModelCategoryCollectionFactory as      CategoryCollectionFactory;
use MagentoFrameworkAppRequestInterface;

* Options tree for "Categories" field
class Options implements OptionSourceInterface

protected $categoryCollectionFactory;

 * @var RequestInterface
protected $request;

 * @var array
protected $categoryTree;

 * @param CategoryCollectionFactory $categoryCollectionFactory
 * @param RequestInterface $request
public function __construct(
    CategoryCollectionFactory $categoryCollectionFactory,
    RequestInterface $request
) {
    $this->categoryCollectionFactory = $categoryCollectionFactory;
    $this->request = $request;

 * {@inheritdoc}
public function toOptionArray()
    return $this->getCategoryTree();

 * Retrieve categories tree
 * @return array
protected function getCategoryTree()
    if ($this->categoryTree === null) {
        $collection = $this->categoryCollectionFactory->create();


        foreach ($collection as $category) {
            $categoryId = $category->getEntityId();
            if (!isset($categoryById[$categoryId])) {
                $categoryById[$categoryId] = [
                    'value' => $categoryId
            $categoryById[$categoryId]['label'] = $category->getName();
        $this->categoryTree = $categoryById;
    return $this->categoryTree;


Hope it helps!

Method 3

$objectManager = MagentoFrameworkAppObjectManager::getInstance();
                //$category = $objectManager->create('MagentoCatalogModelCategory')
                $category = $objectManager->create('MagentoCatalogModelResourceModelCategoryCollectionFactory')->create()
                    ->addAttributeToFilter('level',array('nin' => array(1)))
                    ->addAttributeToFilter('path',array('like' => '%'.$rootCategoryId.'%'))
                    ->addAttributeToSort('parent_id', 'ASC')
                    ->addAttributeToSort('position', 'ASC')
                    ->addAttributeToSort('path', 'ASC');
                // print_r($category->getData());
                $catArray = [];
                foreach ($category as $cat){
                    $catArray[$cat->getID()]['id']= $cat->getID();
                    $catArray[$cat->getID()]['name'] = $cat->getName();
                    $catArray[$cat->getID()]['parent_id'] = $cat->getParentId();
                    $catArray[$cat->getID()]['position'] = $cat->getPosition();
                    $catArray[$cat->getID()]['path'] = $cat->getPath();

Method 4

// Get all the children categories of given category collection factory
foreach ($collection as $key => $value) {
            $temp = $value->getData();
            $categoryObj = $this->_repository->get($temp['entity_id']);
            $subcategories = $categoryObj->getChildrenCategories();
            foreach($subcategories as $key2 => $subcategory) {
                if($subcategory->hasChildren()) {
                    $childCategoryObj = $this->_repository->get($subcategory->getId());
                    $childSubcategories = $childCategoryObj->getChildrenCategories();
                    foreach($childSubcategories as $childSubcategory) {
                        $temp2 = $childSubcategory->getData();
                        $temp1['children'][] = $temp2;
                    $temp['children'][] = $temp1;
            $item[$key][] = $temp;
// Here you can get all the children upto 2 level in "item" variable
echo "<pre>";

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment