Theme blocks
The app adds three app blocks to any Online Store 2.0 theme. You place them in the theme editor like any section, and they adapt to the theme: they take their section’s fonts, colors and color scheme, and only add the layout they need and what accessibility requires.
This page is for the agency or developer who integrates the app into a theme. It explains which block goes where, how to set each one up for the brand and the theme, and how to change their look in a few lines of CSS. Each setting in detail is at the end of each part.
Choose a block
Section titled “Choose a block”| Block | For | Where to place it |
|---|---|---|
| Store locator | Finding the nearest store: a map, a search, filters. The right choice as soon as the brand has dozens of stores or several countries. | On a page’s template, for example “Our stores”. |
| Store page | Giving each store its own page, indexed by search engines: photos, hours, directions. | On the Store page template, once: every page uses it. |
| Store list | Showing every store at a glance, by country, type or in one grid, without a map. Ideal for a brand in a few countries, or for an “Our stores in France” or “Our stockists” page. | On a page’s template, instead of the store locator or under it. |
| Country or city page | A page per country, and per city, listing its stores, indexed by search engines. | On the Country page and City page templates, once each. |
| Store directory | The links to the country pages, and their city pages. | Under the store locator, or at the bottom of the country and city page templates. |
The blocks are served by Shopify, with the page: they stay online even if the app is unavailable. They only show active stores, each on the channels checked on its page in the app (the store locator, its page, or both). The map style and the markers come from the app’s Settings, shared by the whole shop. The maps are Mapbox’s.
Store locator
Section titled “Store locator”The visitor lands on a map already framed on their area, and the list next to it keeps the stores of that area; a search, a filter or Near me frames a new one. If they move or zoom the map, the list stays as it is: a Search this area button offers the new view, then Back to … the list before. On a computer, the list takes the left third and the map the right two thirds; on a phone, a search line, a short map, then the list, which scrolls in its own box.
Choose what the map shows on arrival
Section titled “Choose what the map shows on arrival”A world map with three dots tells the visitor nothing, and an empty map even less. The Map view on arrival setting decides the area framed on first display; If no store in that area decides the fallback when that area is empty.
| The brand… | Set Map view on arrival to |
|---|---|
| sells in several countries with Shopify Markets, and each market has its stores | Market of the online store (the default): the country chosen in the theme’s country selector. |
| has a single online store for visitors from several countries | Visitor’s position: the country of their connection, or their exact position if they already shared it with Near me. |
| is only in one country | Fixed country, with its Country code (FR). |
| has few stores | All stores. |
If the area has no store, the map frames by default the Nearest country with stores: a Belgian visitor sees France, a Japanese visitor sees Europe. A sentence under the search tells them, so the map doesn’t look wrong.
The view on arrival only applies once: as soon as the visitor moves the map, or when the link they followed already holds a city or a store, it no longer plays.
Link to a city or a store
Section titled “Link to a city or a store”The store locator keeps the visitor’s context in the page’s address: their search, the chosen city or store, the filters, the map’s position. A visitor coming back from a store page with the Back button finds the map as they left it, and you can build these addresses yourself, for example for a link from a campaign or a product page:
| Link | Opens |
|---|---|
/pages/our-stores?city=Lyon,FR |
The map framed on the stores of Lyon. |
/pages/our-stores?store=lyon-presqu-ile |
The map centered on this store (its identifier), popup open. |
/pages/our-stores?q=lyon |
The search “lyon” typed, nothing chosen. |
/pages/our-stores?type=Flagship |
Only the stores of the Flagship type checked. Repeat the parameter for several types. |
/pages/our-stores?service=Parking |
Only the stores with this service. |
/pages/our-stores?at=45.76,4.83,13 |
The map at this center (latitude, longitude) and zoom. |
The type and the service are written as on the store locator, in the page’s language. The address’s other parameters are kept.
Structure
Section titled “Structure”On a computer, a grid places the search bar and the list in the left column (one third), the map on the right (two thirds). On a phone, the three stack in the HTML’s order, which is also the tab order.
<store-locator class="store-locator">├─ .store-locator__toolbar search, Near me (.store-locator__near-me, its text .store-locator__near-me-text), filters, the shortcuts (.store-locator__cities, .store-locator__city-choice), .store-locator__open-map│ ├─ .store-locator__search the field and its suggestions (.store-locator__suggestions)│ ├─ .store-locator__results the number of stores (.store-locator__count), the filters button│ └─ .store-locator__filter-panel the checkboxes, one .store-locator__filter per filter├─ .store-locator__map the map, its group circles (.store-locator__cluster), .store-locator__area, .store-locator__back└─ .store-locator__list the list └─ .store-locator__item a store: __city (a city's heading), __nearest, __head (the name and __distance), __name (its button: __locate), __type, __address, __actions (__phone, __directions, __page)All settings
Section titled “All settings”| Setting | Values | Default | What it does |
|---|---|---|---|
| Title | text | “Find a store”, in the editor’s language | The page’s h1, above the map. Empty: no title. |
Map layout
| Setting | Values | Default | What it does |
|---|---|---|---|
| Full page width | on / off | on | The block takes the whole page width, beyond the section’s column. |
| Fill the window height | on / off | on | On a computer, the map grows with the window, under what the theme shows above the block, up to the maximum height: no big blank under it on a large screen. |
| Space above | 0 to 200 px | 0 | See Fixed header or sections without margins. |
| Side margin | 0 to 80 px | 0 | Shown when Full page width is off. |
| Map height | 400 to 1000 px | 680 px | With Fill the window height: the minimum height. On a phone, the map is 40% of the window’s height, this value at most. |
| Maximum map height | 600 to 1600 px | 960 px | With Fill the window height: the map stops growing, and the bottom of the page stays in view in a very tall window. |
| Map on demand on a phone | on / off | off | On a phone, no map on arrival: Show on map, or a card tapped, opens it, framed on the visitor’s location or search. On a computer, the map is always there. |
| Store groups on the map | Tight, Normal, Wide | Normal | Stores too close to tell apart become one circle with their number, which zooms in when clicked. Tight: smaller groups, more circles; Wide: fewer circles. No groups in a view of 50 stores or fewer, nor at street level. |
Search and filters
| Setting | Values | Default | What it does |
|---|---|---|---|
| Search | on / off | on | A search by city, postal code or store name, in the stores of the page, with no network call; a city without a store is looked up with the map’s provider. Case and accents are ignored. |
| City shortcuts | on / off | on | Under the search, the 6 cities of the arrival’s country with the most stores, with their number; hidden once the visitor searches or shares their location. |
| Type filter | on / off | on | Shown from two types. Every type is checked on arrival; stores without a type are never hidden. |
| Services filter | on / off | on | Shown when a store has a service. Nothing is checked on arrival; only the stores offering every checked service stay. |
View on arrival
| Setting | Values | Default |
|---|---|---|
| Map view on arrival | Market of the online store, Visitor’s position, Fixed country, All stores | Market of the online store |
| Country code | two letters, for example FR; used with Fixed country |
empty: the market |
| If no store in that area | Nearest country with stores, Country with the most stores, All stores | Nearest country with stores |
Store page
Section titled “Store page”The block makes up a store’s whole page: its name, its main photo as a banner, its presentation, its address with directions, its services, its contact, its hours with an “Open now” badge at the store’s local time, its exceptional hours, a map, its other photos, and the 3 nearest stores. It also describes the store to search engines (see SEO).
It only works on the Store page template, the one of every store page. You can place other theme sections above or below it, and connect them to the store’s data (see Store page template and data).
Give the title the style of other pages
Section titled “Give the title the style of other pages”The store’s name is the page’s h1. With no style of its own, it takes the theme’s h1 style, which is often larger than the titles of other pages (themes of the Horizon family set those titles with a preset). To give it the same style:
- On the Store page template, add your theme’s heading block (“Heading” in Horizon) above the Store page block.
- Connect its text to the Name field, with the dynamic source (the small plug icon).
- Choose the same style as your other page titles.
- In the Store page block, empty the Title field.
The name stays in the page’s structured data, and the Link to all stores link stays shown.
Structure
Section titled “Structure”<article class="store-page">├─ .store-page__header .store-page__title (the h1), .store-page__back (link to all stores)├─ .store-page__hero the main photo├─ .store-page__body two halves on a computer, one under the other on a phone│ ├─ .store-page__details the sections (.store-page__section): presentation, address and services,│ │ contact, hours (.store-page__hours, .store-page__special)│ └─ .store-page__aside the map (.store-page__map), the other photos (.store-page__photo)└─ .store-page__nearby the nearby stores: .store-card elementsAll settings
Section titled “All settings”| Setting | Values | Default | What it does |
|---|---|---|---|
| Title | text | [name] |
The page’s h1, [name] standing for the store’s name. Empty: no title. |
| Show photos | on / off | on | The main photo as a banner, the others under the map. |
| Show map | on / off | on | A map image, for a store with coordinates. A click opens the directions in Google Maps, in a new tab. |
| Show nearby stores | on / off | on | The 3 nearest stores with a page, as the crow flies, whatever the country. |
| Link to all stores | an address | empty: no link | A link to the store locator page, at the end of the title’s line. |
| Space above | 0 to 200 px | 0 | See Fixed header or sections without margins. |
| Side margin | 0 to 80 px | 0 | For a full-width section. |
The block’s width follows its section’s width setting (Horizon: Page or Full).
Store list
Section titled “Store list”Every store as a grid of cards, without a map: the visitor browses rather than searches. By default, under a heading per country, in the alphabetical order of their name in the visitor’s language; Group by also offers a heading per type, or a single grid. All the content is in the page’s HTML, with a link to each store page: it is also the block search engines read best. The country and city pages have their own block, which shares this one’s rendering: see Country or city page.
A page per country
Section titled “A page per country”For an “Our stores in France” page:
- Create the page and its template, then add the Store list block to it.
- In Only show these countries, enter
FR. - With a single country, the list shows no country heading: only the grid.
For a group of countries, separate the codes with commas: FR, BE, CH. For an “Our stockists” page, enter the type’s name in Only show these store types and group by country.
Structure
Section titled “Structure”<store-list class="store-list">├─ .store-list__header .store-list__title, the block's title├─ .store-list__controls the row of tools (.store-list__tools: .store-list__filter-toggle, .store-list__count), the filters panel (.store-list__filter-panel)└─ .store-list__group one per country (or per type) ├─ .store-list__country the group's heading, from two groups ├─ .store-list__grid .store-card elements └─ .store-list__section grouped by type on a country page: .store-list__section-title, then its .store-list__gridThe filters look the same in the lists and the store locator: their style is in store-filters.css, on the public classes .store-list__filter-* and .store-locator__filter-*.
A card, the same in the list and among a page’s nearby stores:
.store-card├─ .store-card__photo├─ .store-card__name the link to the page, stretched over the whole card├─ .store-card__type, .store-card__address, store-opening-status (the opening status)└─ .store-card__links .store-card__phone, .store-card__directionsAll settings
Section titled “All settings”| Setting | Values | Default | What it does |
|---|---|---|---|
| Title | text | “Our stores”, in the theme editor’s language | Above the list; empty, no title. |
List
| Setting | Values | Default | What it does |
|---|---|---|---|
| Country filter | on / off | on | From two countries; hidden when grouped by country. |
| Type filter | on / off | on | As on the store locator; hidden when grouped by type. |
| Services filter | on / off | on | As on the store locator. |
| Group by | Nothing, Type, Country | Country | A heading per country (or per type, in the order of the types in the app’s Settings, the stores without a type last; the cards then leave out the type). |
| Sort by | Name, City, then name, Type, then city | Name | Within each group. |
| Only show these countries | two-letter country codes, separated by commas | empty: every country | Limits the list to the stores of these countries. |
| Only show these store types | type names or handles, separated by commas, any case | empty: every type | Limits the list to the stores of these types; stores without a type are left out. Filtered when Shopify renders the page: the other stores are not sent. |
| Card size | Small, Medium, Large | Medium | As many cards per row as fit in the section’s width: one on a phone. |
Cards content
| Setting | Default | What it does |
|---|---|---|
| Show store type | on | The type under the name. |
| Show photos | on | The main photo at the top of the card, or an empty frame to keep the cards aligned. |
| Show address | on | The address. |
| Show opening status | on | Open or closed now, at the store’s local time. For stores with opening hours. |
| Show phone link | on | The phone number, a link to call it. |
| Show directions link | on | The directions in Google Maps, in a new tab. |
Spacing: Space above (0 to 200 px, 48 by default) and Side margin (0 to 80 px, 0 by default).
Country or city page
Section titled “Country or city page”The Country or city page block on the “Country page” (metaobject/app--<id>--country_page) and “City page” (metaobject/app--<id>--city_page) templates. It reads the country’s code (and the city) in the entry and lists the store locator’s stores of that country or city, rendered on the server: all of it is in the HTML. A country page sorts them by city, a city page by name. The page’s title and meta description are the entry’s.
- Above the list: the breadcrumb (
.store-list__breadcrumb, Home / France / Lyon), shown when Show the breadcrumb on the country and city pages is checked in the app’s Settings; the title (.store-list__header,.store-list__title), then.store-list__introduction. - Under the list,
.store-list__cities: on a country page, its city pages in alphabetical order, under Title of the cities; on a city page, the link to its country (Link to the country) and the country’s other cities, the current one not a link (aria-current="page"). - Structured data: a
CollectionPage, the country or city (about), the brand (publisher, with the same@idas on the store pages) and the breadcrumb (BreadcrumbList), shown or not.
| Setting | Values | Default | What it does |
|---|---|---|---|
| Title | text; [name] stands for the country’s or the city’s name |
[name] |
Empty: no title, for the theme’s own Heading block above. |
| Type filter, Services filter | on / off | on | As on the Store list. |
| Group by | Nothing, Type | Nothing | A heading per type, in the order of the app’s Settings. |
| Card size | Small, Medium, Large | Medium | As on the Store list. |
| Title of the cities | text; [country] stands for the country’s name |
“Our stores by city” | Empty: no title. |
| Link to the country | text; [country] stands for the country’s name |
“[country]: all our stores” | On a city page. |
The card content and spacing settings are the Store list’s.
Store directory
Section titled “Store directory”“Our stores by country”: a link per published country page, in columns, sorted by name in the visitor’s language (.country-directory, .country-directory__heading, .country-directory__list, .country-directory__link). With Show the cities, each country’s city pages under its name (.country-directory--cities, .country-directory__cities). On a country or city page, the current page is not a link (.country-directory__current, aria-current="page"). Nothing shows without a published country page. Settings: Title (empty, no title), Show the cities (off), Space above (48 px) and Side margin.
Fixed header or sections without margins
Section titled “Fixed header or sections without margins”Two settings, shared by the three blocks, fix the display on some themes, often custom-built ones:
- Space above: the theme’s header stays at the top of the screen and hides the top of the block (the store locator’s search, a page’s title). Set the header’s height, for example 90 px for an 86 px header. The store locator takes it into account to fill the window.
- Side margin: the theme’s apps section has no margins, and the block goes edge to edge. Set the space to leave on each side.
The theme editor’s preview shows the result live.
Restyle a block
Section titled “Restyle a block”The blocks have no style settings: their look comes from the theme, on purpose. To go further, an agency writes its CSS in the Custom CSS of the block’s section (500 characters) or in the theme’s CSS. The blocks’ CSS is written for that:
- a single class is enough, without
!important: each element’s base style has a single class of specificity; - variables for what is changed most often (spacing, radii, borders, backgrounds), to redefine on the block’s root;
- states as attributes:
aria-currenton the store chosen in the store locator’s list,data-state="open"or"closed"on the opening status (store-opening-status),[hidden].
Examples
Section titled “Examples”Framed cards, on a light background, in the list and among the nearby stores:
.store-card { --store-card-padding: 1rem; --store-card-background: color-mix(in srgb, currentColor 4%, transparent); border: 1px solid color-mix(in srgb, currentColor 15%, transparent);}The store locator’s list column on a brand background:
.store-locator { --store-locator-panel-background: #f4efe6; --store-locator-panel-text: #2b2118;}Square photos without rounded corners:
.store-card { --store-card-photo-ratio: 1 / 1; --store-card-radius: 0; }.store-page { --store-page-radius: 0; }The store locator’s borders, muted text and controls are computed from --store-locator-panel-text: change it with the background, keeping a 4.5:1 contrast (see Accessibility).
Classes and variables
Section titled “Classes and variables”Classes follow BEM, prefixed by the block: store-locator__…, store-page__…, store-list__…, and store-card__… for the cards of the list and of the nearby stores. The full list is at the top of each stylesheet (store-locator.css, store-page.css, store-list.css, store-card.css), which the browser’s developer tools show.
| Root | Variables |
|---|---|
.store-locator |
--store-locator-panel-text, --store-locator-panel-background, --store-locator-gap, --store-locator-border, --store-locator-muted, --store-locator-control-border, --store-locator-mobile-map |
.store-page |
--store-page-gap, --store-page-border, --store-page-muted, --store-page-radius |
.store-list |
--store-list-card-size, --store-list-gap, --store-list-group-gap, --store-list-muted |
.store-card |
--store-card-padding, --store-card-gap, --store-card-background, --store-card-radius, --store-card-muted, --store-card-photo-ratio |
Learn more
Section titled “Learn more”- Store page template and data: read the stores in Liquid, in your own sections.
- SEO: the pages’ addresses, redirects and structured data.
- Accessibility: what the blocks do, and what is left to the theme.