Skip to content

Tine Preset Support Pack

Diagnostic and troubleshooting reference for the Tine hardware preset — comparison table, specs-table mode, bulk pricing, and hardware metafields.


FAQ

Q: The comparison table columns are not sorting correctly.

A: The comparison table sort uses natural alphanumeric ordering. Hardware-specific values:

  • Metric thread (M8, M10, M12) sort correctly as strings (M10 > M8 alphabetically, but the natural sort treats them as M10, M12, M8 by number — verify with the diagnostic snippet)
  • For correct metric-thread sort, prefix with zero-padding: M08, M10, M12 instead of M8
  • Composite codes like A2-70 sort as strings; this is correct for standards-code columns

Q: The specs table mode is showing unsorted data in the wrong column.

A: In orientation: rows mode, the table renders spec name/value pairs from section blocks in the order they were added in the theme editor. The table is intentionally non-sortable in rows mode (sorting attribute names is not meaningful). To reorder rows, reorder the blocks in the theme editor.

Q: The bulk-pricing pill is showing but no discount is applied.

A: This is by design — the pill is a messaging display aid only. It does not apply a Shopify discount automatically. To apply actual discounts:

  1. Set up a quantity-break discount in Shopify (Discounts → Create discount → Amount off products → Minimum purchase quantity) or use a price-breaks app.
  2. Set the bulk_threshold in the Quick Order section to match your first discount tier quantity.
  3. The pill will show the savings percentage informationally; the actual discount is applied at checkout by Shopify's discount engine.

Q: Quick order section renders no products.

A: The Quick Order section requires a collection to be selected. This was F-TINE-QUICKORD-01 in the audit. Check:

  1. In the theme editor, navigate to Quick Order → Section settings. Is a collection selected?
  2. Does the selected collection have at least one published product?
  3. If the collection is empty, the section shows a guided empty state — check your collection rules or populate products.

Q: Cross-reference block shows "Part number unavailable".

A: The cross-reference block reads from the product description or manually entered block settings. Check the cross_reference_mpn and cross_reference_manufacturer fields are filled in the block settings in the theme editor.


Decision Tree: "Why is my comparison table not rendering?"

Symptom: Comparison table section appears but has no columns

  -> Are there blocks added to the comparison table section?
    -> In theme editor: Sections → Comparison table → check for column blocks
    -> No blocks: add at least 2 comparison-column blocks
    -> Yes: Continue

  -> Is orientation set correctly?
    -> 'columns' mode: expects multiple column blocks
    -> 'rows' mode: expects spec-row blocks
    -> Wrong block type for current orientation: switch to the matching block type

  -> Are column headings empty?
    -> Empty column heading will render but look invisible — check each block has a heading

  -> Is the niche_metafield_namespace required for this section?
    -> Comparison table does not read metafields directly — specs-table-row PDP blocks do
    -> If metafield data not showing on PDP: check metafield definitions in Shopify Admin

Validator Interpretation

"Lighthouse: Comparison table — interactive element does not have an accessible name"

The comparison table sort buttons are <button> elements wrapping <th> text. If Lighthouse flags this, the button may lack an aria-label. Check that each sortable column header's <button> has either visible text content or an aria-label that names the sort action. The theme ships aria-label="Sort by {column}" — verify this is present in the rendered HTML.

"axe: aria-sort value is not allowed"

The comparison table uses aria-sort="ascending" and aria-sort="descending" per ARIA spec. Valid values are none, ascending, descending, other. If axe flags this, a custom edit may have introduced an invalid value. Check niche-tine.js for the ariaSortUpdate() function.

"Theme check: quick-order section missing collection setting"

This is expected in a fresh install before the merchant selects a collection. Set the collection in the theme editor before deploying. If you see this in CI, configure a default collection in the section schema default: value for the collection picker setting.


Console Diagnostic Snippet

js
(function tineDiagnostic() {
  'use strict';
  const compTable = document.querySelector('.comparison-table');
  const r = {
    preset: document.querySelector('meta[name="uisce-preset"]')?.content ?? 'unknown',
    comparisonTable: {
      present: !!compTable,
      orientation: compTable?.dataset?.orientation ?? 'not found',
      columnCount: document.querySelectorAll('.comparison-table__column').length,
      rowCount: document.querySelectorAll('.comparison-table__row').length,
      sortButtonsPresent: document.querySelectorAll('[aria-sort]').length,
      lastAriaSortValue:
        document.querySelector('[aria-sort]:not([aria-sort="none"])')?.getAttribute('aria-sort') ?? 'none',
    },
    quickOrder: {
      present: !!document.querySelector('.quick-order'),
      productCount: document.querySelectorAll('.quick-order__item').length,
      bulkPillVisible: !!document.querySelector('.quick-order__bulk-pill:not([hidden])'),
    },
    nicheTineLoaded: !!document.querySelector('script[src*="niche-tine"]'),
    presetCSS: !!document.querySelector('link[href*="preset-tine"]'),
    nicheNamespace: document.querySelector('[data-niche-namespace]')?.dataset?.nicheNamespace ?? 'not found',
  };
  console.group('%cTine Diagnostic Report', 'color:#c0392b;font-weight:bold;font-size:14px');
  console.table(r.comparisonTable);
  console.log('Quick order:', r.quickOrder);
  console.log('niche-tine.js loaded:', r.nicheTineLoaded);
  console.log('Preset CSS:', r.presetCSS);
  console.groupEnd();
  return r;
})();

