How can i use external scripts in theme app extension (liquid)

Topic summary

A developer is trying to integrate the Google Maps API into a Shopify theme app extension using Liquid but encounters a timing issue: the page loads before Google’s script, causing google variable to be undefined.

Initial Problem:

  • Cannot use async or defer attributes on script tags in Liquid files without triggering validation errors
  • Attempted inline script imports don’t work with external scripts

Proposed Solutions:

  1. Add script to theme.liquid (made4Uo): Place the Google Maps script tag with async attribute directly in theme.liquid before the </head> closing tag, making it globally available

  2. Use external JavaScript file (diego-navarro):

    • Move the inline script to an external file (e.g., assets/app.js)
    • Reference it using {{ 'app.js' | asset_url | script_tag }} before the {% schema %} block
    • Defer keyword ensures scripts execute after DOM is ready, maintaining execution order
    • Bonus: Eliminates need for jQuery document.ready wrapper

Status: The developer tested the first solution without success; the external file approach with defer attribute appears to be the recommended method for theme app extensions.

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

Hi people, im new devolping in shopify, I need some features of google maps API so Im doing the import in a script tag.


{% render "app_snippet" %}
{% schema %}
{
"name": "Hello World",
"target": "section",
"stylesheet": "customers.css",
"javascript":"customers.js",
"settings": [
{ "label": "Color", "id": "color", "type": "color", "default": "#000000" }
]
}
{% endschema %}

In other file i have the request to my API.

const getLocations = () => {
    let map = new google.maps.Map(document.querySelector('.map_canvas'), {
        zoom: 14,
        center: new google.maps.LatLng(19.4326296, -99.1331785),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    console.log(map);
}

the problem is that my page is loaded before the google’s script and when i want to use the google variable doesnt exist.

If i dont set the property async or defer in the script tag ill get the next error by liquid when i try to push my changes.

So i have to use any of the 2 properties in the tag.

Missing async or defer attribute on script tag at blocks/customers.liquid:1

I tried to do the import since javascript but its not possible, just works with internal scripts.

I found the next possible solution but i dont think its the best way and im not sure how to do it.

1: Move the inline script to an external Javascript file

If you create an external JS file, you can load the script using the defer keyword as all deferred scripts execute in the order that they were called once the DOM is ready. As an added bonus, you wouldn't need to wrap your function with the jQuery(document).ready as you would already know that the document is ready when the script executes.

I suppose there should be a bether way.

THANKS FOR YOUR ANSWER.

Hi @Maxo ,

Try putting this script below on the theme.liquid before the closing bracket

Thanks for your answer.

Do you mean to do something like next?

didnt work, is the same resutl, if i dont set the asyn property throw me the same error and if a do it, it has the same behavior.


  

{% render "app_snippet" %}
{% schema %}
{
"name": "Hello World",
"target": "section",
"stylesheet": "customers.css",
"javascript":"customers.js",
"settings": [
{ "label": "Color", "id": "color", "type": "color", "default": "#000000" }
]
}
{% endschema %}

Oh no. :grin: Sorry did not provide more information.

  1. Go to Admin store > Online Store > Themes > Actions > Edit code

  2. Open theme.liquid file under the Layout folder.

3 . Inside the file search for , the place the script above it.

In this way, the script will be called and will be available any part of the website

Maybe this is what you are looking for:

Put this line before {% schema %}


Now in the file located in assets/app.js

( () => {
    let map = new google.maps.Map(document.querySelector('.map_canvas'), {
        zoom: 14,
        center: new google.maps.LatLng(19.4326296, -99.1331785),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    console.log(map);
}) ()

To pass parameters, refer to this:

https://community.shopify.com/topic/1576308

3 Likes