Skip to content

Uisce Preset Support Pack

Diagnostic and troubleshooting reference for the Uisce services preset — booking CTA, portfolio, service packages, and niche metafields.

The Booking section no longer ships a form. Shopify's Theme Store requirements forbid app-like functionality and name appointment scheduling outright, so the section presents your services and their fees and links out to your own booking tool. Anything below that refers to a booking POST endpoint has been rewritten around the Booking link setting.


FAQ

Q: There is no booking button on the page.

A: The section is a link-out CTA — Shopify's Theme Store forbids a theme shipping appointment scheduling, so the theme presents your services and fees and sends the customer to your own booking tool. The button renders only when Booking link has a value. Check:

  1. Is booking_url set in the Booking CTA section settings? An empty value renders no button at all, and the theme editor shows a reminder while it is blank.
  2. Does the URL work when you paste it into a browser? It is an ordinary link — whatever the URL returns is what the customer sees.
  3. If you want an enquiry form on the same page, add Shopify's own contact form section beneath the Booking section. That posts to your store, not to a third party.

Q: Where did the booking form go?

A: It was removed. Shopify's Theme Store requirements state that themes "must not incorporate app-like functionalities that require API access for full functionality" and name appointment scheduling as an example, and a theme must not post customer details to an endpoint pasted into a theme setting. Bookings now belong to your scheduling app; the theme links to it. If you were using Form action URL, put the same destination in Booking link — or, if that endpoint was a form handler rather than a booking page, point Booking link at your booking tool's public scheduling page instead.

Q: A service shows no fee, or the wrong one.

A: The deposit is read from each service block's deposit_amount setting — an absolute amount in your store currency (a number setting, not a percentage). Liquid formats it through the money filter and prints it beside the service name. Check:

  1. A row showing no fee at all means that block's deposit_amount is blank or 0. Set it on the block, or leave it blank deliberately for a service you do not take a deposit on.
  2. A wrong amount usually means the value was entered in minor units: deposit_amount is in whole store-currency units (enter 40 for a $40.00 deposit, not 4000).

A: No. The section collects nothing — there is no form, no inputs, and no JavaScript reading customer data, so there is nothing to consent to. The details a customer types go into your booking tool under that tool's own privacy terms; name that tool in your store's privacy policy under Settings → Policies → Privacy policy.

Q: Portfolio before/after images are not showing.

A: Older theme versions had a bug where the portfolio section emitted escaped HTML text instead of rendered images. This is resolved in current theme versions. Verify you are on a theme version that includes the 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 handle — case- and space-insensitive. "Residential", "residential", and " Residential " all collapse into a single tab, and the first spelling a merchant entered wins as the tab label. If you still see two tabs:

  1. The category names differ beyond case/spacing — check for typos ("Residental" vs "Residential") or singular/plural variants ("Kitchen" vs "Kitchens"), which are genuinely distinct categories.
  2. Edit the portfolio blocks to use one canonical spelling per category.

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. 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
  • disabled_on cannot help here — it restricts a section by template or section group, not by preset

Decision Tree: "Why can nobody book?"

Symptom: customers cannot start a booking from the Booking section

  -> Is booking_url set?
    -> No: Set it in Booking CTA section settings → Booking link.
       With no link the button does not render at all
    -> Yes: Continue

  -> Does the button appear on the live page?
    -> No: Confirm the section is on the published template, and that the theme editor
       is not showing the blank-link reminder
    -> Yes: Continue

  -> Does clicking it land on your booking tool?
    -> No: Paste the URL into a browser directly. A relative path must start with `/`;
       an external tool needs its full https:// URL
    -> Yes: Continue

  -> Are bookings arriving in your booking tool?
    -> No: That is the tool's own setup — availability, notifications, calendar sync.
       The theme's involvement ends at the link

Validator Interpretation

"Lighthouse: Booking CTA page has Accessibility score < 0.9"

The Booking section itself ships no form controls, so the usual cause is something added beside it: a custom HTML block with unlabelled inputs, or an app block. Check that any custom form elements use <label for="input-id"> pairings.

