一、背景与目标
在 Shopify 实现 “Back in Stock” (BIS) 功能。 实现缺货商品收集用户订阅,当商品补货后自动邮件提醒用户购买,提高转化。
二、技术方案
此功能有两种实现方式:
方案 A:Klaviyo Onsite Snippet 简单快速,适合官方提供的免费主题
方案 B:Klaviyo BIS Subscription API 只使用订阅api,适合自定义主题。
方案 A:使用 Klaviyo Onsite Snippet 集成
1、将 Klaviyo 与 Shopify 集成,将数据导入 Klaviyo
2、在 Shopify 加入 Klaviyo App
3、创建 Back in Stock flow
登录 klaviyo 后台, Flows --> Create Flow ---> 搜索 Back in Stock
4、获取 PUBLIC API KEY
登录 klaviyo 后台, Settings --> Account ---> API keys
5、在主题的 theme.liquid 中加入如下代码片段
- 在
</body>标签上面插入以下代码,并替换 PUBLIC_API_KEY:
<script src="https://a.klaviyo.com/media/js/onsite/onsite.js"></script>
<script>
var klaviyo = klaviyo || [];
klaviyo.init({
account: "PUBLIC_API_KEY",
platform: "shopify"
});
klaviyo.enable("backinstock",{
trigger: {
product_page_text: "Notify Me When Available",
product_page_class: "button",
product_page_text_align: "center",
product_page_margin: "0px",
replace_anchor: false
},
modal: {
headline: "{product_name}",
body_content: "Register to receive a notification when this item comes back in stock.",
email_field_label: "Email",
button_label: "Notify me when available",
subscription_success_label: "You're in! We'll let you know when it's back.",
footer_content: '',
additional_styles: "@import url('https://fonts.googleapis.com/css?family=Helvetica+Neue');",
drop_background_color: "#000",
background_color: "#fff",
text_color: "#222",
button_text_color: "#fff",
button_background_color: "#439fdb",
close_button_color: "#ccc",
error_background_color: "#fcd6d7",
error_text_color: "#C72E2F",
success_background_color: "#d3efcd",
success_text_color: "#1B9500"
}
});
</script>
6、如果主题适配,此时该功能已生效,效果如图
优缺点
✅ 优点:
- 实现快,维护简单。
- 补货时自动发送邮件提醒。
⚠️ 注意:
- 只支持 shopify 官方免费主题。
- 自定义程度有限。
方案 B:使用 Klaviyo BIS Subscription API 自定义集成
使用场景
- 使用shopify自定义主题
- 需要完全掌控表单样式、挂载位置以及交互体验
步骤 1~4 同方案A
5、在 buy-button.liquid 中插入表单
插入在 Buy Button 下方:
{% if product.selected_or_first_available_variant.available == false %}
<div class="back-in-stock-form-wrapper">
<form id="klaviyo-back-in-stock-form">
<input type="email" id="bis-email" placeholder="Enter your email" required>
<button type="submit">Notify Me</button>
<p id="bis-message" style="display:none;color:green;">Thank you! You'll be notified when this product is back in stock.</p>
</form>
</div>
{% endif %}
6、在 global.js (或其他已引用的js)中添加脚本
使用 Klaviyo 官方推荐结构:
(简单验证,并非最终实现代码)
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('klaviyo-back-in-stock-form');
if (form) {
form.addEventListener('submit', async function(e) {
e.preventDefault();
const email = document.getElementById('bis-email').value.trim();
const message = document.getElementById('bis-message');
const variantId = document.querySelector('[name="id"]').value;
const klaviyoVariantId = `$shopify:::$default:::${variantId}`;
const payload = {
"data": {
"type": "back-in-stock-subscription",
"attributes": {
"profile": {
"data": {
"type": "profile",
"attributes": { "email": email }
}
},
"channels": ["EMAIL"]
},
"relationships": {
"variant": {
"data": { "type": "catalog-variant", "id": klaviyoVariantId }
}
}
}
};
try {
const response = await fetch(`https://a.klaviyo.com/client/back-in-stock-subscriptions/?company_id=YOUR_PUBLIC_API_KEY`, {
method: 'POST',
headers: {
"Content-Type": "application/json",
"revision": "2024-06-15"
},
body: JSON.stringify(payload)
});
if (response.ok) {
message.style.display = 'block';
form.reset();
} else {
const resData = await response.json();
console.error(resData);
alert("Subscription failed, please try again.");
}
} catch (error) {
console.error(error);
alert("Subscription failed, please try again.");
}
});
}
});
7、效果如图
三、添加配置及多语言(针对方案B)
1、添加多语言
在 locales/en.default.json 添加:
"back_in_stock": {
"button": "Notify me when available",
"title": "Notify me when available",
"description": "Register to receive a notification when this item comes back in stock.",
"email_placeholder": "Your email",
"submit": "Notify me",
"success": "Thank you! You'll be notified when this product is back in stock."
}
替换原文案,例如"Notify me when available"替换为
{{ 'back_in_stock.button' | t }}
2、添加 Metafield
Name: Back in Stock Enabled
Namespace and key: custom.bis_enabled
Content type: True or False (Boolean)
Description: Enable Back in Stock button when sold out
主要代码
全局 js
document.addEventListener('DOMContentLoaded', function () {
const modal = document.getElementById('bis-modal');
const trigger = document.getElementById('bis-trigger-button');
const close = document.getElementById('bis-close');
const form = document.getElementById('klaviyo-back-in-stock-form');
const message = document.getElementById('bis-message');
if (trigger && modal && close && form) {
// 打开 Modal
trigger.addEventListener('click', () => {
modal.style.display = 'flex';
});
// 关闭 Modal
close.addEventListener('click', () => {
modal.style.display = 'none';
});
// 点击 Modal 外层关闭
modal.addEventListener('click', (e) => {
if (e.target === modal) {
modal.style.display = 'none';
}
});
// 提交表单
form.addEventListener('submit', async function (e) {
e.preventDefault();
const email = document.getElementById('bis-email').value.trim();
const variantId = document.querySelector('[name="id"]').value;
const klaviyoVariantId = `$shopify:::$default:::${variantId}`;
const payload = {
"data": {
"type": "back-in-stock-subscription",
"attributes": {
"profile": {
"data": {
"type": "profile",
"attributes": { "email": email }
}
},
"channels": ["EMAIL"]
},
"relationships": {
"variant": {
"data": { "type": "catalog-variant", "id": klaviyoVariantId }
}
}
}
};
try {
const response = await fetch(`https://a.klaviyo.com/client/back-in-stock-subscriptions/?company_id=YOUR_PUBLIC_API_KEY`, {
method: 'POST',
headers: {
"Content-Type": "application/json",
"revision": "2024-06-15"
},
body: JSON.stringify(payload)
});
if (response.ok) {
message.style.display = 'block';
form.reset();
setTimeout(() => {
modal.style.display = 'none';
message.style.display = 'none';
}, 2000);
} else {
const resData = await response.json();
console.error(resData);
alert("Subscription failed, please try again.");
}
} catch (error) {
console.error(error);
alert("Subscription failed, please try again.");
}
});
}
});
弹窗 liquid
{% if product.selected_or_first_available_variant.available == false
and product.metafields.custom.bis_enabled == true
%}
<button
id="bis-trigger-button"
type="button"
class="primary-btn"
style="width: 100%;"
>
{{ 'back_in_stock.button' | t }}
</button>
<div
id="bis-modal"
style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);align-items:center;justify-content:center;z-index:9999;"
>
<div style="background:#fff;padding:30px;border-radius:6px;max-width:360px;width:90%;position:relative;">
<button
id="bis-close"
style="position:absolute;top:10px;right:10px;background:none;border:none;font-size:22px;cursor:pointer;"
>
×
</button>
<h3
class="heading-3"
style="text-align: center;"
>
{{ product.title }}
</h3>
<p
class="main-desc"
style="margin: 10px 0;"
>
{{ 'back_in_stock.description' | t }}
</p>
<form id="klaviyo-back-in-stock-form">
<input
type="email"
id="bis-email"
placeholder="{{ 'back_in_stock.email_placeholder' | t }}"
required
style="width:100%;padding:10px;margin-top:10px;border:1px solid #ccc;"
>
<button
type="submit"
class="primary-btn"
style="width: 100%;margin-top: 20px;"
>
{{ 'back_in_stock.submit' | t }}
</button>
</form>
<p id="bis-message" style="display:none;color:green;margin-top:10px;">
{{ 'back_in_stock.success' | t }}
</p>
</div>
</div>
{% endif %}
四、测试验证流程
✅ 创建缺货商品或设置变体库存为 0。
✅ 前端加载页面测试表单是否显示。
✅ 填写邮箱订阅后在 Klaviyo 检查是否收到 Subscription 事件。
✅ 补货该商品,验证是否触发 Back in Stock 邮件提醒。
五、参考文档
Getting started with Shopify | Klaviyo Help Center
How to enable onsite tracking for Shopify | Klaviyo Help Center
How to build a back in stock flow | Klaviyo Help Center
How to install Back in Stock for Shopify | Klaviyo Help Center
Set-up Back in Stock Notifications via API | Klaviyo Developers