# Google address autocomplete

Source: https://support.storeconnect.com/articles/google-address-autocomplete · Last modified 21 August 2026

## What you need 

-   A [Google Maps API Key](https://developers.google.com/maps/documentation/embed/get-api-key)
-   The [ISO code for each country](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) you want to support using this method

## Add store variables 

1.  Open your store in StoreConnect.
2.  In the **Store Variables** section, click **New** 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, for example `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.  Click **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](https://github.com/GetStoreConnect/base-theme/blob/main/templates/layouts/theme.liquid "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(()=>d[l](f,...n))})
({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;
}
```

---

## Follow StoreConnect

- [Email Newsletter](https://getstoreconnect.com/c/lp-newsletter)
- [LinkedIn Newsletter](https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7444956928444862464)
- [YouTube](https://www.youtube.com/channel/UCngKdP2x8l1wcbAKW3tvU8g)
- [LinkedIn](https://www.linkedin.com/company/storeconnect)
- [X / Twitter](https://x.com/storeconnecthq)

## Popular Links

- [Partners](https://getstoreconnect.com/partners)
- [News](https://getstoreconnect.com/articles/news)
- [Events](https://getstoreconnect.com/articles/events)
- [Feature Comparison](https://getstoreconnect.com/how-we-compare)
- [Download a free trial](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FMkeKUAT)
- [Book a Demo](https://getstoreconnect.com/contact)

## Documentation

- [Help documentation](https://support.storeconnect.com/help-documentation)
- [AI agents](https://support.storeconnect.com/ai)
- [Videos & tutorials](https://support.storeconnect.com/videos-tutorials)
- [Developer reference](https://support.storeconnect.com/developer-reference)
- [Release notes](https://support.storeconnect.com/release-notes)
- [Troubleshooting](https://support.storeconnect.com/troubleshooting)
- [Trust Center](https://trust.getstoreconnect.com/)
- [Status Page](https://status.storeconnect.com/)

## Contact

- info@getstoreconnect.com
- US +1 415 745 3230
- AUS +61 2 8365 2308

100 S Ashley Dr, Suite 600-2461
Tampa FL 33602-600 USA

Level 22, Sydney Place
180 George Street
Sydney, NSW, 2000, AUS

---

StoreConnect Support — https://support.storeconnect.com/articles/google-address-autocomplete