Customising product info tabs in Magento 2

Customising product info tabs in Magento 2

Whether horizontal (which are more common) or vertical, tabs are a great way to avoid information overload by organizing large content into easily digestible chunks of data. When done right they provide all the information (related to one specific subject) without overwhelming users, allowing them to quickly navigate through the content by showing data from just one tab at a time. From the UX standpoint tabs’ main purpose is to simply facilitate access to information and it’s also useful to know that they don’t have any negative effect on your SEO and site ranking in any way.

In Magento, like in most other eCommerce platforms, tabbed navigation is utilized on product pages for displaying various product information and data. By default, and this is the same for Luma and Blank theme, there are three tabs on the product page:
details about the product i.e. description
more information which stores product attributes and values
reviews provided by products buyers and consumers

These tabs can easily be customised, and we’ll show you how. But, just before we start let’s take some time to explore and find out which templates and layout files we are actually going to customise. One way to do this is to enable Template Path Hints and add Block Names to Hints through Magento admin:

Stores => Configuration => Advanced => Developer => Debug

Although, it’s doubtful how useful these debug settings are at least now we know which Magento module (hint: module-catalog) is responsible for product info tabs so we can begin with our customisation. Let’s start off easy.

Renaming product tabs

In order to set another title for our tab we have to override base layout file catalog_product_view.xml found inside vendor/module_catalog folder. Standard (Magento) way to do this is to create new layout file inside our theme scope and name it exactly like the base file.

Our file path should look like this:
app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/layout/catalog_product_view.xml

And the code inside our file like this:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <referenceBlock name="product.info.details">                
      <referenceBlock name="product.info.description">
        <arguments>
          <argument name="title" translate="true" xsi:type="string">Description</argument>
        </arguments>
      </referenceBlock>
    </referenceBlock>
  </body>
</page>

If we analyse the code above we’ll see that the first layout handler
<referenceBlock name="product.info.details"> reference our product tabbed navigation as a whole while the child handler <referenceBlock name="product.info.description"> reference single tab, in our case details tab. With <argument name="title" translate="true" xsi:type="string"> we simply set new title for our tab. <arguments> handler is just a (required) container for <argument> and it does’t have it’s own attributes.

Removing product tabs

This one is even more simple. We just have to reference our target block and set remove attribute to true. So our catalog_product_view.xml looks like this:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <referenceBlock name="product.info.review" remove="true" />
  </body>
</page>

Adding custom tab

Now, let’s say we want to create an additional tab in our product info tabs and populate it with content e.g. value of some particular attribute. For demonstration purpose, let’s say that our new tab will hold information about contents of product packaging.

First, from Magento admin, we will create new attribute, let’s name it Packaging and add it to default attribute set.
Next, we will:
– create new template file, we can name it packaging-content.phtml
– save it in: app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/view/
– paste the following code:

<?php
$_helper = $this->helper('Magento\Catalog\Helper\Output');
$_product = $block->getProduct();
$_code = $block->getAtCode();
$_className = $block->getCssClass();
$_attributeLabel = $block->getAtLabel();
$_attributeType = $block->getAtType();
$_attributeAddAttribute = $block->getAddAttribute();
if ($_attributeLabel && $_attributeLabel == 'default') {
    $_attributeLabel = $_product->getResource()->getAttribute($_code)->getFrontendLabel();
}
  $_attributeValue = $_product->getResource()->getAttribute($_code)->getFrontend()->getValue($_product);
?>
 
<?php if ($_attributeValue): ?>
    <div class="packaging-content" <?php  echo $_attributeAddAttribute;?>>
        <?php echo $_attributeValue; ?>
    </div>
<?php endif; ?>

N.B. attribute set (from the first step) must match string value in our if statement (line: 9)

