Phase 5:
App Data Simulation
Resilient rendering of app-like metafields across cards & PDP
WinSport Theme · app_data Namespace · Defensive Coding
Why App Data?
Shopify apps (reviews, badges, subscriptions) store data as metafields in their own namespaces. Themes must render this data across multiple surfaces — and survive gracefully when the app is uninstalled and its data disappears.
custom.*
Phase 4 — Store-owned
Metafields defined by the store (care_instructions, difficulty_rating, is_new_arrival). Controlled by the merchant.
app_data.*
Phase 5 — App-owned
Metafields that simulate an external app (badge text, certifications JSON). May disappear if app is uninstalled.
3 Metafield Keys
boolean
badge_enabled
Controls whether the badge is visible on product cards in collections
Surface: Collection cards
single_line_text
badge_text
Custom badge text — “Best Seller”, “Pro Pick”, “Award Winner”
Surface: Collection cards
Best Seller
json
extra_info
Structured object with warranty, origin, and certifications array
Surface: PDP
Warranty 2 years
Certifications CEISO 9001
Collection Badge
- Badge reads
app_data.badge_enabled — must be true
- Text from
app_data.badge_text — must be non-blank
- Positioned top-left overlay, separate from Shopify’s Sale/Sold Out badges
- Double-guard: enabled check first, then text check — either missing = no output
PDP Certifications
Collapsible Certifications Section
- Reads
app_data.extra_info as JSON
- Each key checked independently: warranty, origin, certifications[]
- Certifications rendered as pill tags via
for cert in app_info.certifications
- Collapsible accordion matching Phase 4 design pattern
Code Highlights
{%- assign app_badge_enabled = card_product.metafields.app_data.badge_enabled.value -%}
{%- if app_badge_enabled == true -%}
{%- assign app_badge_text = card_product.metafields.app_data.badge_text.value -%}
{%- if app_badge_text != blank -%}
<span class="card__app-badge">{{ app_badge_text | escape }}</span>
{%- endif -%}
{%- endif -%}
{%- assign app_info = product.metafields.app_data.extra_info.value -%}
{%- if app_info != blank -%}
{%- if app_info.warranty != blank -%} {%- endif -%}
{%- if app_info.origin != blank -%} {%- endif -%}
{%- if app_info.certifications != blank -%}
{%- for cert in app_info.certifications -%}
<span class="cert-tag">{{ cert | escape }}</span>
{%- endfor -%}
{%- endif -%}
{%- endif -%}
Key Takeaways
- Separate namespace —
app_data.* vs custom.* mirrors real app architecture
- Multi-surface rendering — same data flows to collection cards AND PDP
- JSON metafield — structured data parsed natively by Shopify, each key accessed independently
- Defensive at every level — namespace, key, and nested keys all checked before rendering
- App-uninstall safe — if all app_data metafields are removed, zero output, zero errors
WinSport Theme · Phase 5 Complete · Dawn v15.4.1 · Shopify 2.0