Scripts not loading in .liquid file

For some reason my .liquid file is not loading correctly for my theme app extension.

I noticed this because when i try to console log the window.niceGCisProductPage i get undefined.

So I did some digging. The .liquid file is loading correctly mostly but the seems to be running after the page loads.

Has this happened to anyone?

The block is enabled. Shown below:

      "17045291632749660504": {
        "type": "shopify://apps/izigift-test-app/blocks/gift-block/9553414d-8324-4b23-91e0-aa81212b55cd",
        "disabled": false,
        "settings": {}
      }

Below is the full gift-block code

<link rel="stylesheet" href="{{ 'flatpickr.min.css' | asset_url }}">
<script type="module"src="{{ 'flatpickr.min.js' | asset_url }}"></script>

<script>
    window.nicegc_initial_variant_id = {{ product.selected_or_first_available_variant.id | default: "null" }};
    window.niceGcImageUrl = "{{ 'iziGftLogo.png' | asset_img_url: 'large' }}";
    window.niceGcIsGiftCard = {% if product.type == 'iziGift' %}true{% else %}false{% endif %};
    window.niceGcGiftableProduct = {% if product.metafields.iziGift.giftable_product == 'true' %}true{% else %}false{% endif %};
    window.niceGcProductTitle = "{{ product.title | default: "" }}";
    window.niceGcProductHandle = "{{ product.handle | default: "" }}";
    window.niceGcAssociations = {
        {% for variant in product.variants %}
            {% assign metafield_value = variant.metafields.iziGift.GiftCard %}
            "{{ variant.id }}": "{{ metafield_value }}"{% unless forloop.last %},{% endunless %}
        {% endfor %}
    };
    window.niceGCisProductPage = {% if request.page_type == 'product' %}true{% else %}false{% endif %};
    window.niceGcModalVersion = "{{ shop.metaobjects.app--xxxxx--gift_card_modal_data.modal_version.modal_version_controller | default: "version_1" }}";
    window.offerInfo = {{ shop.metaobjects.app--xxxxx--izigift_storefront_campaign.first-campaign.configuration | default: "" }};
    window.hideButtons = {{ product.metafields.iziGift.rewardCard | default: false }};
</script>

{% for block in section.blocks %}
  {% render block %}
{% endfor %}

{% if product.type == 'iziGift' or content_for_header contains "previewBarInjector.init();" or content_for_header contains "Shopify.designMode" %}
    {% comment %}We want to show this button on 'iziGift' products or in the preview. User might open a random product
    page and try to add our button and cant see anything on the screen. Last 2 check are for the shopify customizer
    screen
    {% endcomment %}

    <style>
      form[action^="/cart/add"] button:not(.nicegc-gift-button),
      form[action^="/cart/add"] div[data-shopify="payment-button"]:not(.nicegc-gift-button),
      form[action^="/cart/add"] input[type="submit"]:not(.nicegc-gift-button)
      {% if shop.permanent_domain == 'handicraft-prym.myshopify.com' %}
        , div[class="product-select__cta"] button[type="submit"]:not(.nicegc-gift-button)
      {% endif %}
      {% if shop.permanent_domain == 'hipkids-com-au.myshopify.com' %}
        , div[class="c-product-details__add"] button[type="submit"]:not(.nicegc-gift-button)
      {% endif %}
      {% if shop.permanent_domain == "vella-bioscience.myshopify.com" %}
        , div[class="grid grid-cols-[auto_1fr] gap-2 w-full"] button[type="submit"]:not(.nicegc-gift-button)
      {% endif %}
      {
        display: none !important;
      }

      .nicegc-gift-button *::before,
      .nicegc-gift-button *::after {
        content: "" !important;
      }
    </style>
{% endif %}

{% if product.metafields.iziGift.rewardCard == true %}
  <style>
    form[action^="/cart/add"]
    {
      display: none !important;
    }
  </style>
{% endif %}



{% schema %}
{
    "name": "Send as gift button",
    "target": "body",
    "enabled_on": {
        "templates": ["*"]
     },
    "stylesheet": "gift-button.css",
    "javascript": "gift-button.js",
    "settings": []
}
{% endschema %}

This is what i can see in the elements of the dev console

Any help would be appreciated this is killing me!

1 Like

Your dev console shows window.niceGCProductPage = true; not undefined. Is this intentional?

Yea that’s another part of the problem I mean. It shows true in the dev console but when I try to log it from my gift-button.js file it logs as undefined.

1 Like

Ahhh so your references in gift-button.js are not in sync with the window. Now it is clear what you speak of. So when you reference request.page_type in gift-button.js what is that for you?

Sounds like you may have a race condition.

Theme app extension JavaScript loads via async which means the JavaScript may run before the page is finished loading (see also Theme app extension configuration). So if the inline script that contains the window.niceGCisProductPage hasn’t been processed yet, the values would be empty.

You can verify this by adding a console.log in both your external script and in the inline script block so you can see the order they are being run. I suspect you will see the external script runs first in the scenario that is broken.

One fix would be to delay the processing of your script until the dom is finished loading (aka DOMContentLoaded): Document: DOMContentLoaded event - Web APIs | MDN. If you need more control you can always load the script yourself and add your own onload handler.

1 Like

Quick solution is to load the script manually within the block code instead of using the javascript property. This at least gives you more control over when the script will be loaded. For example, you can load gift-button.js just like you did with flatpickr.min.js, but place it after your inline <script> tag. That way, when gift-button.js runs, your setup code will already be available. That’s how we have been doing it.

Hey everyone, thank you so much for the responses. I finally figured out the issue. Like I thought it would be, it was super simple :man_facepalming:t6:.

The below line of code seems like it was erroring out.

    window.nicegc_initial_variant_id = {{ product.selected_or_first_available_variant.id | default: "null" }};

I needed to change it to this:

    window.nicegc_initial_variant_id = {{ product.selected_or_first_available_variant.id | default: "" }};

Shout out to @matthew_smith I posted this on Twitter and he gave me the answer. Here it is:

2 Likes