Appearance
Footer support guide
Diagnostic and troubleshooting reference for the footer surface — auto-emitted policy row, GDPR newsletter, payment-icon aria-labels, block library, localization form, trust copy, follow-on-shop toggle, and the .footer__copyright color-mix migration. For merchant setup and configuration, see Footer guide.
FAQ
Q1: Why doesn't my newsletter show up in the footer?
Newsletter, social links, and payment icons are blocks — not section toggles. To show the newsletter: go to Theme editor → Sections → Footer → Add block → Newsletter. To show social links: Add block → Social links. To show payment icons: Add block → Payment icons.
Fix:
- Theme editor → Sections → Footer
- Click
Add block - Select
Newsletter - Save
If the block is already present but the newsletter still doesn't render:
- Run the console snippet below — inspect
newsletterin thefooterrow. Should betrueif acustomer-formelement is present inside.footer__newsletter-block. - Inspect
document.querySelector('.footer__newsletter-block customer-form')in DevTools — should return the form element. - Confirm
assets/customer-form.jsis loading: DevTools → Network → filtercustomer-form— should return 200.
Q2: How do I add a custom link to the footer policies?
Footer policies are auto-emitted from shop.shop_policies — you add them in Shopify admin, not the theme editor.
To add a policy:
- Shopify admin → Settings → Policies
- Click the policy type you want to add (Privacy policy, Refund policy, etc.)
- Write or paste your policy text
- Save — the footer renders the link automatically
Policies accepted: Privacy policy, Refund policy, Shipping policy, Terms of service, Subscription policy, Contact information.
You cannot add arbitrary custom links to the policy row. The policy row is reserved for Shopify-native policies. To add custom links, add a link_column block to the footer instead.
Q3: Newsletter submit shows "Please accept marketing cookies first"
This is the Customer Privacy API gate. The newsletter form checks Shopify.customerPrivacy.marketingAllowed() before submission. If the visitor has not accepted marketing cookies via the consent banner, the form is blocked.
Fix — for visitors:
The visitor must click "Accept" on the cookie consent banner before the newsletter form will submit.
Fix — for testing:
Call in DevTools before testing the form:
javascript
Shopify.customerPrivacy.setTrackingConsent({ marketing: true, analytics: true, preferences: true, sale_of_data: true });Then reload the page and try the newsletter form again.
If your store has no consent banner: You may have Shopify.customerPrivacy.marketingAllowed() always returning false. Verify you have not disabled the banner globally — the theme respects the Shopify consent API contract.
Q4: How do I customize per-preset footer block compositions?
Each preset has a different default block composition in config/settings_data.json. To override:
- Theme editor → Sections → Footer
- Rearrange, add, or remove blocks using the block controls
- Blocks in the theme editor override the
settings_data.jsondefaults for that preset
For programmatic changes: Edit config/settings_data.{preset}.json directly (or modify the block composition in the relevant preset's settings object in config/settings_data.json). Then push via scripts/push-presets.sh.
Q5: .footer__copyright text is barely visible
This was a known defect (carry-over from axe-core reports in Phases 06.4, 06.5, and 06.6). It was fixed in Phase 06.9 via the color-mix pattern:
css
color: color-mix(in srgb, var(--color-foreground) 70%, var(--color-background));If it still appears low-contrast after upgrading:
- Confirm you are running Uisce theme version ≥ 06.9 (check
assets/critical.cssheader comment for version) - Run the console snippet → inspect
footer.present— should betrue - DevTools → Elements → inspect
.footer__copyright→ Computed → color — should be the 70% foreground value - If the color is still the old value, perform a hard refresh (Ctrl+Shift+R) to clear the CDN-cached
footer.css
If the contrast fails on a specific color scheme, file an issue with the data-color-scheme value from the <body> element.
Console diagnostic snippet
Paste into Chrome DevTools console (F12 → Console tab) on any page of the live store. Reports footer state always; also reports 404, password, or gift-card state when on those surfaces.
js
(function () {
var path = location.pathname;
var report = { path: path, surfaces: {} };
// Footer always
var footer = document.querySelector('.footer');
report.surfaces.footer = {
present: !!footer,
policies: !!document.querySelector('.footer__policies'),
localization: !!document.querySelector('.footer__localization'),
newsletter: !!document.querySelector('.footer__newsletter-block customer-form'),
payment_icons_aria: Array.from(document.querySelectorAll('.footer__payment span[aria-label]')).length,
};
// 404
if (document.querySelector('.section-404')) {
report.surfaces['404'] = {
hero: !!document.querySelector('.section-404__hero svg'),
search: !!document.querySelector('.section-404__search'),
recently_viewed: !!document.querySelector('recently-viewed'),
noindex: document.querySelector('meta[name="robots"]')
? document.querySelector('meta[name="robots"]').content
: null,
};
}
// Password
if (document.querySelector('.password-page')) {
report.surfaces.password = {
logo: !!document.querySelector('.password-page__logo img'),
hero: !!document.querySelector('.password-page__hero svg'),
countdown: !!document.querySelector('count-down'),
newsletter: !!document.querySelector('.password-page__newsletter customer-form'),
social: !!document.querySelector('.password-page__social'),
localization: !!document.querySelector('.password-page__localization'),
};
}
// Gift-card
if (document.querySelector('.gift-card-page')) {
report.surfaces.gift_card = {
qr: !!document.querySelector('gift-card-qr canvas'),
copy: !!document.querySelector('gift-card-copy'),
balance: document.querySelector('.gift-card-page__balance')
? document.querySelector('.gift-card-page__balance').textContent.trim()
: null,
state:
['active', 'expired', 'depleted'].filter(function (s) {
return !!document.querySelector('.gift-card-page--state-' + s);
})[0] || 'active',
apple_wallet: !!document.querySelector('.gift-card-page__apple-wallet'),
google_wallet: !!document.querySelector('.gift-card-page__google-wallet'),
};
}
console.table(report.surfaces);
return report;
})();What to look for:
footer.present === true— footer DOM is present (should be on every page)footer.policies === true— policy row is rendering (requires published policies in Shopify admin)footer.localization === true— localization form is rendering (requiresshow_country_selectoror similar to be ON)footer.newsletter === true— newsletter block is present AND<customer-form>has upgradedfooter.payment_icons_aria— count of payment icons witharia-label(should be ≥ 1 if shop has payment types)
Curl cheat-sheet (D-67)
Topic 1 — Footer policy URL resolution
Verify your policy URLs resolve correctly:
bash
# Replace 'your-store.myshopify.com' with your store domain
curl -L -s -o /dev/null -w "%{http_code}" https://your-store.myshopify.com/policies/privacy-policy
# Expected: 200For a password-protected store, use the auth cookie approach:
bash
# 1. Get auth token (store uses preset name as password)
curl -s -c cookies.txt -b cookies.txt \
-X POST https://your-store.myshopify.com/password \
-d "form_type=storefront_password&password=uisce&utf8=%E2%9C%93"
# 2. Verify policy URL with auth cookie
curl -L -s -b cookies.txt -o /dev/null -w "%{http_code}" \
https://your-store.myshopify.com/policies/privacy-policy
# Expected: 200Topic 2 — 404 status code
bash
curl -I https://your-store.myshopify.com/not-a-real-path-12345
# Expected: HTTP/2 404Topic 3 — Password form action
bash
curl -I https://your-store.myshopify.com/password
# Expected: HTTP/2 200 (password page)Topic 4 — Gift-card noindex header
bash
curl -I https://your-store.myshopify.com/gift_cards/{code}
# Expected: x-robots-tag: noindex, nofollow (Shopify platform header)Topic 5 — Apple Wallet pass URL availability
bash
curl -I {apple_wallet_pass_url}
# Expected: HTTP/2 200 (if Apple integration enabled)Topic 6 — Google Wallet template substitution
Inspect page HTML to verify the template was substituted:
bash
curl -s https://your-store.myshopify.com/gift_cards/{code} | grep 'gift-card-page__google-wallet'
# Expected: <a href="https://...?code={code}&amount={amount}" ...>Topic 7 — Cache-control for footer asset freshness
bash
curl -I https://your-store.myshopify.com/cdn/shop/t/1/assets/footer.css
# Expected: cache-control: public, max-age=31536000 (Shopify CDN strong cache)
# After pushing theme changes, the asset URL includes a new version param — cache busts automatically