Accessibility Diagnostic

Comparison table sort accessibility check

js
(function checkComparisonTableA11y() {
  const table = document.querySelector('.comparison-table table');
  if (!table) {
    console.warn('No comparison table found');
    return;
  }
  const sortButtons = table.querySelectorAll('th [aria-sort]');
  const liveRegion = document.querySelector('[role="status"]');
  console.log({
    tablePresent: true,
    sortableColumns: sortButtons.length,
    ariaSortValues: [...sortButtons].map((b) => b.getAttribute('aria-sort')),
    liveRegionPresent: !!liveRegion,
    caption: table.querySelector('caption')?.textContent?.trim() ?? 'MISSING',
  });
})();

Expected: sortableColumns > 0 (if sort enabled), valid aria-sort values.

Quick order bulk pill check

js
const pills = document.querySelectorAll('.quick-order__bulk-pill');
const liveRegion = document.querySelector('[aria-live="polite"]');
console.log({
  pillCount: pills.length,
  visiblePills: [...pills].filter((p) => !p.hidden).length,
  liveRegionPresent: !!liveRegion,
  pillText: pills[0]?.textContent?.trim() ?? 'none visible',
});

Localization Notes

Comparison table locale keys

Sort direction announcements use sections.comparison_table.sort_ascending / sections.comparison_table.sort_descending locale keys. All 50 locales covered. The bulk-pricing pill label uses sections.quick_order.bulk_save_label — check this key is translated correctly for your non-EN markets.

Standards names are not localized

Technical standards names (ASTM F3125, ISO 898-1, DIN EN ISO 7045) are English-language designations recognized internationally. They should NOT be translated — use the official designation string as the spec value.


Curl Cheat-Sheet

bash
# Verify Product + additionalProperty JSON-LD on a hardware product
curl -s "https://your-store.myshopify.com/products/m8-hex-bolt" \
  | grep -A 15 '"additionalProperty"'

# Check niche_metafield_namespace on comparison table page
curl -s "https://your-store.myshopify.com/pages/compare" \
  | grep 'data-niche-namespace'

# Verify preset-tine.css is linked
curl -s "https://your-store.myshopify.com" \
  | grep 'preset-tine'

# Check aria-sort attribute is present on comparison table
curl -s "https://your-store.myshopify.com/pages/compare" \
  | grep 'aria-sort'

Localization Notes

Comparison table locale keys

Sort direction announcements use sections.comparison_table.sort_ascending and sections.comparison_table.sort_descending locale keys. Both are present in all 50 locales. The specs-table-row PDP block section strings are in blocks.specs_table_row.*.

Bulk-pricing pill locale key

The savings percentage shown in the bulk-pricing pill uses sections.quick_order.bulk_save_label with {percent} interpolation. Check this key is correctly translated for your EU/international markets (Irish/British English, German, French etc.).

Standards references are language-neutral

Technical standards designations (ASTM F3125, ISO 898-1, DIN EN ISO 7045, BS EN ISO) are not localized. Use them verbatim in spec values. If you need to explain a standard in a customer-facing description, add a richtext block in your product description.


Deployment Checklist

Before going live with the Tine preset:

  • [ ] settings.preset set to tine in Theme settings
  • [ ] Comparison table has at least 2 column or 2 row blocks populated
  • [ ] orientation setting is set to the correct mode for each table usage context
  • [ ] Quick order section has a collection selected
  • [ ] bulk_threshold and bulk_save_percent match your actual pricing tier
  • [ ] Product metafield definitions for uisce_tine.* created in Shopify Admin
  • [ ] At least 4 products have material and dimensions_mm metafields populated
  • [ ] Header menu includes product navigation (Compare, Products, Bulk Order)
  • [ ] JSON-LD validated: Product + additionalProperty appears on product pages
  • [ ] Comparison table aria-sort is verified: run diagnostic snippet above
  • [ ] preset-tine.css linked: confirmed via curl check above

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

Built for the Shopify Theme Store.