Skip to content

Neart Preset Support Pack

Diagnostic and troubleshooting reference for the Neart wellness/supplements preset — ingredient list, dosage guide, routine builder, how-to-use mode, and supplement metafields.

Includes a dedicated section on Theme Store medical-claim risk avoidance (see below).


FAQ

Q: The dosage calculator shows "NaN" or a wrong result.

A: The dosage calculator reads the Dosage per kg (mg) section setting (dosage_per_kg, default 5), passed to the script via the data-dosage-per-kg attribute. It never reads the uisce_neart.dosage_per_kg product metafield — that metafield feeds only the JSON-LD output and the PDP dosage/ingredient theme blocks. Check:

  1. Is Dosage display mode (dosage_mode) set to Body weight calculator? The default is Per serving, which shows static serving guidance and no calculator input.
  2. Is the Dosage per kg (mg) section setting a sensible number for the product?
  3. Is the calculator mode only used for eligible products (creatine, protein, caffeine — products where weight-based dosing is scientifically supported)?

Note: the Maximum weight (kg) setting controls only the above-range warning threshold — the weight input's HTML max stays fixed at 200 regardless. If the dosage figure in JSON-LD or a PDP block is wrong instead, check the uisce_neart.dosage_per_kg metafield — it must be number_decimal or number_integer type, not a text string like "0.5 mg/kg".

Q: The ingredient list section is empty.

A: The Ingredient List section renders exclusively from its ingredient blocks — it reads no metafields, and its uisce_neart namespace is hardcoded (the section has no namespace setting). Check:

  1. Are there ingredient blocks added in the theme editor? With zero blocks the section renders nothing on the live storefront (an empty-state hint appears only in the theme editor).

The uisce_neart.ingredients metafield drives a different component: the PDP ingredient-list theme block added on product pages. That metafield is a multi_line_text_field holding comma-separated ingredient names (CSV) — a JSON array pasted there renders as raw text.

Q: "Individual results may vary" disclaimer is not showing.

A: The disclaimer is configured via the Claims disclaimer textarea setting (claims_disclaimer) on the Routine Builder section only. The Dosage Guide has no disclaimer setting — it always renders a fixed healthcare caveat from the sections.dosage_guide.healthcare_caveat locale key. Check:

  1. In the theme editor, navigate to the Routine Builder section.
  2. Is the Claims disclaimer field populated? The theme ships a default: "Individual results may vary. Food supplements are not intended to diagnose, treat, cure or prevent any disease."
  3. An empty claims_disclaimer renders no disclaimer element — clearing the field removes the disclaimer entirely, so replace the default with jurisdiction-appropriate copy rather than deleting it.

Q: The pulse-rhythm animation is visible for customers who have requested reduced motion.

A: This is a critical accessibility issue. The animation is switched off by an @media (prefers-reduced-motion: reduce) { animation: none; } override in assets/preset-neart.css. If the animation shows for customers with prefers-reduced-motion: reduce:

  1. Check whether a custom CSS edit has removed or overridden the reduced-motion override.
  2. Check the browser's accessibility settings — some browsers expose this as "Reduce motion" in System Preferences (macOS) or Ease of Access (Windows).
  3. Test with DevTools: Chrome → Rendering → Emulate CSS media feature → prefers-reduced-motion: reduce. If animation still plays, the CSS override has been removed.

Q: The aria-live announcement for dosage calculation is not being read by a screen reader.

A: The dosage calculation result uses role="status" with aria-live="polite". Check:

  1. The live region element must exist in the DOM before the live update occurs (it cannot be inserted dynamically). Verify <div role="status" aria-live="polite"> is in the rendered HTML source.
  2. The result updates synchronously on every input event — there is no debounce or delay. Some screen readers coalesce rapid successive announcements from a polite live region; that is screen-reader behavior, not a theme defect.
  3. The aria-describedby on the weight input references the visually hidden formula description, not the live region (the live region has no id). Do not expect it to point at the result element.

Medical-Claim Risk Avoidance (Theme Store + Regulatory)

This section is mandatory reading for Neart merchants operating in EU/UK/US markets. The Neart preset surfaces dosage and ingredient information. Incorrect wording can:

  1. Cause your store to be flagged by the Shopify Theme Store review team
  2. Trigger MHRA (UK), HPRA (IE), or FDA enforcement action on your store's marketing copy
  3. Cause your Google Shopping feed to be suspended for medical claims

What wording to NOT use

Medical/therapeutic claims (strictly prohibited for food supplements):

