Production Shopify · Announcement banners
Run storewide announcement banners merchants can publish and retire
Flash sales, shipping deadlines, and holiday promos need announcement bars that ops teams can publish and retire without a deploy. This guide is about header/announcement section instances that are always present in the theme structure but controlled by merchant-facing visibility settings.
Production implementation guide · Updated 2026-08-03
Announcement bars are not homepage heroes—teach the scope
Homepage heroes live in index.json and appear only on the landing page. Announcement bars live in header-group.json or as a dedicated announcement section registered on multiple templates—they are storewide chrome, not campaign landing UI.
Hero sections
- Appears on homepage only
- Large imagery and campaign messaging
- Often multiple CTAs or rich content
- Controlled per template in theme editor
Announcement bars
- Appears storewide (header-group or multi-template registration)
- Concise text and optional link
- Often dismissible or time-bound
- Controlled by visibility toggle—not template removal
Register announcement bar in header-group.json for storewide presence
Themes using section groups (OS 2.0) place announcement bars in header-group.json alongside the main header. This makes the bar appear on every page without manual registration per template. The bar is always part of the theme structure—visibility is controlled by a section setting.
If the theme does not use section groups, the announcement section must be registered in the order array of each template JSON file (index, product, collection, page, etc.). This is more maintenance but achieves the same outcome.
header-group.json registration sketch
{
"name': 'Header",
"type': 'header",
"sections": {
"announcement": {
"type': 'announcement-bar",
"settings": {
"enabled": true,
"message': 'Free shipping on orders over $50",
"link': '/collections/sale"
}
},
"main-header": {
"type': 'header"
}
},
"order": ["announcement", "main-header"]
}Announcement before main header in stacking order. Visibility controlled by enabled setting.
Visibility toggle: publish and retire without removing the section
Announcement sections should have an enabled or visible boolean setting. When false, the section renders nothing—but remains in the theme structure. This lets merchants retire a promo by toggling a checkbox, then re-enable it later without rebuilding the section.
Avoid requiring merchants to delete and re-add the section. That workflow loses settings and disrupts header-group order.
Schema sketch — visibility toggle
{
"name': 'Announcement bar",
"settings": [
{
"type': 'checkbox",
"id': 'enabled",
"label': 'Show announcement bar",
"default": false
},
{
"type': 'text",
"id': 'message",
"label': 'Message",
"default': 'Welcome to our store"
},
{
"type': 'url",
"id': 'link",
"label': 'Link (optional)"
},
{
"type': 'checkbox",
"id': 'dismissible",
"label': 'Allow customers to dismiss",
"default": false
}
]
}enabled default false—bar hidden until merchant activates. dismissible gives shoppers a close option.
Message and optional link: keep it concise and accessible
Announcement bars are narrow. Message text should be 8–15 words max. If a link is provided, wrap the entire bar or render a visually distinct inline link. If no link, the message is static text—do not render an empty <a> tag.
For accessibility: if the bar is clickable, provide an accessible name that includes the message. If dismissible, the close button needs an aria-label.
Dismissible announcements: localStorage and privacy considerations
If dismissible is true, store the dismissed state in localStorage or a cookie. Key it to a unique announcement ID or message hash—not a generic 'announcement_dismissed'—so future promos can reappear after previous ones are closed.
Respect privacy: localStorage is acceptable for UI preferences. Do not track dismissal analytics without consent. GDPR/CCPA may require a consent banner before setting non-essential cookies.
Dismissible logic sketch
const announcementId = 'announcement-{{ section.id }}';
const dismissed = localStorage.getItem(announcementId);
if (!dismissed && section.settings.enabled) {
showAnnouncement();
}
closeButton.addEventListener('click', () => {
localStorage.setItem(announcementId, 'true');
hideAnnouncement();
});Keyed to section.id so different announcements are independent. Check enabled setting before rendering.
Production debugging for announcement bars
| Symptom | Checks |
|---|---|
| Bar appears on homepage but not PDPs | Section in header-group.json? Registered in product.json order? Template-specific override? |
| Bar visible even when enabled = false | Liquid {% if %} missing? Caching issue? App override? |
| Dismissed bar reappears on refresh | localStorage key correct? JS error before setItem? Incognito mode clearing storage? |
| New announcement hidden after old one dismissed | localStorage key generic (not unique per message)? Same section.id reused? |
Practice an announcement bar section by hand
Build this in header-group.json before using any generator. You should explain storewide scope, visibility toggles, and why this is not a homepage hero.
- 01
Create sections/announcement-bar.liquid
Implement enabled toggle, message + optional link, dismissible optional.
- 02
Register in header-group.json
Place before main header; verify appears on homepage, PDP, collection, page.
- 03
Visibility toggle pass
enabled = false should hide bar; enabled = true should show it.
- 04
Dismissible logic
If dismissible, store dismissed state in localStorage keyed to section.id.
- 05
Mobile and accessibility test
Message readable on narrow viewport; close button has aria-label; clickable bar has accessible name.
Use the converter after the announcement model is settled
Static banner HTML can be drafted faster in the converter once you know whether you need dismissible behavior, link wrapping, and header-group registration. The converter does not decide storewide chrome strategy for you.
Supporting draft acceleration — not a substitute for announcement bar design.
What to study next for announcement bar sections
Continue with adjacent skills. Hero sections are a different pattern—study when campaign landing UI is needed instead of storewide chrome.
Beginner
Liquid and section groups before storewide chrome.
- Shopify Liquid for beginners
Read conditional logic for visibility toggles.
- How Shopify sections work
Where section groups sit in theme structure.
Intermediate
Schema, settings, and related storewide UI.
- Shopify schema guide
Boolean toggles and URL pickers for announcements.
- Worked implementation examples
Real-world announcement bar code studies.
- Campaign hero sections
Different pattern: homepage landing UI—not storewide chrome.
Advanced
Delivery under merchandising pressure.
- Reusable section design patterns
When to build announcement vs hero vs modal.
- Dawn theme integration
Register announcement in header-group.json.
- Resources hub
Curriculum index.
Editorial review
Reviewed by the HTML to Liquid Converter team


Content is reviewed by the HTML to Liquid Converter Shopify development team before publication. Technical accuracy is validated against current Shopify Online Store 2.0 conventions and active client theme work.
Last updated:
Questions or corrections? Contact us.