Countdown Timer works on Android and PC but not IOS

Topic summary

A Shopify store owner reports a countdown timer displaying “NaN” error on iOS devices while functioning correctly on Android and desktop browsers. Screenshots confirm the cross-platform inconsistency.

Troubleshooting attempts:

  • Initial suggestion to wrap the script in a DOMContentLoaded event listener didn’t resolve the issue
  • Testing on multiple physical iPhones (iPhone 14 and others) consistently reproduced the error
  • One responder tested on iPhone 11, 11 Pro, and 12 without encountering problems, suggesting potential device-specific or inspection tool differences

Root cause identified:
The issue stems from date string parsing inconsistencies across browsers. The code uses new Date('{{ section.settings.custom_liquid }} 00:00:00'), but iOS Safari parses date strings differently than other browsers.

Proposed solution:
Reformat the date string to the ISO 8601 standard (yyyy-mm-ddThh:mm:ss.sssZ), which is universally recognized across all browsers. Adding “.000” to the time format should resolve the parsing issue and eliminate the NaN error on iOS devices.

Additional note: There’s a mismatch between using countdown as a class in HTML while attempting to retrieve it by ID in the script.

Summarized with AI on November 5. AI used: claude-sonnet-4-5-20250929.

Hello,

The countdown timer on the site has a “NaaN” error when viewed on iOS devices (right screenshot). However, it looks ok when viewed on Desktop/Android (left screenshot).

Can you advise how to fix please? The code is below. Thank you.

{%- style -%}
  .section-{{ section.id }}-padding {
    padding-top: calc({{ section.settings.padding_top }}px * 0.75);
    padding-bottom: calc({{ section.settings.padding_bottom }}px  * 0.75);
  }

  @media screen and (min-width: 750px) {
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top }}px;
      padding-bottom: {{ section.settings.padding_bottom }}px;
    }
  }
{%- endstyle -%}
<div class="color-{{ section.settings.color_scheme }} gradient">
  <div class="section-{{ section.id }}-padding">

    {%- if section.id == 'template--20243326697784__fd66ea91-20e6-4508-ab6d-1bb16e7dc913' %} 
      <section>
  <div class="timerhead" >
    <h2>Flash Sale</h2>
  </div>
  <div style="display:flex; align-items: center; font-weight: 700; padding-right:40px; max-width:100%;">
    Ends In :  
    <div class="countdown">
      <div id="days" class="countCls"  style="margin-right: 10px;"></div> :  
      <div id="hours" class="countCls"  style="margin-right: 10px;"></div> :  
      <div id="minutes" class="countCls"  style="margin-right: 10px;"></div> :  
      <div id="seconds" class="countCls" ></div>
    </div>
  </div>
</section>

<script>
  // Set the target date for the product arrival
  const targetDate = new Date('{{ section.settings.custom_liquid }} 00:00:00').getTime();

  // Update the countdown every second
  const countdownInterval = setInterval(function() {
    const now = new Date().getTime();
    const timeRemaining = targetDate - now;

    if (timeRemaining <= 0) {
      clearInterval(countdownInterval);
      document.getElementById('countdown').innerHTML = 'Product has arrived!';
    } else {
      const days = Math.floor(timeRemaining / (1000 * 60 * 60 * 24));
      const hours = Math.floor((timeRemaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      const minutes = Math.floor((timeRemaining % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((timeRemaining % (1000 * 60)) / 1000);

      document.getElementById('days').innerHTML = `${days}D`;
      document.getElementById('hours').innerHTML = `${hours}H`;
      document.getElementById('minutes').innerHTML = `${minutes}M`;
      document.getElementById('seconds').innerHTML = `${seconds}S`;
    }
  }, 1000);
</script>
    {% else -%}
      {{ section.settings.custom_liquid }}
    {% endif -%}
    

    
  </div>
</div>

{% schema %}
{
  "name": "t:sections.custom-liquid.name",
  "tag": "section",
  "class": "section",
  "settings": [
    {
      "type": "liquid",
      "id": "custom_liquid",
      "label": "t:sections.custom-liquid.settings.custom_liquid.label",
      "info": "t:sections.custom-liquid.settings.custom_liquid.info"
    },
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "label": "t:sections.all.colors.label",
      "default": "background-1"
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 40
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 52
    }
  ],
  "presets": [
    {
      "name": "t:sections.custom-liquid.presets.name"
    }
  ]
}
{% endschema %}

Hi @bryanquek
Tested it on IOS device and it is working fine on my end.
However, you can try updating your script as

document.addEventListener("DOMContentLoaded", function(){ 
//your script here
})

Please hit Like and Mark as a solution if it helps

I tried adding the script and viewed again on my iPhone14 device but still has that error.

What iOS phone are you using?

@bryanquek
I have tested it on iPhone 11, iPhone 11 Pro, iPhone 12 as seems to working fine on my end.
Can you share the URL on which you are getting the issue. If you’d like to discuss this more, don’t hesitate to send me a PM.

Please hit Like and mark it as a solution if this has helped you.

I tried on a few other physical iPhones as well and all of them still has the ‘NaN’ error.
Could you be trying via the Chrome inspect tool?

Hi @bryanquek
Please share your store URL as I can check better in that case.

Please use this! Thank you
http://oppostoresg.com/

Hi @bryanquek
Can you update the date for any future one so that I can check it.
Also, found that you are using countdown as a class in HTML but in script you are trying to get it by ID.

When you create the targetDate…

const targetDate = new Date('{{ section.settings.custom_liquid }} 00:00:00').getTime();

you pass a string value. Different browsers can parse that string differently. The universally recognised format for times is yyyy-mm-ddThh:mm:ss.sssZ, as explained here. By adding “.000” you should solve the problem.

Check this.