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.

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

Announcement bar symptoms and checks
SymptomChecks
Bar appears on homepage but not PDPsSection in header-group.json? Registered in product.json order? Template-specific override?
Bar visible even when enabled = falseLiquid {% if %} missing? Caching issue? App override?
Dismissed bar reappears on refreshlocalStorage key correct? JS error before setItem? Incognito mode clearing storage?
New announcement hidden after old one dismissedlocalStorage 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.

  1. 01

    Create sections/announcement-bar.liquid

    Implement enabled toggle, message + optional link, dismissible optional.

  2. 02

    Register in header-group.json

    Place before main header; verify appears on homepage, PDP, collection, page.

  3. 03

    Visibility toggle pass

    enabled = false should hide bar; enabled = true should show it.

  4. 04

    Dismissible logic

    If dismissible, store dismissed state in localStorage keyed to section.id.

  5. 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.

Intermediate

Schema, settings, and related storewide UI.

Advanced

Delivery under merchandising pressure.

Editorial review

Reviewed by the HTML to Liquid Converter team

Dhruv Goyani, Shopify Developer at HTML to Liquid Converter

Dhruv Goyani

3 years web design + 3 years Shopify development experience

LinkedIn profile →
Nishad Kikani, Lead Shopify Developer at HTML to Liquid Converter

Nishad Kikani

2 years web design + 6 years Shopify development experience

LinkedIn profile →

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.