Magento 2 - How to keep those checkout error messages from disappearing

Published Thursday, October 19, 2017

If you ever had an error during checkout, you might have noticed that the error message hides after a few seconds. It's five seconds to be exact. That's too quick for me. Many times I don't notice it until it disappears.

Why hide it at all? I think it's best to keep it visible until the customer decides to hide it. Here's how to accomplish that:

First, copy this file:

 
   vendor/magento/module-ui/view/frontend/web/template/messages.html
 

Over to:

 
   app/design/frontend/YourPackage/YourTheme/Magento_Ui/web/template/messages.html
 

Then change this line:

 
  7<div data-role="checkout-messages" class="messages" data-bind="visible: isVisible(), click: removeAll">
 

To:

 
  7<div data-role="checkout-messages" class="messages" data-bind="click: removeAll">
 

Clear your cache and re-deploy the static content:

 
   bin/magento setup:upgrade
   bin/magento setup:static-content:deploy
 

There you have it. This will keep the message visible until the customer clicks on it.

How does this work?

The "visible: isVisible()" part tells the component to trigger a timer when the error message becomes visible. You can see this in:

vendor/magento/module-ui/view/frontend/web/js/view/messages.js [copy] [hide]

 48/**
 49 * Checks visibility.
 50 *
 51 * @return {Boolean}
 52 */
 53isVisible: function () {
 54    return this.isHidden(this.messageContainer.hasMessages());
 55},

[copy] [hide]

 19defaults: {
 20    template: 'Magento_Ui/messages',
 21    selector: '[data-role=checkout-messages]',
 22    isHidden: false,
 23    listens: {
 24        isHidden: 'onHiddenChange'
 25    }
 26},

This watches for any error messages that might load, and to call onHiddenChange() when that happens:

[copy] [hide]

 67onHiddenChange: function (isHidden) {
 68    var self = this;
 69
 70    // Hide message block if needed
 71    if (isHidden) {
 72        setTimeout(function () {
 73            $(self.selector).hide('blind', {}, 500);
 74        }, 5000);
 75    }
 76}

This tells it to hide the error message after 5000 milliseconds.

The choice to use "isHidden" as the variable name is a bit confusing. When the message container has messages, isHidden is set to true. That sounds backwards to me. Basically, isHidden acts like a switch. It's initially set to false by default, and then gets set to true when there are messages, triggering the hide timer in onHiddenChange.