Shopify Store Locator Generator
A location list with a click-to-switch map, no Google Maps API key needed.
Your details
Your section file (sections/store-locator.liquid)
{%- comment -%}
Store locator. Add one Location block per store in the theme editor; each gets a "Get
directions" link (Google Maps, no API key needed) and, if the map is on, clicking a location
swaps a plain Maps embed to that address.
Managing many stores as a metaobject instead? Swap the {% for block in section.blocks %} loop
below for {% for location in metaobjects.store_location.values %} and read
location.name.value, location.address.value etc. once you've created a "Store location"
metaobject definition under Settings → Custom data → Metaobjects.
{%- endcomment -%}
{%- style -%}
#StoreLocator-{{ section.id }}{background:#ffffff;padding:1.5rem 1rem}
#StoreLocator-{{ section.id }} .ea-sl__heading{margin:0 0 1rem;font-size:1.3em;font-weight:600}
#StoreLocator-{{ section.id }} .ea-sl__layout{display:grid;grid-template-columns:minmax(240px,340px) 1fr;gap:1.5rem;align-items:start}
#StoreLocator-{{ section.id }} .ea-sl__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem;max-height:420px;overflow:auto}
#StoreLocator-{{ section.id }} .ea-sl__item{border:1px solid #e5e5e5;border-radius:8px;padding:.75rem .9rem}
#StoreLocator-{{ section.id }} .ea-sl__item.is-active{border-color:#1a1a1a}
#StoreLocator-{{ section.id }} .ea-sl__select{display:block;width:100%;text-align:left;background:none;border:0;padding:0;font:inherit;cursor:pointer;color:inherit}
#StoreLocator-{{ section.id }} .ea-sl__name{display:block;font-weight:600}
#StoreLocator-{{ section.id }} .ea-sl__address,#StoreLocator-{{ section.id }} .ea-sl__hours{display:block;font-size:.9em;opacity:.75;margin-top:.15rem}
#StoreLocator-{{ section.id }} .ea-sl__links{display:flex;gap:.75rem;margin-top:.5rem;font-size:.85em}
#StoreLocator-{{ section.id }} .ea-sl__links a{color:#1a1a1a}
#StoreLocator-{{ section.id }} .ea-sl__map{position:relative;min-height:320px;border-radius:8px;overflow:hidden;background:#eee}
#StoreLocator-{{ section.id }} .ea-sl__map iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
@media (max-width:640px){#StoreLocator-{{ section.id }} .ea-sl__layout{grid-template-columns:1fr}}
{%- endstyle -%}
<div id="StoreLocator-{{ section.id }}" class="ea-sl">
{%- if section.settings.heading != blank -%}
<p class="ea-sl__heading">{{ section.settings.heading | escape }}</p>
{%- endif -%}
<div class="ea-sl__layout">
<ul class="ea-sl__list" role="list">
{%- for block in section.blocks -%}
<li class="ea-sl__item{% if forloop.first %} is-active{% endif %}" {{ block.shopify_attributes }}>
<button type="button" class="ea-sl__select" data-address="{{ block.settings.address | escape }}" {% if forloop.first %}aria-current="true"{% endif %}>
<span class="ea-sl__name">{{ block.settings.name | escape }}</span>
<span class="ea-sl__address">{{ block.settings.address | escape }}</span>
{%- if block.settings.hours != blank -%}<span class="ea-sl__hours">{{ block.settings.hours | newline_to_br }}</span>{%- endif -%}
</button>
<div class="ea-sl__links">
{%- if block.settings.phone != blank -%}
<a href="tel:{{ block.settings.phone | remove: ' ' | remove: '(' | remove: ')' | remove: '-' }}">{{ block.settings.phone }}</a>
{%- endif -%}
<a href="https://www.google.com/maps/dir/?api=1&destination={{ block.settings.address | url_encode }}" target="_blank" rel="noopener">Get directions</a>
</div>
</li>
{%- endfor -%}
</ul>
{%- if section.settings.show_map and section.blocks.size > 0 -%}
<div class="ea-sl__map">
<iframe
id="StoreLocatorMap-{{ section.id }}"
title="Store map"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
src="https://maps.google.com/maps?q={{ section.blocks.first.settings.address | url_encode }}&z={{ section.settings.map_zoom }}&output=embed"
></iframe>
</div>
{%- endif -%}
</div>
</div>
{%- if section.settings.show_map -%}
<script>
(function () {
var root = document.getElementById('StoreLocator-{{ section.id }}');
var frame = document.getElementById('StoreLocatorMap-{{ section.id }}');
if (!root || !frame) return;
var buttons = root.querySelectorAll('[data-address]');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function (e) {
var btn = e.currentTarget;
var items = root.querySelectorAll('.ea-sl__item');
for (var j = 0; j < items.length; j++) { items[j].classList.remove('is-active'); }
btn.closest('.ea-sl__item').classList.add('is-active');
frame.src = 'https://maps.google.com/maps?q=' + encodeURIComponent(btn.getAttribute('data-address')) + '&z={{ section.settings.map_zoom }}&output=embed';
});
}
})();
</script>
{%- endif -%}
{% schema %}
{
"name": "Store locator",
"tag": "section",
"class": "ea-store-locator-section",
"max_blocks": 30,
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Find a store near you"
},
{
"type": "checkbox",
"id": "show_map",
"label": "Show a map",
"default": true
},
{
"type": "range",
"id": "map_zoom",
"label": "Map zoom",
"min": 10,
"max": 18,
"step": 1,
"default": 14,
"info": "Higher is closer."
},
{
"type": "header",
"content": "Colors"
},
{
"type": "color",
"id": "accent",
"label": "Accent",
"default": "#1a1a1a"
},
{
"type": "color",
"id": "background",
"label": "Background",
"default": "#ffffff"
}
],
"blocks": [
{
"type": "location",
"name": "Location",
"settings": [
{
"type": "text",
"id": "name",
"label": "Name"
},
{
"type": "text",
"id": "address",
"label": "Address",
"info": "Used for the map and the directions link."
},
{
"type": "text",
"id": "phone",
"label": "Phone (optional)"
},
{
"type": "textarea",
"id": "hours",
"label": "Hours (optional)"
}
]
}
],
"presets": [
{
"name": "Store locator",
"blocks": [
{
"type": "location",
"settings": {
"name": "Downtown Flagship",
"address": "123 Main St, Austin, TX 78701",
"phone": "(512) 555-0142",
"hours": "Mon–Sat 10am–7pm, Sun 11am–5pm"
}
},
{
"type": "location",
"settings": {
"name": "Westside Outlet",
"address": "4500 Bee Cave Rd, Austin, TX 78746",
"phone": "(512) 555-0198",
"hours": "Mon–Sun 10am–8pm"
}
}
]
}
]
}
{% endschema %}
To install: in Shopify admin go to Online Store → Themes, click … next to your theme → Edit code. Under Sections choose Add a new section, name it as shown above, replace the contents with this code and save. Then open Customize and add the section where you want it. Try it on a duplicate of your theme first. Add one Location block per store, or use the "Store locator" preset already filled in from what you entered here.
The map is a plain Google Maps embed keyed to the address text, not a geocoded pin, so keep addresses formatted normally (street, city, state) for Maps to find them reliably.
Live preview
No API key required
Most store locator tutorials assume the Google Maps JavaScript API, which needs a Google Cloud account, billing enabled, and an API key you have to keep secret. This section skips all of that by using a plain Google Maps embed URL (maps.google.com/maps?q=...&output=embed), which loads inside an iframe with no key and no account.
Each store is its own block in the theme editor, so staff can add or edit locations without touching code. Clicking a location in the list swaps the embedded map to that address and adds a "Get directions" link built from Google's directions URL format, which also works without a key.
- If you manage locations as a metaobject instead of blocks, swap the block loop for
{% for location in metaobjects.store_location.values %}, once you've created a matching metaobject definition under Settings → Custom data → Metaobjects. - The map is a plain address lookup, not a geocoded pin, so keep addresses in a normal street/city/state format.
Adding it to your theme
- 01
Add the section
Online Store → Themes → Edit code → Sections → Add a new section named
store-locator, paste the code, then add it to a page (like a Store Locator or Contact page) in Customize. A Location block preset is already filled in from what you entered here.
Questions people ask
Do I need a Google Maps API key?
No. This uses a plain Maps embed URL, which works without an API key or a Google Cloud account for basic display and directions links.
Can I show all locations on one map with pins?
Not with this generator. A single map with a pin per store needs the Google Maps JavaScript API (a key, billing and more setup). This gives you one embed that switches address when you click a different location, which covers most small chains without that overhead.
How many locations can I add?
Up to 30 blocks. For more, consider the metaobjects approach mentioned in the guide, which scales better in the theme editor.
Will this work if I don't use Online Store 2.0?
It's written as a section for Online Store 2.0 themes (sections with blocks, edited in Customize). Vintage themes without section support would need a developer to adapt it.
Related tools
Last reviewed 30 September 2026.
Sources: Google Maps Embed without an API key (output=embed)
