RM Wishlist Plus — Merchant Setup & Theme Code Snippets Guide
1. Merchant Quick Setup (No Code Required)
RM Wishlist Plus uses Shopify's native Online Store 2.0 App Embeds and Blocks. You can complete 95% of setups directly through the visual Shopify Theme Customizer without writing a single line of code.
Step 1: Enable App Embed in Theme Editor (Required)
Required for all storesThe App Embed loads the wishlist core script and styles. It must be enabled for all features to work.
- In your Shopify Admin, go to Online Store → Themes.
- On your live theme, click Customize.
- On the left vertical toolbar, click the App Embeds icon (puzzle piece icon).
- Find Wishlist Config & Styles (or RM Wishlist Plus Core) and switch it to ON.
- Configure your brand colors: Empty Heart Color (outline for unsaved items, e.g. #111111 or #000000), Filled Heart Color (active color when saved, e.g. #ff0000 or #e11d48), and Button Labels ("Add to Wishlist" and "Remove").
- Click Save in the top-right corner.
Step 2: Add Wishlist Button to Product Pages
Zero Code BlockPlace the heart wishlist button directly on your product detail pages:
- In the Theme Customizer top dropdown, select Products → Default product.
- In the left panel, find the Product information section.
- Click Add block.
- Under the Apps tab, select Wishlist Button.
- Drag and reposition the block (we recommend placing it directly beneath the Buy buttons / "Add to Cart" block).
- Customize settings in the right sidebar: Change button text (or leave blank to show icon only), adjust border width, border color, and corner radius to match your store buttons, and check Full Width if desired.
- Click Save.
Step 3: Create Dedicated Wishlist Page (/pages/wishlist)
Dedicated URL: /pages/wishlistGive shoppers a clean, dedicated page to view, share, and purchase their saved items:
- In Shopify Admin, go to Online Store → Pages and click Add page.
- In the title field, type: Wishlist.
- Verify that the URL handle ends with /pages/wishlist.
- Leave the page content box empty and click Save.
- Go back to Online Store → Themes → Customize.
- From the top dropdown menu, choose Pages → Wishlist.
- In the template sections list, click Add section (or Add block).
- Select Wishlist Page from the Apps tab.
- Customize settings: Heading & Subheading (e.g., "My Wishlist" and "Your favorite items, saved in one place."), Grid Layout (card width e.g. 240px and spacing 30px), Variant Selector (Dropdown or Popup Overlay), and Login Requirement.
- Click Save.
Step 4: Enable Floating Hearts on Collection Grids
Universal Theme SupportDisplay floating heart icons on every product card across your collection, catalog, and search pages:
- In Theme Customizer, click the App Embeds tab (left sidebar).
- Click Wishlist Config & Styles to expand its settings.
- Scroll down to Auto-Injection (Product Cards).
- Verify the Product Card CSS Selector matches your theme (For Dawn / Sense / Craft / Refresh / Studio: .product-card__info or .card-wrapper; For Prestige / Impulse / Focal: .grid-product__content or .product-item; For other themes: Inspect your product card in browser DevTools to find its CSS container class).
- Click Save. Floating hearts will now appear on all catalog cards.
2. All Theme Code Snippets (Ready to Copy & Paste)
If you want custom placements, header badges, or cart "Save for Later" functionality, use the tested snippets below.
Snippet 1: Cart "Save for Later" Button (Theme Snippet Method)
Allows shoppers to move items from the cart directly to their wishlist. Split into two clean steps:
Step 1: Create the snippet file
- In Shopify Admin, go to Online Store → Themes → Edit code (under the three dots ...).
- In the sidebar under Snippets, click Add a new snippet.
- Name the snippet: rm-save-for-later.
- Paste the following code and click Save:
{% comment %}
RM Wishlist Plus — Cart "Save for Later" Button
Usage: {% render 'rm-save-for-later', item: item, index: forloop.index %}
{% endcomment %}
<button
type="button"
data-rm-cart-save-for-later
data-product-handle="{{ item.product.handle }}"
data-line="{{ index }}"
data-key="{{ item.key }}"
aria-label="Save {{ item.product.title | escape }} for later"
class="rm-save-for-later-btn"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; flex-shrink: 0;">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>
<span>Save for later</span>
</button>Step 2: Render inside your theme's cart template
- Open your cart line-item template (sections/main-cart-items.liquid or snippets/cart-drawer.liquid).
- Find the cart line items loop ({% for item in cart.items %}), and add:
{% render 'rm-save-for-later', item: item, index: forloop.index %}Snippet 2: Cart "Save for Later" Direct Inline HTML Button
Paste this code directly inside your cart line items loop (next to the theme's remove / quantity buttons):
<!-- RM Wishlist Plus: Direct Cart Save for Later Button -->
<button
type="button"
data-rm-cart-save-for-later
data-product-handle="{{ item.product.handle }}"
data-line="{{ forloop.index }}"
data-key="{{ item.key }}"
aria-label="Save {{ item.product.title | escape }} for later"
class="rm-save-for-later-btn"
style="
background: transparent;
border: none;
color: #4b5563;
font-size: 13px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 0;
text-decoration: underline;
text-underline-offset: 3px;
"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>
<span>Save for later</span>
</button>Snippet 3: Header Navigation Wishlist Icon & Live Count Bubble
Place this snippet in your store's header (typically in sections/header.liquid or snippets/header-actions.liquid near the Account or Cart icons):
<!-- RM Wishlist Plus — Header Wishlist Link & Live Counter -->
<a href="/pages/wishlist" class="rm-header-wishlist-link" aria-label="View saved items">
<span class="rm-header-wishlist-icon" aria-hidden="true">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>
</span>
<span class="rm-header-wishlist-text visually-hidden">Wishlist</span>
<span data-rm-wishlist-count class="rm-header-wishlist-badge" style="display: none;">0</span>
</a>
<style>
.rm-header-wishlist-link {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
color: inherit;
text-decoration: none;
padding: 8px;
transition: transform 0.15s ease;
}
.rm-header-wishlist-link:hover {
transform: scale(1.08);
}
.rm-header-wishlist-badge {
position: absolute;
top: 2px;
right: 0;
background: #e11d48;
color: #ffffff;
font-size: 11px;
font-weight: 700;
border-radius: 999px;
min-width: 18px;
height: 18px;
padding: 0 4px;
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 1;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
</style>Snippet 5: Manual Floating Heart for Custom Collection Cards
If you prefer manual placement over auto-injection on product cards (e.g. inside snippets/card-product.liquid):
<!-- RM Wishlist Plus: Manual Floating Card Heart -->
<button
type="button"
class="rm-wl-card-float"
data-rm-wishlist-toggle
data-product-handle="{{ card_product.handle | default: product.handle }}"
data-product-id="{{ card_product.id | default: product.id }}"
aria-label="Save to wishlist"
aria-pressed="false"
>
<svg class="rm-wl-icon-empty" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#111111" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>
</button>Snippet 6: Custom Wishlist Card Template (Metafields & Logic)
For merchants customizing how product cards render on /pages/wishlist with metafields, sale badges, and low-stock indicators:
<!-- Custom Wishlist Card Layout -->
<div class="rm-wl-custom-card" style="display: flex; flex-direction: column; gap: 8px; height: 100%; position: relative;">
<!-- Image -->
<a href="#" data-wl-link class="rm-wl-custom-image" style="display: block; position: relative; padding-bottom: 125%; background: #f3f4f6; overflow: hidden; border-radius: 8px;">
<img data-wl-image src="" alt="" width="300" height="300" loading="lazy" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;" />
</a>
<!-- Vendor & Badges -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 4px;">
<span data-wl-vendor style="font-size: 11px; text-transform: uppercase; color: #6b7280; font-weight: 600;"></span>
{% if on_sale %}
<span style="background: #fef2f2; color: #dc2626; font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px;">SALE</span>
{% endif %}
{% if inventory < 5 %}
<span style="background: #fffbeb; color: #b45309; font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px;">LOW STOCK</span>
{% endif %}
</div>
<!-- Title -->
<a href="#" data-wl-link data-wl-title style="font-size: 14px; font-weight: 600; text-decoration: none; color: #111827; line-height: 1.3;"></a>
<!-- Price -->
<div style="margin-top: 2px;">
<span data-wl-price style="font-weight: 700; font-size: 15px; color: #111827;"></span>
<span data-wl-compare-price style="text-decoration: line-through; color: #9ca3af; margin-left: 6px; font-size: 13px;"></span>
</div>
<!-- Custom Metafield (e.g. Fabric or Material) -->
<div data-wl-metafield="custom.material" style="font-size: 12px; color: #4b5563;"></div>
<!-- Actions -->
<div style="margin-top: auto; padding-top: 10px; display: flex; flex-direction: column; gap: 6px;">
<button type="button" data-wl-cart-btn data-rm-wishlist-move-to-cart style="width: 100%; background: #111827; color: #ffffff; border: none; padding: 10px 14px; cursor: pointer; text-align: center; border-radius: 6px; font-weight: 600; font-size: 13px;">
Move to Cart
</button>
<button type="button" data-wl-remove-btn data-rm-wishlist-remove style="background: transparent; border: none; color: #9ca3af; font-size: 12px; cursor: pointer; padding: 4px 0; text-align: center;">
Remove
</button>
</div>
</div>Snippet 7: JavaScript Re-scan Hook for AJAX Modals & Filters
If your theme uses custom AJAX collection filters or opens quick-view modals that dynamically inject product HTML, trigger this lightweight re-scan function after your theme renders:
// Trigger RM Wishlist Plus to attach buttons onto freshly injected HTML:
if (window.RmWishlistInit) {
window.RmWishlistInit();
}
// Example with Quick-View Modal:
document.addEventListener('quickview:opened', () => {
if (typeof window.RmWishlistInit === 'function') {
window.RmWishlistInit();
}
});Snippet 8: Custom CSS Styling & Animation Overrides
Paste this code into Online Store → Themes → Customize → Theme settings → Custom CSS to add modern micro-animations and heart pop effects:
/* ── RM Wishlist Plus Custom Styles ────────────────────────── */
/* 1. Heart pop animation when product is wishlisted */
.rm-wl-icon-filled {
animation: rmHeartPop 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes rmHeartPop {
0% { transform: scale(0.6); opacity: 0.5; }
50% { transform: scale(1.3); }
100% { transform: scale(1); opacity: 1; }
}
/* 2. Floating Heart on Product Cards */
.rm-wl-card-float {
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(4px);
border: 1px solid rgba(0, 0, 0, 0.06) !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important;
}
.rm-wl-card-float:hover {
transform: scale(1.12) !important;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.14) !important;
}
/* 3. PDP Wishlist Button Hover State */
.rm-wl-pdp-btn {
letter-spacing: 0.02em;
transition: all 0.2s ease !important;
}
.rm-wl-pdp-btn:hover {
transform: translateY(-1px);
opacity: 0.9;
}3. Wishlist Card Logic Engine & Code Editor Guide (/app/editor)
The Logic Engine is the built-in templating system that powers the product cards rendered on your store's dedicated wishlist page (/pages/wishlist). You can customize this layout without touching your Shopify theme files by opening RM Wishlist Plus Admin → Code Editor (/app/editor). The editor provides a live Monaco code editor with two tabs: 1. Custom Product Cards (card-template.html) and 2. Custom Data (custom-data.json).
What is the Logic Engine?
When shoppers visit /pages/wishlist, the client engine (wishlist-core.js) fetches their saved products via the secure App Proxy and evaluates your card template using our custom client-side Liquid parser:
Loops First ({% for %})
Expands repeated items like tags or color swatches.
Conditions Second ({% if %})
Evaluates operators and dynamic flags (on_sale, inventory < 5, etc.) to show/hide badges or content.
DOM Hydration
Populates links, images, titles, prices, and variant selectors into data-wl-* attributes.
HTML Data Attributes (Auto-Hydration)
Add these special attributes to your HTML elements in card-template.html. The app will automatically populate them with live product data:
| Attribute | Recommended HTML Tag | What It Injects |
|---|---|---|
data-wl-link | <a href="#"> | Product page URL (/products/{handle}) |
data-wl-image | <img src="" alt="" /> | Featured product image URL + Title alt text |
data-wl-title | <a href="#"> or <span> | Product title text |
data-wl-vendor | <span> or <div> | Product vendor / brand name |
data-wl-price | <span class="price"> | Formatted price (auto-updates when variants change) |
data-wl-compare-price | <span class="compare"> | Original crossed-out price if product is on sale |
data-wl-cart-btn | <button type="button"> | Move to Cart button (handles single & multi-variants) |
data-wl-remove-btn | <button type="button"> | Remove from wishlist action button |
data-wl-product-field="field" | <div> or <span> | Core Shopify field: tags, productType, descriptionHtml, or totalInventory |
data-wl-metafield="ns.key" | <div> or <span> | Custom metafield value (e.g. custom.material) |
Template Variables
You can use standard curly brace variables inside your HTML and condition blocks:
| Variable | Output Description |
|---|---|
{{ title }} | Product title |
{{ vendor }} | Vendor or brand |
{{ price }} | Current formatted price |
{{ compare_price }} | Compare-at / original price |
{{ image }} | Main featured image URL |
{{ url }} | Link to product page |
{{ handle }} | Product URL handle (slug) |
{{ tags }} | Comma-separated product tags |
{{ type }} | Shopify Product Type |
{{ inventory }} | Total inventory quantity available across all variants |
{{ descriptionHtml }} | Full HTML product description |
{{ metafield:namespace.key }} | Value of any registered metafield |
Conditional Statements ({% if ... %})
Use {% if %} blocks to dynamically show badges, sale banners, or urgency alerts.
| Condition / Operator | Example | When It Evaluates to TRUE |
|---|---|---|
| on_sale | {% if on_sale %} SALE! {% endif %} | Current variant compare-at price > price |
| out_of_stock | {% if out_of_stock %} Sold Out {% endif %} | All variants of the product are unavailable |
| < (Less than) | {% if inventory < 5 %} Low Stock! {% endif %} | Inventory count is below 5 |
| > (Greater than) | {% if inventory > 10 %} Plenty in stock! {% endif %} | Inventory count is above 10 |
| == (Equals) | {% if type == 'Shoes' %} Free Shipping! {% endif %} | Product type exactly matches string |
| contains | {% if tags contains 'New' %} <badge>NEW</badge> {% endif %} | Product tags or string contains value |
Practical Conditional Examples:
<!-- 1. Sale Discount Badge -->
{% if on_sale %}
<span class="badge-sale" style="background:#fee2e2; color:#ef4444; font-weight:700; padding:2px 8px; border-radius:4px; font-size:11px;">
ON SALE
</span>
{% endif %}<!-- 2. Low Inventory Urgency Indicator -->
{% if inventory < 5 %}
<span class="badge-urgency" style="background:#fef3c7; color:#d97706; font-size:11px; font-weight:600; padding:2px 6px; border-radius:4px;">
⚠️ Only few items left!
</span>
{% endif %}<!-- 3. New Arrival Badge Based on Tags -->
{% if tags contains 'New Arrival' %}
<span class="badge-new" style="background:#111827; color:#ffffff; font-size:10px; font-weight:700; padding:3px 8px; border-radius:12px;">
NEW
</span>
{% endif %}<!-- 4. Sold Out Overlay -->
{% if out_of_stock %}
<div style="background:rgba(0,0,0,0.6); color:#fff; padding:6px 12px; border-radius:4px; font-size:12px; font-weight:700; text-align:center;">
SOLD OUT
</div>
{% endif %}Loops & Lists ({% for ... %})
Iterate over product tags or metafield lists. Dot-notation is supported for object properties.
<div style="display:flex; flex-wrap:wrap; gap:4px; margin-top:4px;">
{% for tag in tags %}
<span style="background:#f3f4f6; color:#4b5563; font-size:10px; padding:2px 6px; border-radius:10px;">
#{{ tag }}
</span>
{% endfor %}
</div><div style="display:flex; gap:6px; margin-top:6px;">
{% for c in metafield:custom.colors %}
<span style="width:14px; height:14px; border-radius:50%; border:1px solid #d1d5db; background:{{ c.hex }};" title="{{ c.name }}"></span>
{% endfor %}
</div>Metafields & Metaobject References
The logic engine seamlessly expands Shopify Metafields and Metaobjects:
Activating Custom Data (custom-data.json)
To use tags, inventory, type, or custom metafields in your template, they must be registered in the Custom Data tab in the Code Editor (/app/editor):
{
"productFields": [
"tags",
"productType",
"totalInventory",
"descriptionHtml"
],
"productMetafields": [
{ "namespace": "custom", "key": "material" },
{ "namespace": "custom", "key": "colors" }
]
}- In the Code Editor, click the Custom Data tab.
- Check the standard product fields you want to fetch, or type your Metafield namespaces and keys.
- Click Save Changes. The data is now available in your card template immediately!
4. Theme File Placement Guide (Where to Paste Code)
Quick reference table for locating exactly where each snippet belongs across common Shopify Online Store 2.0 themes.
| Feature | Common Theme File Path | Where to Place Inside File |
|---|---|---|
| Save for Later Snippet | snippets/rm-save-for-later.liquid | Create as a new file under Snippets |
| Save for Later Render | sections/main-cart-items.liquid or snippets/cart-drawer.liquid | Inside {% for item in cart.items %} loop, near the remove link |
| Header Wishlist Badge | sections/header.liquid or snippets/header-actions.liquid | Next to Cart or Account icon (<a href="/cart">) |
| Manual PDP Button | sections/main-product.liquid | Beside or directly below the buy buttons / add to cart form |
| Manual Card Heart | snippets/card-product.liquid or snippets/product-card.liquid | Inside the product card image wrapper container |
| Custom CSS Overrides | assets/base.css or assets/theme.css | At the very bottom of the stylesheet (or Theme Settings → Custom CSS) |
Shopify Dawn / Free Themes (Sense, Craft, Refresh, Studio)
- Header Icon: sections/header.liquid — search for class="header__icons" and place Snippet 3 directly before <a href="{{ routes.cart_url }}".
- Cart Drawer: snippets/cart-drawer.liquid — search for <cart-remove-button and place Snippet 1 or Snippet 2 right above it.
- Cart Page: sections/main-cart-items.liquid — search for <cart-remove-button and place Snippet 1 or Snippet 2 above it.
Premium Themes (Prestige, Impulse, Focal, Symmetry, Broadcast)
- Prestige / Focal: In snippets/cart-drawer.liquid or snippets/line-item.liquid, place Snippet 1 below line item quantity controls.
- Impulse: In snippets/cart-item.liquid, place Snippet 1 under line-item title and price.
5. Pre-Launch Verification Checklist
Before publishing to your live shoppers, verify each item below to ensure smooth operation:
Go to Theme Customizer → App Embeds → "Wishlist Config & Styles" is switched to ON.
Visit any product page; confirm the Wishlist button displays and clicks smoothly.
Visit /pages/wishlist; confirm the grid or empty-state message appears cleanly.
Add an item as a guest, refresh the browser; verify the item remains in the wishlist.
On /pages/wishlist, click "Move to Cart"; confirm the item enters the shopping cart and opens the drawer.
Confirm the count badge updates from 0 to 1 immediately upon saving an item.
Check on an iPhone or Android device; confirm buttons are easy to tap and properly formatted.
6. Frequently Encountered Questions
Answers to the most common setup and theme compatibility questions.
No. For 95% of stores, simply enabling the App Embed and adding the Wishlist Button and Wishlist Page blocks via the visual Theme Customizer is all that is required. The code snippets in Section 2 are optional for merchants who want extra features like Cart Save for Later or Header Icons.
7. Merchant Support & Free Integration
Have a unique theme design or want our engineers to install and style the buttons for you? We provide 100% free setup and styling support for all Shopify merchants using RM Wishlist Plus.