Do NOT useWhy
"Treats/cures/prevents [condition]"Medicinal claim — requires product licence in EU/UK
"Clinically proven to reduce [symptom]"Therapeutic claim — requires evidence dossier
"Doctor-recommended dose for [condition]"Medical authority claim — triggers MHRA borderline review
"Take X mg for [disease/disorder]"Disease claim — prohibited under EU Health Claims Regulation
"MedicalRecommendation" in your visible copySchema.org type — triggers structured data scrutiny
"Prescription-strength formula"Implies medicinal classification

Personalised medical framing (risky for dosage guide):

RiskySafer alternative
"Recommended dose for your weight""Suggested serving based on typical adult ranges"
"Consult your doctor before changing your dosage""Talk to a healthcare professional before changing dosage" (the theme's built-in caveat wording)
"Your personalised dosage: X mg""Based on {N}kg, typical serving: {serving_size}"
"This product has been tested for safety""Produced in a GMP-certified facility"

What wording is SAFE

Per the EU Health Claims Regulation (EC 1924/2006) and DSHEA (US), the following are permitted for authorised nutrient function claims:

  • "Magnesium contributes to normal muscle function" (EU authorised claim for Magnesium)
  • "Vitamin D contributes to the maintenance of normal bones" (EU authorised)
  • "Zinc contributes to normal immune function" (EU authorised)
  • "As part of a balanced diet and healthy lifestyle" (general purpose disclaimer)
  • "Contains X mg of Magnesium per serving" (factual label statement)
  • "Serving size: 2 capsules (400 mg)" (label directions)
  • "Store in a cool, dry place. Keep out of reach of children." (storage/safety statement)

Full list of EU authorised health claims: ec.europa.eu/food/safety/labelling_nutrition/ claims/register/public/?event=register.home

How to override copy in admin if jurisdiction differs

The dosage guide's fixed safety copy comes from locale keys that can be customized per locale in the Shopify Translation app:

Locale keyPurposeWhere it renders
sections.dosage_guide.healthcare_caveatAlways-rendered caveat closing the dosage panelBoth dosage display modes
sections.dosage_guide.warning_above_rangeNon-clinical warning when weight exceeds the thresholdBody weight calculator mode

To override via the Translation app:

  1. Shopify Admin → Apps → Translations / Translate & Adapt → select your language.
  2. Find the section key (e.g., sections.dosage_guide.healthcare_caveat).
  3. Enter your jurisdiction-specific text.

The routine builder's disclaimer is not a locale key — edit its Claims disclaimer setting directly in the theme editor (translatable per locale as theme-editor content).

enable_structured_product_usage_data setting

This checkbox on the Dosage Guide and Ingredient List sections gates MedicalRecommendation structured data emission. Leave it false unless:

  • Your products are classified as medical devices (Class I or above) under EU MDR 2017/745
  • You have a written opinion from a regulatory solicitor confirming the classification
  • You are operating as a prescription-dispensing pharmacy (Shopify Health & Medical channel)

For the overwhelming majority of food-supplement merchants: leave it false. The default Product + additionalProperty JSON-LD communicates your dosage and timing data to Google without medical-classification risk (ingredient data is not included in additionalProperty).


Decision Tree: "Why isn't my dosage guide showing data?"

Symptom: Dosage guide renders but shows placeholder text

  -> Is serving_size_text set in the section settings?
    -> No: set it (e.g., "200mg — Take 1 capsule daily with food"); when blank, nothing renders
       on the live storefront (the placeholder appears only in the theme editor)
    -> Yes: Continue

  -> Is dosage_mode set to "Body weight calculator"?
    -> Check section settings; the default is "Per serving" (no calculator input)
    -> If it should show a calculator: switch the mode for eligible products only

  -> Is the weight input type="number" with inputmode="numeric"?
    -> Run the diagnostic snippet below; check 'weightInputPresent'
    -> If missing: theme file may be stale; push latest via push-presets.sh

  -> Is the Routine Builder's claims_disclaimer empty?
    -> Empty disclaimer = no disclaimer element in HTML; add text in section settings
       (the dosage guide's healthcare caveat always renders regardless)
    -> Not a functional bug, but a compliance requirement

Validator Interpretation

"Lighthouse: Dosage guide — form element does not have accessible name"

The weight calculator input must have an accessible label. The theme renders a fixed <label for="dosage-weight-{section id}"> element whose text comes from the sections.dosage_guide.weight_label locale key ("Body weight") — there is no label setting to populate and the label cannot be blank. If Lighthouse flags the input, a custom code edit has removed or detached the label; restore sections/dosage-guide.liquid.

"axe: aria-live region is missing role or aria-live attribute"

The dosage result <div role="status" aria-live="polite"> must exist before the first calculation. If axe flags the live region, verify it is present in the page HTML before JavaScript runs (it should be server-rendered by the Liquid template, not injected by JS).

"Theme Store review flagged 'medical recommendation' language in section"

If the Theme Store review team flags medical-claim wording:

  1. Review all section heading, subheading, and block content settings for prohibited phrases (see table above).
  2. Check that enable_structured_product_usage_data is false on the Dosage Guide and Ingredient List sections (there is no separate JSON-LD section in the editor).
  3. Review the claims_disclaimer text to ensure it uses non-advisory language (not "talk to your doctor").
  4. Check blog post content for therapeutic claims — these are not in theme code but are in merchant content and still count for review purposes.

Console Diagnostic Snippet

js
(function neartDiagnostic() {
  'use strict';
  const dosageGuide = document.querySelector('.dosage-guide');
  const weightInput = document.querySelector('input[data-dosage-input]');
  const liveRegion = document.querySelector('[role="status"][aria-live]');
  const r = {
    preset: document.body.className.match(/preset-([a-z]+)/)?.[1] ?? 'unknown',
    dosageGuide: {
      present: !!dosageGuide,
      servingSize: document.querySelector('.dosage-guide__serving-text')?.textContent?.trim() ?? 'not found',
      weightInputPresent: !!weightInput,
      weightInputType: weightInput?.type ?? 'N/A',
      weightInputMode: weightInput?.inputMode ?? 'N/A',
      liveRegionPresent: !!liveRegion,
      liveRegionRole: liveRegion?.getAttribute('role') ?? 'missing',
      caveatPresent: !!document.querySelector('.dosage-guide__caveat'),
    },
    ingredientList: {
      present: !!document.querySelector('.ingredient-list'),
      cardCount: document.querySelectorAll('.ingredient-list__card').length,
      allergenChips: document.querySelectorAll('.ingredient-list__allergen[role="img"]').length,
    },
    routineBuilder: {
      present: !!document.querySelector('.routine-builder'),
      stepCount: document.querySelectorAll('.routine-builder__step').length,
      disclaimerPresent: !!document.querySelector('.routine-builder__disclaimer'),
    },
    pulseAnimation: {
      presetCSS: !!document.querySelector('link[href*="preset-neart"]'),
      reducedMotionRespected: window.matchMedia('(prefers-reduced-motion: reduce)').matches
        ? 'reduce — animation should be static'
        : 'no preference — animation may play',
    },
    nicheNamespace: document.querySelector('[data-niche-namespace]')?.dataset?.nicheNamespace ?? 'not found',
    medicalJsonLD: Array.from(document.querySelectorAll('script[type="application/ld+json"]')).some((s) =>
      s.textContent?.includes('"MedicalRecommendation"'),
    ),
  };
  console.group('%cNeart Diagnostic Report', 'color:#8e44ad;font-weight:bold;font-size:14px');
  console.table(r.dosageGuide);
  console.log('Ingredient list:', r.ingredientList);
  console.log('Routine builder:', r.routineBuilder);
  console.log('Pulse animation / reduced motion:', r.pulseAnimation);
  if (r.medicalJsonLD) {
    console.warn(
      '⚠ MedicalRecommendation JSON-LD is present — verify enable_structured_product_usage_data is intentional',
    );
  }
  console.groupEnd();
  return r;
})();

Key checks:

  • caveatPresent: true — the dosage guide's healthcare caveat always renders with the section
  • disclaimerPresent: true — ensure the routine builder's claims disclaimer is configured
  • liveRegionPresent: true — required for dosage calculation accessibility (body weight calculator mode only)
  • medicalJsonLD: false — confirm unless explicitly enabled

Curl Cheat-Sheet

bash
# Verify Product + additionalProperty JSON-LD on a supplement product
curl -s "https://your-store.myshopify.com/products/magnesium-400mg" \
  | grep -A 10 '"additionalProperty"'

# Check that MedicalRecommendation JSON-LD is NOT present on default products
curl -s "https://your-store.myshopify.com/products/magnesium-400mg" \
  | grep '"MedicalRecommendation"'
# Expected: no output (or only in a comment/source reference)

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

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

# Verify ingredient list page exists
curl -o /dev/null -s -w "%{http_code}\n" \
  "https://your-store.myshopify.com/pages/ingredients"
# Expected: 200

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

Built for the Shopify Theme Store.