Third and final step is to place following code in our layout file catalog_product_view.xml:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <referenceBlock name="product.info.details">                
      <block class="Magento\Catalog\Block\Product\View\Description" name="packaging-content" template="Magento_Catalog::product/view/packaging-content.phtml" group="detailed_info">
        <arguments>
          <argument name="at_call" xsi:type="string">getPackaging</argument>
          <argument name="at_code" xsi:type="string">packaging</argument>
          <argument name="css_class" xsi:type="string">packaging</argument>
          <argument name="at_label" xsi:type="string”>packaging</argument>
          <argument name="add_attribute" xsi:type="string">itemprop="packaging"</argument>
          <argument name="title" translate="true" xsi:type="string">Packaging content</argument>
        </arguments>
      </block>
    </referenceBlock>
  </body>
</page>

Adding related products in tabbed navigation

For adding related products we also need two files, template and layout:
Our template file, we shall name it related-products.phtml and save it in app/design/frontend/<Vendor>/<Theme>/Magento_Catalog/templates/product/ will have just one line of code:

<?php echo $this->getBlockHtml('catalog.product.related'); ?>

And our layout file catalog_product_view.xml should look like this:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";; xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <!— 1st Code Block: Get Related Products as new tab -->
    <referenceBlock name="product.info.details">
      <block class="Magento\Catalog\Block\Product\View" name="deliveryinfo.tab" as="deliveryinfo" template="Magento_Catalog::product/related-products.phtml" group="detailed_info" >
        <arguments>
          <argument translate="true" name="title" xsi:type="string">Related Products</argument>
        </arguments>
      </block>
    </referenceBlock>
 
    <!— 2nd Code Block: Move original block to product info tabs -->
    <move element="catalog.product.related" destination="product.info.details" />
  </body>
</page>

First code block is to set up a new tab with related products, and the second one is for removing the original block from layout flow.

In similar fashion this can be done for displaying upsell products as well. All we need to do is change our template (we can name it upsell-products.phtml) file to:

<?php echo $this->getBlockHtml('product.info.upsell'); ?>

And in our layout file change:
– name of template file to upsell-products.phtml (line: 6)
– title of our tab to “You might be interested” or something similar (line: 8)
– element attribute to product.info.upsell (line: 14)

Wrapping up

As you can see from these examples, it’s fairly easy to customise product page tabbed navigation. Add some CSS for styling and you’ll have your new tabs with new customised content in a matter of few hours.

And if you wish to customise some other parts of product page you can refer to this blog post.

Related Inchoo Services

You made it all the way down here so you must have enjoyed this post! You may also like:

Sticky Sidebar in Magento Danijel Vrgoc
, | 2

Sticky Sidebar in Magento

Customising product info tabs in Magento 2 (part 2) Igor Tikvic
, | 2

Customising product info tabs in Magento 2 (part 2)

Programmatically create upsell, cross sell and related products in Magento Damir Serfezi
Damir Serfezi, | 3

Programmatically create upsell, cross sell and related products in Magento

8 comments

  1. According to your tutorial I added the related products as a custom tab. This works great so far.
    But i ran into a problem: What if a product has no related products assigned to it? At the moment the tab content is empty, but the tab is still there, of course. I guess I need some sort of an if-condition but I don’t know how to handle this problem within the xml-file :-/

  2. Hi,

    Using your snippet I am unable to add more than one custom product tab. It throws exception

    Element 'argument': Duplicate key-sequence ['title'] in key identity-constraint 'blockArgumentName'
    . The same exception for other argument type like at_call and at_code.
    
    How do I more multiple product tabs using your above code?
    
    Thanks.

  3. How would you best add a tab, like the example above, that uses a drop down with admin codes being ‘size charts’ but different size charts vis CMS blocks?{{widget type="Magento\Cms\Block\Widget\Block" template="widget/static_block/default.phtml" block_id="8"}}

  4. On the adding a custom tab, what would be the best method to render the attributes front end label as a CMS block:

    eg: admin label is size chart and the size chart is: {{widget type=”Magento\Cms\Block\Widget\Block” template=”widget/static_block/default.phtml” block_id=”8″}}

    With there being different size charts per item.

    1. I also faced the problem how to change order of the product tabs.
      Regular solution with after/before attributes in xml didn`t work in this case.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.