關於我們 服務 社群 聯絡 作品集 技術文章 開始合作 🐾

這次幫客戶「MU 沐藍輕履」做 1Shop 的首頁客製化,本來以為就是加兩組按鈕的事,結果花了一整個晚上才搞懂 1Shop 的「官網」跟「獨立銷售頁」差在哪,為什麼我貼在「全網站」的 JavaScript 有些頁面吃得到、有些頁面吃不到。

這篇是給其他也在接 1Shop 客製化案子的工程師、或者自己是 1Shop 店家想搞懂為什麼某些程式碼沒效的人看的。

🐾
「你以為的全網站,不是 1Shop 的全網站。」
— 善善,接案顧問貓

需求:很單純的兩個按鈕

客戶的需求其實不複雜:

  1. 首頁分類按鈕:9 個品牌/分類的快捷入口,圓形 logo + 文字,像蝦皮那種
  2. 全站回首頁按鈕:右下角加一個浮動按鈕,融入 LINE/FB 客服按鈕群組

做法也很直覺:寫好 HTML + CSS + JavaScript,貼到 1Shop 後台的「全網站」自訂區塊,應該就搞定了對吧?

事情當然沒這麼簡單。

第一個坑:頁面結構每個都不一樣

我原本寫的 JS 用了這樣的邏輯:找到 nav.navbar 把按鈕插在它後面。在首頁測試完美,所以放心交給客戶驗收。

然後客戶回覆:「某某商品頁怎麼沒有按鈕?」

我打開那個頁面 F12 查 DOM,傻眼了 — 這頁根本沒有 nav.navbar,連 chat-list(右下角的 LINE/FB 浮動按鈕群組)都沒有。同樣是 1Shop 的銷售頁,為什麼結構差這麼多?

⚠️
關鍵發現 1Shop 的銷售頁分成兩種版型,DOM 結構完全不同。我原本以為只要是銷售頁就都一樣,這個預設害我花了好幾小時除錯。

第二個坑:「官網」跟「獨立銷售頁」的差別

去後台一查,發現 MU 的銷售頁列表有個篩選 tab:「全部 / 官網 / 非官網」。而且每個銷售頁旁邊有個兩碼英文編號,像是 GFPJVQNIHW

我原本以為這些代碼是不同的模板類型,查了 1Shop 官方文件才發現 — 這些只是「銷售頁編號前綴」,單純拿來標記訂單歸屬用的(例如訂單號 GF20260422001 就代表這筆訂單來自 GF 開頭的那個銷售頁)。

真正的差別在「有沒有加入官網」。根據 1Shop 官方文件,銷售頁分成兩種:

✅ 隸屬於官網的銷售頁

  • 金流、物流、優惠跟官網共用
  • 購物車合併(可一次買多品項)
  • 上方有固定的官網選單
  • 吃「全網站」自訂 HTML/CSS/JS

⚠️ 獨立銷售頁

  • 金流、物流、優惠各自獨立
  • 購物車獨立
  • 沒有官網選單
  • 不吃「全網站」自訂設定

也就是說,當我把程式碼貼在後台「全網站 → Body 最上方」,只有「隸屬於官網」的銷售頁會執行這段 JavaScript。那些沒加入官網的「獨立銷售頁」,就算網址長得一樣、一樣是 1Shop 平台,根本不會載入我貼的程式碼

怎麼判斷是哪一種?

有三個方法可以判斷某個頁面是不是「隸屬官網」:

方法 1:看 URL 模式(不可靠)

兩種都是 https://商店網址/xxxxxx 的 6 碼格式,從網址上看不出來。

方法 2:看後台分類(最直接)

進後台「銷售頁」列表,頂部有「全部 / 官網 / 非官網」三個篩選 tab,直接看是哪一組。

方法 3:看前台 DOM(技術最硬核)

按 F12 打開開發者工具,跑這段指令:

console.log('navbar:', !!document.querySelector('nav.navbar'));
console.log('chat-list:', !!document.querySelector('.chat-list'));
console.log('page-sale:', !!document.querySelector('.page-sale'));

官網銷售頁會有 nav.navbarchat-list,獨立銷售頁可能只有 page-sale

解法:多層 fallback 策略

搞清楚架構後,我重新設計了程式碼的邏輯。既然不同頁面結構不同,就不能只靠一個選擇器,得準備多套方案:

function insertCategoryButtons() {
  // 策略 1: 首頁 → 插在 navbar 後面
  var navbar = document.querySelector('nav.navbar');
  if (navbar) {
    navbar.insertAdjacentHTML('afterend', html);
    return;
  }

  // 策略 2: 商品頁 → 插在 page-sale 容器開頭
  var pageSale = document.querySelector('.page-sale');
  if (pageSale) {
    pageSale.insertAdjacentHTML('afterbegin', html);
    return;
  }

  // 策略 3: 找「精選單品」標題,插在它前面
  var headings = document.querySelectorAll('h1, h2, h3');
  for (var i = 0; i < headings.length; i++) {
    if (headings[i].textContent.indexOf('精選單品') !== -1) {
      headings[i].insertAdjacentHTML('beforebegin', html);
      return;
    }
  }

  // 策略 4: 最終 fallback,插在 body 最上面
  document.body.insertAdjacentHTML('afterbegin', html);
}

回首頁按鈕也一樣:有 chat-list 的頁面融入原生按鈕群組;沒有的頁面就用 position: fixed 做獨立浮動按鈕。

💡
重試機制也要加 1Shop 的頁面是動態渲染的,DOMContentLoaded 觸發時目標元素可能還沒出現。要用 setInterval 每 300ms 檢查一次,最多試 30 次(9 秒)。這個比預期重要很多。

第三個坑:獨立銷售頁根本載不到我的程式碼

就算把 fallback 做好,獨立銷售頁還是完全沒反應。因為問題不在 DOM 找不找得到,是 1Shop 根本不會把我貼在「全網站」的程式碼載入到獨立銷售頁。

三個解法:

解法 優點 缺點
A. 把獨立銷售頁加入官網 一鍵解決,程式碼不用改 金流、物流、優惠會被官網覆蓋
B. 每個獨立銷售頁各自貼程式碼 不影響原本設定 維護麻煩,改版要改 N 次
C. 分類按鈕只連官網銷售頁 程式碼最簡單 客戶可能想連獨立銷售頁

我最後跟客戶溝通,他們建立這些獨立銷售頁的本意就是給官網分類用,只是沒勾「加入官網」。所以走方案 A,客戶在後台勾個勾,全部搞定。

收穫與檢討

這次案子的技術面其實不難,卡關的都是平台知識的坑。反省一下:

🐾 下次接案前會先做的事

🐾 技術層面學到的事

🎯
一句話結論 接 1Shop 客製化之前,先搞清楚客戶的銷售頁有沒有「加入官網」。這個設定決定了你的所有程式碼策略。

寫在最後

如果你也在做 1Shop 的客製化,或你是 1Shop 的店家想優化網站體驗,歡迎聯絡我聊聊。這次的踩坑經驗之後會整理成一份標準化的 1Shop 客製化方案,適合需要首頁按鈕、分類選單、全站 UI 調整的店家。

畢竟踩過的坑,不做第二次就是賺到嘛。

← 回文章列表 聊聊你的案子 →

你的 1Shop 網站也想做客製化?

不論是首頁改版、分類選單、站內流程優化,或你遇到「某些頁面就是沒效」的怪問題,
都可以找我聊聊。一次搞懂,一次做對。

跟小柯聊聊 →