两行代码,Shopify 商品页就有了截止时间
不开代码编辑器,只在模板编辑器里加一个分区,倒计时就上线了。
Shopify Theme Store 上架的主题必须自带一个 Custom Liquid 分区,就因为这一条要求,Shopify 商品页上的倒计时从头到尾不用碰代码文件。这个分区在模板编辑器里就是一个吃原始 HTML 的输入栏,所以加载器脚本和挂载元素可以像加一块富文本那样放进商品模板,文件树一次都不用打开。真正值得慢慢想的是:这个时钟到底在倒向什么。BootSignal 的倒计时走向你写进 data-target 的那个固定时刻,对每一位顾客都是同一瞬间,所以它变不成那种给每个访客悄悄从头再来的常青计时器。套餐只在边缘处才成为问题:Shopify 给模板编辑器和这个分区都没有附套餐条件,而做不了这件事的四个套餐,是连一个普通店面都没有的那一侧。
没有要升的套餐,例外只有四个
Shopify 在文档里说明代码编辑器、模板编辑器和 Custom Liquid 分区时,都没有点名任何套餐条件,Basic 套餐页面则说 Basic 包含一个由你自己改的在线商店,改的方式是 "through Shopify's built-in theme editor",也就是 Shopify 内置的模板编辑器。所以 Basic 及以上没有要买的东西。现有的九个套餐里有四个落在这句话之外,理由分两种。
其中两个根本没有店面。Lite 套餐页面写着 "The Lite plan doesn't include the online store sales channel",Agentic 套餐页面把 "Online Store" 排在 "aren't available with the Agentic plan" 的功能列表最前面。没有主题、没有商品页,时钟也就无处渲染。另外两个有店面,但几乎没有控制权:Starter 说 "Other themes and customization options aren't available on the Starter plan",Retail 说 "You can't use any other theme with the Retail plan" 和 "Further customization options aren't available on the Retail plan"。两者都被限制在 Spotlight 主题上,两个页面都没说代码编辑器进不进得去,而且都不再接受新店铺,所以 Starter 和 Retail 记成未确认,而不是记成不行。
在粘贴之前,先把截止时间的位置定下来
倒计时不是一个功能,而是一个位置上的决定。放在购买按钮下面,它回答的是顾客此刻正在问的问题。放在店铺顶部的横幅里,它够得着还在逛分类页、连商品都没挑好的人。放在购物车页面,它对的是已经选好却还在犹豫的人。挑一个就好:同一条动线上摆三个时钟,读起来就不再是信息,而是压迫。
| 你想放的位置 | Shopify 上的落点 | 怎么加 | 会出现在 |
|---|---|---|---|
| 购买按钮下面 | 商品模板 | 在模板编辑器里加 Custom Liquid 分区或区块 | 用这个模板的全部商品 |
| 店铺顶部通栏 | 布局文件 theme.liquid | 编辑代码,粘在闭合的 </body> 标签前 | 整个店面,结账页除外 |
| 购物车页面 | 购物车模板 | 在模板编辑器里加 Custom Liquid 分区 | 只有购物车页面 |
| 博客文章下面 | 文章的主分区文件 | 编辑代码,Dawn 的话是 sections/main-article.liquid | 全部博客文章 |
| 结账流程里 | 这条路够不到 | 结账是另一套定制界面 | 哪里都不出现 |
购物车那一行常让人意外。Shopify 要求上架主题在除顾客账户、礼品卡和结账之外的每一个模板上都支持分区,所以购物车页面跟商品页一样吃 Custom Liquid 分区。结账才是真正的墙,主题层面的代码一概够不到。
这就是那个时钟,它正在这一页上走
倒计时至目标日 · 到点显示你的消息
这不是截图,是正在运行的小部件;商品页上它同样落在正文栏宽里。
从模板编辑器里加,不打开任何代码文件
两个 Shopify 地址都要挂到同一个 site id 下
一家 Shopify 店铺有两个网址,而小部件看不出它们是同一家店。一个是你设为主域名的自定义域名,Shopify 会把它展示 "to customers as they browse your online store",也就是顾客浏览你的在线商店时看到的那个,其余地址都重定向到它。另一个是店铺创建时带的
.myshopify.com地址,这个名字 Shopify 只肯替你改一次,之后再不受理。两个都加进 BootSignal 控制台:小部件是拿location.hostname去对同一个 site id 下登记的地址,从你漏掉的那一个送出的页面,什么都不会渲染。哪天真把那一次改名用掉了,先登记新地址再切换。打开模板编辑器,切到商品模板
在 Shopify 后台进 在线商店(Online Store),找到主题,点 自定义(Customize)打开模板编辑器。用顶部菜单栏中间的模板下拉菜单切到商品模板,这样你改的就是顾客在商品页上看到的东西,而不是首页。
加一个 Custom Liquid 分区,把两行一起粘进去
在左侧边栏点分区的图标,选 Add section(新增一个分区),要放进已有分区里就选 Add block(新增一个区块),然后挑 Custom Liquid(作用是让你直接粘 HTML 的那个分区)。把它拖到时钟该待的位置,通常就在价格或者加入购物车按钮下面。加载器和挂载元素粘进代码栏,把
YOUR_SITE_ID换成控制台在域名旁边给你的那串,再点 保存(Save)。数字下面单位名称用哪种语言由data-lang决定,下面这段已经设成zh-cn,出来的是天、小时、分、秒。<script src="https://bootsignal.com/bootsignal.js" data-site-id="YOUR_SITE_ID" data-lang="zh-cn" defer></script> <div data-bootsignal="countdown" data-target="2026-12-31T23:59:59" data-expired="This sale has ended."></div>把真正的截止时刻写进 data-target
把占位的时间戳换成你的折扣真正停掉的那一刻,格式保持一样。然后把
data-expired写成时钟走完之后页面该说的那句话。下面这个值是示例,给顾客看的那句用中文重写就行。<div data-bootsignal="countdown" data-target="2026-09-01T23:59:59" data-expired="Sale pricing has ended. Free shipping is still on."></div>保存,然后去看一个真实的商品地址
模板编辑器会在分区内容上画自己的覆盖层,所以它是版面检查,不是行为检查。保存,在普通标签页里打开一个线上的商品页,看着数字往下走。什么都没渲染出来,先拿地址栏的主机名对一下你登记的域名。
- Custom Liquid 设置项的内容上限是 50kb,小部件的代码段离得很远。
- 写坏的 Liquid 保存时报错,没闭合的 HTML 标签会被自动补齐,复制到一半的代码段因此会被重排。闭合的
</div>和</script>要跟着一起粘。 - 这个设置项用不了
{% javascript %}和{% stylesheet %}标签,能在保存里活下来的形状就只剩普通 HTML 加一个<script src>。加载器正好就是这个形状。 - 脚本标签上的
defer留着。Shopify 的 Theme Check 把阻塞解析的脚本列为拖慢店面的原因。
真实的截止时间,和话术之间的差别
紧迫感只有在它是真的时候才站得住。你的促销周日午夜结束,时钟这么写,周一回来的顾客看到的就是他预期的价格。另一种时钟不管你什么时候到都显示五小时,换个浏览器就重置,和店里发生的任何事都没有关系。看出来的顾客不只是跳过这次优惠,他们连页面上其余的话也不再信了。
BootSignal 只做第一种。data-target 是一个固定的时间戳,所有人倒向同一刻,也在同一刻一起归零。没有按访客计时的模式,也没有重启。促销延期,你就自己改时间戳再保存,那是你做的决定,不是小部件自己跑的循环。
整份目录都照这条规矩走。社会认同提示只会重放你网站已经记录下来的动态,它没有办法编出一笔根本不存在的俄亥俄州订单。在电商站上,这就是社会认同和道具之间的差别。
一个 Custom Liquid 分区,一个时间戳,不装应用。
如果你的主题没有 Custom Liquid 分区
Custom Liquid 是 Shopify Theme Store 的上架要求,不是平台层面的保证。自建主题、非市场主题或者老的 vintage 主题可以不带它,遇上这种情况就只剩代码编辑器。Shopify 后台进 在线商店(Online Store),找到主题,点横向菜单("...")图标选 编辑代码(Edit code)。先把主题复制一份,留个能退回去的东西。
到这里两段要分开放。加载器进 布局(Layout)文件夹里的 theme.liquid,粘在闭合的 </body> 标签之前,因为它本来就该在每个页面上加载一次。挂载元素不是这样:theme.liquid 是全站布局,倒计时粘在那里,你的政策页和搜索结果页上都会冒出一个时钟。
也就是说,要找的是分区文件,不是模板文件。Online Store 2.0 或 Horizon 世代的主题里,商品模板是 templates/product.json,而 Shopify 写着 "If you're using a JSON template, then any HTML or Liquid code needs to be included in a section"。标记粘进那个 JSON,文件就坏了,保存不过去。打开 分区(Sections)文件夹,编辑负责渲染商品页的那个分区。博客文章 Shopify 给的是同一条规则,Dawn 里对应的文件是 sections/main-article.liquid。
<div data-bootsignal="countdown"
data-target="2026-09-01T23:59:59"
data-expired="Sale pricing has ended."></div>唯一该放进 theme.liquid 的那个挂载元素
全店通告是例外。如果每一页上的每一位顾客都该知道促销周日结束,那么全站布局就是它该待的地方,公告横幅正是为此做的。把它粘在 theme.liquid 里加载器旁边,闭合的 </body> 标签之前,每条新公告给一个自己的 data-id。
<div data-bootsignal="announce"
data-message="Summer sale ends Sunday at midnight"
data-link="/collections/sale"
data-link-text="Shop the sale"
data-id="summer-2026"></div>顶部横幅 · 按访客记忆关闭状态
公告横幅。data-link 收的是店铺里普通的路径,所以它可以直接指向这次促销对应的分类页。
横幅和时钟要说同一件事。横幅上写周日、底下时钟走到周六,比两个都不放更糟。
跑起来要花多少钱
促销那一周是流量冲高的一周,而在按量计费的小部件上,那也是账单冲高的一周。这里的计量单位换成了域名:每个已注册域名每月 $20 或每年 $200,全部小部件都在内,价格里没有任何一项跟流量或浏览量挂钩。所以商品页上的时钟和它上面的横幅,在冷清的周二和一年里最忙的那天要价一样。这个价钱背后的目录是 38 个付费小部件加 33 个免费浏览器工具,之后发布的小部件也算在里面。第二家店就是第二个域名,在控制台里定价。完整价格有细节,带价的横向对比在对比区。
写好时钟归零之后要说的那句话
多数商家会仔细设 data-target,然后在 data-expired 里随手打一句转头就忘的话。这是反的。过期文案才是挂得最久的那一句,从促销结束的那一刻起一直待在商品页上,直到你想起来为止,而忙起来的店铺可能是好几天。
给它派个活。"The sale has ended" 只告诉顾客他来晚了,此外什么都没说。"Sale pricing has ended, free shipping is still on",促销价结束但包邮还在,等于给了他一个留在这一页上的理由。
时钟没出现的时候
- 拿地址栏里的主机名对一下你登记的域名。自定义域名和
.myshopify.com同时应答的店铺,两个都要登记。 - 确认加载器在页面上只出现一次。既粘进 Custom Liquid 分区又粘进
theme.liquid,同一个商品页上就有两份。 - 看 Custom Liquid 栏保存下来的内容,而不是你粘进去的内容。没闭合的标签保存时会被替你补上,丢了
</div>的代码段回来时结构已经变了。 - 确认挂载元素在你正在看的那个模板上。加到首页模板上的分区不会出现在商品页上,而这一条最耗人时间。
- 想一想粘完之后主题有没有更新过。Shopify 提醒,如果你的代码改动与主题更新不兼容,更新后的副本里全部代码改动都会被删掉,而 Custom Liquid 分区在这件事里怎么算,它没有交代,所以每次更新后都去商品页看一眼。
除了那次粘贴本身,你配置的东西没有一样存在主题里。重新加一次分区、把时间戳再打一遍,同一个时钟就回来了,这让主题更新变成一件麻烦事,而不是一次损失。
常见问题
- 目标时间用的是哪个时区?
data-target里写什么就按 ISO 日期时间解析,而没带偏移量的值(2026-12-31T23:59:59)会按每位访客自己的本地时间读。这意味着洛杉矶的顾客和首尔的顾客看到促销结束的时刻不一样。真要定一个死线,就把偏移量写明:2026-12-31T23:59:59+09:00,UTC 则写Z。这样所有人倒向的是同一瞬间。- templates/product.json 是倒计时该待的地方吗?
- 不是。那个文件是一份清单而不是一个页面:它写明哪些分区参与渲染,并保存你给它们的设置,所以硬塞一段原始标记进去会让 JSON 失效,保存会被拒绝。Shopify 对这类模板给的规则是标记必须住在分区里,于是倒计时只剩两个家:要么在模板编辑器里新增一个 Custom Liquid 分区,要么改 分区(Sections)文件夹里负责渲染商品页的那个文件。
- 模板编辑器的预览里,倒计时会走吗?
- 不太可靠。预览跑的是你线上的店面,不是被沙箱隔开的供应商框架,所以数字通常确实会出现。问题在压在数字上面的东西:编辑器会在分区内容上盖一层自己的覆盖层,这让预览适合确认位置,却不适合确认行为。先保存,再在正常的浏览器窗口里打开线上商品页,盯着数字往下走一遍。
- 一个页面上能放几个倒计时?
- 想放几个放几个。加载器会挂载它找到的每一个元素,所以两个
data-bootsignal="countdown"的 div 各带各的data-target,互不干扰地各走各的。加载器本身仍然是整个主题里粘一次。 - 能不能让计时器对每个访客重新开始?
- 不能,而且这是有意的。
data-target是一个固定时间戳,每位顾客倒向同一刻,时钟也对所有人在同一刻走完。按访客重置的常青计时器是一种诱导性设计,这个小部件没有做这件事的开关。截止时间要挪,得你自己去改那个时间戳。 - 主题一更新,装好的东西还在吗?
- 有可能就没了。Shopify 说,如果你对主题代码所做的改动与主题更新不兼容,更新后的副本里你做的全部代码改动都会被删掉,而它的文档没有交代 Custom Liquid 分区在这件事里怎么算。更新前先复制主题,更新后打开一个商品页看看。把加载器和挂载元素照原来的时间戳再粘一遍,时钟就完全复原,因为它没有任何东西存在主题里。
先登记店铺域名,再把时钟放进一个 Custom Liquid 分区。
数据来源
- Shopify Dawn: 日本語テーマ翻訳ファイル(テーマエディタに出るセクション表示名の出どころ) (核对 2026-08-25)
- Shopify Help Center: Theme editor features overview (Edit theme, Sections sidebar, template dropdown) (核对 2026-08-25)
- Shopify Help Center: Editing theme code (Edit code path, theme update warning, Theme Check parser blocking scripts) (核对 2026-08-25)
- Shopify.dev: Input settings (liquid setting type, 50kb cap, auto closed tags, disallowed tags) (核对 2026-08-25)
- Shopify.dev: Theme Store requirements (Custom Liquid section requirement, templates must support sections) (核对 2026-08-25)
- Shopify Help Center: Basic plan (online store customized through the built in theme editor) (核对 2026-08-25)