Theme Integration
Rich Landing Bundle: Theme App Extension Overview
Rich Landing Bundle integrates with Shopify Online Store 2.0 using a theme app extension composed of:
- App Embed Block
- Globally injects the bundle widget’s JavaScript and CSS.
- Ensures scripts/styles are loaded once and shared across all bundle instances.
- Typically enabled via Theme Editor → App embeds.
- Section Blocks (Bundle Widgets)
- Placed on specific templates/pages via Theme Editor → Add section/block.
- Each block instance represents a bundle widget with its own configuration (products, discounts, layout, etc.).
- Communicates with the globally loaded script from the app embed.
Bundle Widget Block
The Bundle Widget section/block:
- Renders a container element with data attributes (bundle ID, settings) that the app’s JavaScript uses to hydrate the widget.
- Uses optimized loading:
- Minimal HTML payload (skeleton markup only).
- Defers heavy logic to the app’s JS loaded via the app embed.
- Shows a skeleton UI while the JS initializes:
- Placeholder product tiles, prices, and buttons.
- Smooth transition to the fully interactive widget when data is ready.
Typical responsibilities:
- Output a root
<div>with a unique ID anddata-*attributes. - Optionally render server-side fallbacks (e.g., basic product info) for SEO or no-JS environments.
- Respect theme spacing, colors, and typography via CSS variables or theme settings.
Collection Bundle Block
The Collection Bundle Block is a specialized section/block intended for collection templates:
- Placed on
collectiontemplates (e.g.,main-collection.liquidor a dedicated bundle section). - Can:
- Show bundles related to the current collection.
- Use collection metafields or app-side configuration to determine which bundles to render.
- Uses the same global JS/CSS from the app embed, but passes collection-specific context:
data-collection-handledata-collection-id- or other identifiers used by the app backend.
This allows you to:
- Automatically surface relevant bundles on collection pages.
- Maintain a consistent widget UI across product, landing, and collection templates.
Liquid Code Examples
Below are representative Liquid snippets illustrating how a Theme App Extension for Rich Landing Bundle might be structured.
- App Embed (global loader) —
snippets/rich-landing-bundle-app-embed.liquid - Bundle Widget Section —
sections/rich-landing-bundle-widget.liquid - Collection Bundle Section —
sections/rich-landing-bundle-collection.liquid
The code blocks that follow show how these pieces work together in a real extension.
snippets/rich-landing-bundle-app-embed.liquid
liquid
1{% comment %}2App Embed: loads global JS/CSS for Rich Landing Bundle3File: snippets/rich-landing-bundle-app-embed.liquid4{% endcomment %}5 6{% if content_for_header contains 'shopify-features' %}7 <link8 rel="stylesheet"9 href="{{ 'rich-landing-bundle.css' | asset_url }}"10 >11 12 <script13 src="{{ 'rich-landing-bundle.js' | asset_url }}"14 defer15 data-rich-landing-bundle-app16 ></script>17 18 <script>19 window.RichLandingBundle = window.RichLandingBundle || {};20 window.RichLandingBundle.shop = {{ shop.permanent_domain | json }};21 window.RichLandingBundle.locale = {{ request.locale.iso_code | json }};22 </script>23{% endif %}24 sections/rich-landing-bundle-widget.liquid
liquid
1{% comment %}2Bundle Widget Section: renders a single bundle widget instance3File: sections/rich-landing-bundle-widget.liquid4{% endcomment %}5 6<section7 class="rich-landing-bundle-section"8 data-section-id="{{ section.id }}"9>10 <div11 id="rich-landing-bundle-{{ section.id }}"12 class="rich-landing-bundle-widget"13 data-bundle-id="{{ section.settings.bundle_id }}"14 data-layout="{{ section.settings.layout }}"15 data-show-title="{{ section.settings.show_title }}"16 >17 {%- comment -%}18 Skeleton UI: shown before JS hydration19 {%- endcomment -%}20 <div class="rich-landing-bundle-skeleton">21 <div class="rich-landing-bundle-skeleton__header"></div>22 <div class="rich-landing-bundle-skeleton__items">23 {% for i in (1..3) %}24 <div class="rich-landing-bundle-skeleton__item">25 <div class="rich-landing-bundle-skeleton__image"></div>26 <div class="rich-landing-bundle-skeleton__text"></div>27 </div>28 {% endfor %}29 </div>30 <div class="rich-landing-bundle-skeleton__footer"></div>31 </div>32 </div>33</section>34 35{% schema %}36{37 "name": "Rich Landing Bundle Widget",38 "target": "section",39 "settings": [40 {41 "type": "text",42 "id": "bundle_id",43 "label": "Bundle ID",44 "info": "Select or paste the bundle ID from the Rich Landing Bundle app."45 },46 {47 "type": "select",48 "id": "layout",49 "label": "Layout",50 "options": [51 { "value": "horizontal", "label": "Horizontal" },52 { "value": "vertical", "label": "Vertical" }53 ],54 "default": "horizontal"55 },56 {57 "type": "checkbox",58 "id": "show_title",59 "label": "Show bundle title",60 "default": true61 }62 ],63 "presets": [64 {65 "name": "Rich Landing Bundle Widget",66 "category": "Apps"67 }68 ]69}70{% endschema %}71 sections/rich-landing-bundle-collection.liquid
liquid
1{% comment %}2Collection Bundle Section: bundles on collection pages3File: sections/rich-landing-bundle-collection.liquid4{% endcomment %}5 6{% if template.name == 'collection' and collection %}7 <section8 class="rich-landing-bundle-collection-section"9 data-section-id="{{ section.id }}"10 >11 <div12 id="rich-landing-bundle-collection-{{ section.id }}"13 class="rich-landing-bundle-widget rich-landing-bundle-widget--collection"14 data-context="collection"15 data-collection-id="{{ collection.id }}"16 data-collection-handle="{{ collection.handle }}"17 data-bundle-source="{{ section.settings.bundle_source }}"18 >19 <div class="rich-landing-bundle-skeleton">20 <div class="rich-landing-bundle-skeleton__header"></div>21 <div class="rich-landing-bundle-skeleton__items">22 {% for i in (1..3) %}23 <div class="rich-landing-bundle-skeleton__item">24 <div class="rich-landing-bundle-skeleton__image"></div>25 <div class="rich-landing-bundle-skeleton__text"></div>26 </div>27 {% endfor %}28 </div>29 <div class="rich-landing-bundle-skeleton__footer"></div>30 </div>31 </div>32 </section>33{% endif %}34 35{% schema %}36{37 "name": "Rich Landing Collection Bundles",38 "target": "section",39 "settings": [40 {41 "type": "select",42 "id": "bundle_source",43 "label": "Bundle source",44 "options": [45 {46 "value": "collection_metafield",47 "label": "Use collection metafield configuration"48 },49 {50 "value": "app_rules",51 "label": "Use rules defined in the Rich Landing Bundle app"52 }53 ],54 "default": "app_rules"55 }56 ],57 "presets": [58 {59 "name": "Rich Landing Collection Bundles",60 "category": "Apps"61 }62 ]63}64{% endschema %}65