NORTH JS TECH
Skip to content
North Js Tech

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:

  1. 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.
  1. 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 and data-* 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 collection templates (e.g., main-collection.liquid or 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-handle
  • data-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.

  1. App Embed (global loader)snippets/rich-landing-bundle-app-embed.liquid
  2. Bundle Widget Sectionsections/rich-landing-bundle-widget.liquid
  3. Collection Bundle Sectionsections/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 

Last updated March 23, 2026

Let's talk