Check the booking button. It ships with localized text ("Request a booking"); if you see this error, check for a theme code edit that replaced the label with an icon or emptied the string.

"Theme check: booking_url setting value is empty"

This is expected in development before you configure your booking link. 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, or the section renders with no button.


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.body.className.match(/preset-([a-z]+)/)?.[1] ?? 'unknown',
    bookingCTA: {
      present: !!document.querySelector('niche-renderer[data-preset="uisce"]'),
      bookingLink: document.querySelector('.booking-cta__submit')?.getAttribute('href') ?? 'NOT SET',
      serviceRows: document.querySelectorAll('.booking-cta__service').length,
      collectsNothing: document.querySelectorAll('.booking-cta form, .booking-cta input').length === 0,
    },
    portfolio: {
      present: !!document.querySelector('.portfolio'),
      itemCount: document.querySelectorAll('.portfolio__card').length,
      filterButtons: document.querySelectorAll('[data-portfolio-filter]').length,
    },
    servicePackages: {
      present: !!document.querySelector('.service-packages'),
      tierCount: document.querySelectorAll('.service-packages__card').length,
    },
    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:

  • bookingLink: your configured Booking link (not NOT SET)
  • serviceRows: one per Service block you added
  • collectsNothing: true — the section ships no form and no inputs
  • presetCSS: true

Accessibility Diagnostic

Running the axe check against the booking page

bash
# Run the axe CLI (dev only — package name is @axe-core/cli)
npx @axe-core/cli "https://your-store.myshopify.com/pages/book-a-service"

Or use Chrome DevTools → Accessibility → Run axe. Expected: 0 critical violations.

Booking section aria requirements

For the Booking section to pass WCAG 2.1 AA:

  • Both regions carry a heading — the service list and the booking summary
  • The services render as a real <ul>/<li> list, so screen readers announce the count
  • The call to action is a real <a href> with text, not an icon and not a <div> with a click handler
  1. Navigate to your booking page and tab to the button — it must take focus and show a visible focus ring.
  2. Press Enter. The browser navigates to your Booking link.
  3. Middle-click (or long-press on mobile) and confirm "Open in new tab" is offered — that is the behaviour a real link gives you and a scripted button does not.

Localization Notes

Booking section copy

The section's own strings — the service heading, the deposit label, the summary heading, the button text, and the "no services" line — ship in all 50 locales. There is no consent copy: the section collects nothing, so there is nothing to consent to.

Service name localization

Service block names are merchant-entered text in theme settings — they are not localized via the locale system. If you operate a multilingual store, use the Shopify Translate & Adapt app to translate service names per locale.

Booking link is a URL, not a translated string. If your booking tool has a per-market scheduling page, translate the setting value with Translate & Adapt rather than duplicating the section.


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 the booking link is rendered on the booking page (0 means Booking link is blank)
curl -s "https://your-store.myshopify.com/pages/book-a-service" \
  | grep -c 'booking-cta__submit'

# 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.preset set to uisce in Theme settings
  • [ ] booking_url set in Booking CTA section settings (not blank)
  • [ ] Booking link opened and verified — it lands on your booking tool's own scheduling page
  • [ ] At least 2 service blocks in Booking CTA with service_name, service_handle, and deposit_amount set
  • [ ] Page book-a-service created and assigned page.book template
  • [ ] Portfolio section has at least 2 case-study blocks with images
  • [ ] Page portfolio created and assigned page.portfolio template
  • [ ] Service packages has at least 2 Service blocks with inclusions
  • [ ] Booking CTA button present, focusable, and lands on your booking tool (test above)
  • [ ] Service + Offer JSON-LD appears on service product pages (curl check)
  • [ ] Portfolio category filter shows one tab per category (deduplication is case- and space-insensitive; the first spelling entered wins as the tab label)
  • [ ] preset-uisce.css linked in page head
  • [ ] Header menu includes "Book a Service" and "Portfolio" links
  • [ ] Your privacy policy names the booking tool the link sends customers to
  • [ ] Each service row shows the correct fee (test in browser)

Support pack last updated: 2026-05-03 (Phase 06.10 closeout)

Built for the Shopify Theme Store.