Skip to content
Log in

Google address autocomplete

On this page

What you need

Add store variables

  1. Open your store in StoreConnect.
  2. Select New in the Store Variables section and add the following variables.
    1. Name - Address Auto-complete Google API Key - google_autocomplete_api_key Value - your Google Maps API key Available in Liquid = true
    2. Name - Address Auto-complete Countries Key - autocomplete_countries Value - 2 character, comma separated ISO code for each country you want to support i.e. US, CA (Google supports up to five at a time) Available in Liquid = true
    3. Name - Default Auto-complete Country Key - default_autocomplete_country Value - 2 character ISO code for one country you want to include Available in Liquid = true
  3. Save.

Update your theme layout template (in Liquid)

  1. Open your theme record in StoreConnect.
  2. Open the applicable Theme Template.
  3. If your theme doesn’t already have a theme template, grab it here and create one for your theme: theme.liquid
  4. Add the following code to the very bottom of the theme template Content section. This ensures address fields have loaded before the layout runs.
  5. Select Save.

```liquid

{%- assign google_autocomplete_api_key = store_variables[‘google_autocomplete_api_key’] default: blank -%}  
{%- assign autocomplete_countries = store_variables[‘autocomplete_countries’] default: ‘AU,US’ strip -%}
{%- assign default_autocomplete_country = store_variables[‘default_autocomplete_country’] default: ‘AU’ -%}  

// Google Maps loader (g=>{var h,a,k,p=”The Google Maps JavaScript API”,c=”google”,l=”importLibrary”,q=”ib“,m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement(“script”));e.set(“libraries”,[…r]+””);for(k in g)e.set(k.replace(/[A-Z]/g,t=>”_“+t[0].toLowerCase()),g[k]);e.set(“callback”,c+”.maps.”+q);a.src=https://maps.${c}apis.com/maps/api/js?+e;d[q]=f;a.onerror=()=>h=n(Error(p+” could not load.”));a.nonce=m.querySelector(“script[nonce]”)?.nonce||”“;m.head.append(a)}));d[l]?console.warn(p+” only loads once. Ignoring:”,g):d[l]=(f,…n)=>r.add(f)&&u().then(()=>dl)}) ({key: “{{ google_autocomplete_api_key }}”, v: “weekly”});

const allowedCountries = ‘{{ autocomplete_countries }}’.split(‘,’).map(c => c.trim()).filter(c => c);

let autocomplete; let address1Field; let address2Field; let cityField; let postalField; let countryField; let stateField;

async function initAutocomplete() { try { // Import the places library await google.maps.importLibrary(‘places’);

    // Get form fields
    address1Field = document.querySelector('#shipping_address_line_1');
    address2Field = document.querySelector('#shipping_address_line_2');
    cityField = document.querySelector('#shipping_city__customer_information');
    postalField = document.querySelector('#shipping_postal_code__customer_information');
    countryField = document.querySelector('#shipping_country__customer_information');
    stateField = document.querySelector('#shipping_state__customer_information');

    if (!address1Field) {
        console.error('Address field not found');
        return;
    }

    // Set default country
    if (countryField) {
        countryField.value = '{{ default_autocomplete_country }}';
        countryField.dispatchEvent(new Event('change', { bubbles: true }));
    }

    // Update placeholder
    address1Field.placeholder = 'Start typing your address...';

    // Create autocomplete on the existing input using the Autocomplete class
    autocomplete = new google.maps.places.Autocomplete(address1Field, {
        componentRestrictions: { country: ['{{ default_autocomplete_country }}'] },
        fields: ['address_components', 'geometry'],
        types: ['address']
    });

    // Listen for place selection
    autocomplete.addListener('place_changed', fillInAddress);

    // Listen for country changes
    if (countryField) {
        countryField.addEventListener('change', function() {
            const selectedCountry = this.value;

            if (selectedCountry && allowedCountries.includes(selectedCountry)) {
                // Update autocomplete country restriction
                autocomplete.setComponentRestrictions({
                    country: [selectedCountry]
                });

                // Clear form fields when country changes
                if (address1Field) address1Field.value = '';
                if (address2Field) address2Field.value = '';
                if (cityField) cityField.value = '';
                if (postalField) postalField.value = '';
                if (stateField) stateField.value = '';
            }
        });
    }

} catch (error) {
    console.error('Failed to initialize autocomplete:', error);
} }

function fillInAddress() { const place = autocomplete.getPlace();

if (!place.address_components) {
    console.log('No address components found');
    return;
}

let address1 = '';
let postcode = '';
let city = '';
let state = '';

// Parse address components
for (const component of place.address_components) {
    const types = component.types;

    if (types.includes('street_number')) {
        address1 = component.long_name + ' ';
    }
    if (types.includes('route')) {
        address1 += component.long_name;
    }
    if (types.includes('locality')) {
        city = component.long_name;
    }
    if (types.includes('administrative_area_level_1')) {
        state = component.short_name;
    }
    if (types.includes('postal_code')) {
        postcode = component.long_name;
    }
}

// Fill in the form fields
address1Field.value = address1.trim();
if (cityField) cityField.value = city;
if (postalField) postalField.value = postcode;

// Set state - give state dropdown time to populate
if (stateField && state) {
    setTimeout(() => {
        stateField.value = state;
        stateField.dispatchEvent(new Event('change', { bubbles: true }));
    }, 500);
}

// Focus on address line 2 for apartment/unit number
if (address2Field) {
    address2Field.focus();
}

console.log('Address filled:', { address1, city, state, postcode }); }

// Initialize when DOM is ready if (document.readyState === ‘loading’) { document.addEventListener(‘DOMContentLoaded’, initAutocomplete); } else { initAutocomplete(); }

/* Style the autocomplete dropdown */ .pac-container { z-index: 10000 !important; border-radius: 8px; margin-top: 4px; box-shadow: 0 2px 6px rgba(0,0,0,0.3); font-family: inherit; }

.pac-item { padding: 10px 12px; cursor: pointer; font-size: 14px; line-height: 1.4; }

.pac-item:hover { background-color: #f5f5f5; }

.pac-item-query { font-size: 15px; color: #333; }

.pac-matched { font-weight: 600; } ```

Was this article helpful?

Was this article helpful?