Appearance
Uisce Preset Support Pack
Diagnostic and troubleshooting reference for the Uisce services preset — booking CTA, portfolio, service packages, and niche metafields.
FAQ
Q: The booking form submits but nothing happens.
A: The form requires a valid form_action_url endpoint. Check:
- Is
form_action_urlset in the Booking CTA section settings? An empty URL causes the form to POST back to the current page with no handler. - Is your endpoint returning HTTP 200? Check the browser Network tab after form submission.
- Is the endpoint CORS-enabled for your store domain? Netlify Forms and Formspree require the form
actionattribute to match the registered endpoint domain.
Q: The deposit amount shows as "NaN%" or a wrong number.
A: The deposit percentage is read from the selected service block's deposit_percent value (a number 0–100). Check:
- In the theme editor, each service block in the Booking CTA section has
deposit_percentset to a numeric value (not blank, not text like "15%"). niche-uisce.jsreadsdata-depositfrom the selected<option>element in the service select. If the option'sdata-depositattribute is missing or empty, the JS falls back to 0.
Q: The consent checkbox appears but the submit button stays disabled even when checked.
A: Two possible causes:
window.Shopify.customerPrivacyis not loaded — this happens on development stores with the consent banner disabled. Check the browser console forcustomerPrivacy is not defined. On production stores, the Shopify Customer Privacy API loads automatically; on development stores with?preview_theme_id=you may need to preview in incognito to trigger it.- Your consent banner (if using a third-party cookie app) is blocking
analyticsProcessingAllowed(). Check that your cookie banner correctly calls Shopify's Customer Privacy APIsetTrackingConsent().
Q: Portfolio before/after images are not showing.
A: This was F-PORTFOLIO-IMG-01 in Phase 06.10 — the portfolio section was emitting escaped HTML text instead of rendered images. Fix shipped in Plan 06.10-01. Verify you are on a theme version that includes this fix by checking the assets/portfolio.css file date in the theme files list.
Q: Category filter in the portfolio section shows duplicate categories.
A: The portfolio filter deduplicates categories by exact string equality. Check for:
- Inconsistent capitalization: "residential" vs "Residential" are treated as different.
- Leading/trailing spaces in the
categoryblock setting. - Edit all portfolio blocks to use consistent category names.
Q: Service packages section is showing on non-Uisce preset pages.
A: The service-packages section has no case settings.preset guard in the Liquid template (F-UIS-SERVIC-08 from the audit). If you are using a shared theme across multiple presets, the section may appear on non-Uisce preset pages visually. To hide it on non-Uisce pages:
- Either add the section only to Uisce-specific page templates
- Or use the
disabled_onsection schema to restrict it
Decision Tree: "Why is my booking form not working?"
Symptom: Booking form does not submit
-> Is form_action_url set?
-> No: Set it in Booking CTA section settings → Form action URL
-> Yes: Continue
-> Does the browser Network tab show a request after clicking Submit?
-> No: Check if consent checkbox is checked; check JS console for errors
-> Yes: Continue
-> What HTTP status does the endpoint return?
-> 200: Check form_success_heading is set; look for a white screen (success state rendered)
-> 4xx/5xx: Check endpoint is correctly configured; check CORS origin whitelist
-> Is the error "customerPrivacy is not defined"?
-> Yes: Shopify Customer Privacy API not loaded — test on production preview, not dev URL
-> No: Check niche-uisce.js version; may be serving pre-Phase-06.10-01 cached fileValidator Interpretation
"Lighthouse: Booking CTA page has Accessibility score < 0.9"
Most common cause on Uisce: form input labels not associated with inputs (missing for/id pairs). The theme ships correct associations. If you have added custom HTML blocks near the form, check that any custom form elements use <label for="input-id"> pairings.
"axe: Form element doesn't have an accessible name"
Check whether the booking form's service <select> element has a <label> associated via for/id. This is shipped correctly in the theme; if you see this error, check for a theme code edit that may have broken the label association.
"Theme check: form_action_url setting value is empty"
This is expected in development before you configure your form endpoint. It is not a theme-check offense — it is a schema type: url setting with an empty default. Set the value in the theme editor before deploying to production.
Console Diagnostic Snippet
Paste into DevTools Console on any Uisce page to get a structured diagnostic report:
js
(function uisceDiagnostic() {
'use strict';
const r = {
preset: document.querySelector('meta[name="uisce-preset"]')?.content ?? 'unknown',
bookingCTA: {
present: !!document.querySelector('niche-renderer[data-preset="uisce"]'),
formAction: document.querySelector('form[data-booking-form]')?.action ?? 'NOT SET',
consentChecked: document.querySelector('input[name="booking_consent"]')?.checked ?? false,
customerPrivacyLoaded: typeof window?.Shopify?.customerPrivacy !== 'undefined',
analyticsAllowed: (function () {
try {
return window.Shopify.customerPrivacy.analyticsProcessingAllowed();
} catch {
return 'API_NOT_LOADED';
}
})(),
},
portfolio: {
present: !!document.querySelector('.portfolio'),
itemCount: document.querySelectorAll('.portfolio__item').length,
filterButtons: document.querySelectorAll('[data-portfolio-filter]').length,
},
servicePackages: {
present: !!document.querySelector('.service-packages'),
tierCount: document.querySelectorAll('.service-packages__tier').length,
},
nicheMetafieldNamespace: document.querySelector('[data-niche-namespace]')?.dataset?.nicheNamespace ?? 'not found',
presetCSS: !!document.querySelector('link[href*="preset-uisce"]'),
};
console.group('%cUisce Diagnostic Report', 'color:#006989;font-weight:bold;font-size:14px');
console.table(r.bookingCTA);
console.log('Portfolio:', r.portfolio);
console.log('Service Packages:', r.servicePackages);
console.log('Preset CSS loaded:', r.presetCSS);
console.groupEnd();
return r;
})();Expected output when working correctly:
formAction: your configured endpoint URL (not empty, not the current page)consentChecked:falseinitially,trueafter customer checks the boxcustomerPrivacyLoaded:trueon production storespresetCSS:true
Accessibility Diagnostic
Running the axe check against the booking page
bash
# Install axe-core CLI (dev only)
npx axe-core-cli@latest "https://your-store.myshopify.com/pages/book-a-service" \
--exit 0 --reporter json 2>&1 | head -100Or use Chrome DevTools → Accessibility → Run axe. Expected: 0 critical violations.
Booking form aria requirements
For the booking form to pass WCAG 2.1 AA:
- Every
<input>,<select>,<textarea>must have an associated<label>(viafor/id) - The consent checkbox must have a visible label — not just an aria-label
- The submit button must have accessible text (not just an icon)
- Error messages must be associated with their fields via
aria-describedby - The live error summary must use
role="alert"(assertive) for immediate announcement
Testing the consent flow
- In Chrome, open an incognito window and navigate to your booking page.
- Accept the cookie banner when it appears (or simulate
analyticsProcessingAllowed: truevia the console:window.Shopify.customerPrivacy.setTrackingConsent({analytics: true}, () => {})). - Verify the submit button becomes enabled after checking the consent checkbox.
- Submit the form and verify the success state appears.
Localization Notes
Consent text localization
The GDPR consent checkbox copy is controlled by sections.booking_cta.consent_text locale key. The theme ships this key in all 50 locales. If you need jurisdiction-specific consent language (e.g., PIPEDA for Canada, LGPD for Brazil), override the locale key via the Shopify Translation app for the relevant locale.
Service name localization
Service block names in the booking form's select element are merchant-entered text in theme settings — they are not localized via the locale system. If you operate a multilingual store, create separate theme presets or use the translation app to translate service names per locale.
Curl Cheat-Sheet
bash
# Verify Service + Offer JSON-LD on a service product
curl -s "https://your-store.myshopify.com/products/standard-clean" \
| grep -o '"@type":"Service"[^<]*' | head -5
# Check niche_metafield_namespace is rendered on the booking page
curl -s "https://your-store.myshopify.com/pages/book-a-service" \
| grep 'data-niche-namespace'
# Verify preset-uisce.css is linked in the page head
curl -s "https://your-store.myshopify.com" \
| grep 'preset-uisce'
# Check booking-cta section is present on the book page
curl -s "https://your-store.myshopify.com/pages/book-a-service" \
| grep -c 'booking-cta'Deployment Checklist
Before going live with the Uisce preset:
- [ ]
settings.presetset touiscein Theme settings - [ ]
form_action_urlset in Booking CTA section settings (not blank) - [ ]
form_success_headingandform_success_bodyconfigured - [ ] At least 2 service blocks in Booking CTA with
deposit_percentandservice_priceset - [ ] Page
book-a-servicecreated and assignedpage.book.uiscetemplate - [ ] Portfolio section has at least 2 case-study blocks with images
- [ ] Page
portfoliocreated and assignedpage.portfolio.uiscetemplate - [ ] Service packages has at least 2 tier blocks with inclusions
- [ ] Booking CTA consent checkbox present and functional (test consent flow above)
- [ ] Service + Offer JSON-LD appears on service product pages (curl check)
- [ ] Portfolio category filter works with consistent category names (no case mismatch)
- [ ]
preset-uisce.csslinked in page head - [ ] Header menu includes "Book a Service" and "Portfolio" links
- [ ] GDPR consent text is present and uses booking-specific purpose language
- [ ] Deposit calculation shows correct values for each service (test in browser)
Support pack last updated: 2026-05-03 (Phase 06.10 closeout)