GUIDE  ·  2026  ·  DESIGN SYSTEM

20

26

Date 2026 / 05 / 25
Type AI 設計協作指南 · Part 4
Tools Claude Code · Google Sheets · Apps Script

2026

Real Data

設計概念串接真實商品資料——設計師工作指南

從 Wireframe IA 到 Google Sheets 資料建構,到 HTML 建置,到評審前資料更新—— 真實商品資料貫穿整個設計概念生命週期。 掌握這份工作地圖,不管面對多複雜的設計情境(包含 tab 切換、時段資料),你都知道從哪裡開始。

前言

設計概念裡的商品資料,不應該是假的

閱讀前提:這篇與前三篇的關係

AI 設計協作指南 Part 1–3 聚焦在 Figma 設計階段——如何寫 Brief 讓 Claude Code 在 Figma 裡建置設計,以及如何做 QA。 Part 4 覆蓋的是另一個工作情境:HTML 設計概念(design concept)。 這不是 Figma 建置的替代方案,而是在正式建 Figma 前,用 HTML prototype 做快速視覺探索的流程。 在 SHP 電商設計系統裡,這個 HTML 環境有一套串接真實商品資料的機制——這篇就是這套機制的完整說明。

這篇文章在整個設計流程的哪個位置

FIG.00 · 產品設計流程全覽

設計需求
Brief / 發想
設計概念 HTML
本篇 · Part 4
三方評選
選定方向
Figma 正式建置
Part 1–3
QA & 交付
工程師接手

本篇聚焦在「設計概念 HTML」這個階段——評選時讓所有人看到真實商品在不同版型下的樣子,才能做有根據的設計決策

什麼是「設計概念」?

在 SHP 設計系統的工作流程裡,設計概念(design concept)是指以 HTML + CSS 建立的可互動 prototype, 用於探索不同的頁面方向、驗證視覺構想、以及在正式 Figma 建置前讓相關人員評選。 它不是最終交付物,而是一個「快速低成本的思考工具」。

SHP 設計系統已預先建立了完整的元件庫(商品卡、導覽列、底部 Tab Bar 等)和資料串接機制—— 設計師不需要從零設計,只需要組合元件、定義版型,然後讓商品資料自動填入。 product-loader.js 就是這個資料串接機制的核心。 它負責讀取每日更新的 data/products.json, 並自動把商品資料渲染成設計系統規格的商品卡。

設計師在建立 prototype 時,最常見的做法是手動填入假商品名稱、隨便寫一個價格、 用佔位圖取代實際圖片。這個習慣在靜態設計稿沒有問題, 但在可互動的設計概念裡,它會造成兩個根本性問題:

視覺評估失真

假資料遮蔽真實排版問題

商品名稱長度不一,有的 8 個字,有的 30 個字。假資料通常是精心挑選過的「剛好合適」長度。真實資料才能暴露排版的邊界情況。

維護成本爆炸

每次更新要改兩個地方

商品資料每天都在變——價格調整、優惠券更新、新商品上架。假資料讓設計概念永遠滯後於真實狀態,每次 review 前都要手動更新一遍。

解決方案是讓設計概念直接讀取 data/products.json—— 這份資料每天由 Google Sheets + Apps Script 自動更新。 設計師只需要學會三條規則,就能讓自己的概念永遠顯示最新商品資料, 完全不需要手動維護。

3 核心規則
0 行 JS 需要手寫
概念自動更新
設計系統 真實商品資料 Claude Code 協作 SHP Design System
01

設計師的工作流程:四個階段

設計概念的真實資料串接,不是做完 HTML 再回頭補的工作,而是貫穿整個設計概念生命週期的四個階段。 清楚哪些事情只需要做一次、哪些需要每天重複,是這份工作的核心分工。

2 一次性設定階段
1 每日重複操作
三方評選交付

四個工作階段拆解

Wireframe IA 與資料規劃 設計決策

在 Wireframe 階段決定頁面的資訊架構——包含哪些模組、每個模組的商業邏輯、資料故事要說什麼。 同步在 Wireframe 標注上為每個商品模組決定 section 標籤代碼(例如「降價」、「相機」、「秒殺10點」)。 這些代碼後續會同時出現在 Google Sheets Staging 欄值和 HTML 的 data-filter 裡——先想清楚,後面執行才不會亂。

輸出:模組清單 + section 標籤代碼對照表。完整流程見 02 — 規劃階段

Google Sheets 資料建構 一次性設定

在 Google Sheets Staging tab 新增 section 欄位(欄位標題必須是英文 section,全小寫), 為每個商品填入對應的 section 標籤值。完成後執行 📤 匯出 JSON,更新本機 data/products.json

關鍵原則:Apps Script 強制重新匯入不會覆蓋 section 欄——這個設定只需要做一次,之後每日更新不會被清掉。 複雜情境(Tab 切換、時段資料)的資料建構方式見 03 — Google Sheets 情境指南

HTML 建置 一次性設定

引入 product-loader.js,為每個模組容器加上 data-apidata-filter="section:xxx"、 視需要加 data-maxdata-label。 在瀏覽器確認每個模組都正確載入預期數量的商品,排版在真實資料下沒有破版。

HTML 設定完成後即固定,不需要每天重新設定。三條核心規則見 05,data-filter 語法速查見 06

評審前資料更新 每日重複

每次想讓設計概念顯示最新商品資料(價格、優惠券、圖片): Apps Script 🔄 強制重新匯入全部 → 📤 匯出 JSON → 貼入本機 products.json → 瀏覽器 Cmd+Shift+R。 整個流程約 5–7 分鐘。

⚠️ 一定要用 🔄 強制重新匯入,而不是 📥 匯入——後者只處理 name 欄空白的商品,無法更新已有名稱的商品價格。

評選完成後的下一步

設計概念通過三方評選、選定方向後,進入 Figma 正式建置階段。 建置流程請參照 AI 設計協作指南 Part 1(Brief 撰寫)、Part 2(Figma 建置)、Part 3(品質確認)。 設計概念的工作到這裡結束——不同的工具、不同的精確度標準、相輔相成的兩個階段。

02

規劃階段:在 Wireframe 時就開始想資料

大多數設計師的習慣是:先把 HTML 建好,再回頭想要放什麼資料。這個順序是倒過來的。 資料規劃應該在 Wireframe IA 階段就完成——你在動手建 HTML 時,每個模組的資料需求已經清楚, 不需要中途停下來補;在 Google Sheets 裡準備好資料後,你可以在 HTML 建置同時就看到真實商品,立即確認排版沒有破版。

2-A 每個模組在問一個資料問題

設計概念裡的每個商品模組,都在對使用者說一個故事——「這些是最便宜的」、「這些是最近有降價的」、「這些是你可能喜歡的」。 在 Wireframe 的時候,你已經決定了每個模組的商業邏輯。 資料規劃就是把這個商業邏輯翻譯成 Google Sheets 能理解的語言。

每個商品容器在 Wireframe 階段只需要回答一個問題: 「這個模組的商品,在 Google Sheets 裡應該有什麼共同特徵?」 這個共同特徵就是你的 section 代碼——它是 Google Sheets Staging 欄值和 HTML data-filter 的共同語言。

2-B 從 Wireframe 標注到 section 代碼:三步驟

在 Wireframe 上標記每個商品容器的「資料意圖」

Wireframe 完成後,為每個商品容器加一個標注,說明它的商業語意。 不需要特別工具,Figma annotation、便利貼備注、或設計規格表都行。 重點是在視覺設計開始前,先確認每個模組的資料邏輯——而不是等 HTML 建好才想。

標注範例:「最新降價商品區」→ 資料意圖:近期售價下降的商品,預計 6–8 筆

列出模組清單,決定 section 標籤代碼

為設計概念的所有商品模組列一份清單,每個模組決定一個 section 代碼。 這個代碼之後要填進 Google Sheets 的 section 欄,也要寫進 HTML 的 data-filter——兩個地方的值必須完全一致,包含大小寫。

推薦用中文代碼(如 降價相機秒殺10點)——可讀性好,維護直覺。英文也可以,但選一種格式統一,不要混用。

確認「這個 section,哪些商品應該有它?數量夠嗎?」

有了 section 代碼後,想一下你能找到多少商品可以被標為這個代碼。 如果「相機精選」這個 section 在 Staging 裡只有 1 件商品,版面就會塌陷——及早在 Wireframe 階段發現,調整設計或更換商品,比 HTML 建好才發現便宜得多。

特別是 tab 切換情境(如秒殺時時樂的 4 個時段 tab),每個 tab 至少需要 3–4 筆商品,共需準備 12–16 筆。 商品數量可行性要在 Wireframe 階段就確認。

2-C Wireframe 資料標注對照表(範例)

Wireframe 模組名稱 資料意圖 Section 代碼 預計商品數
最新降價 近期售價有調降的商品 降價 6–8 筆
相機精選 相機類別主力商品 相機 4 筆(+ data-max="4")
你可能會喜歡 AI 推薦 / 個人化商品 推薦 6 筆(+ data-max="6")
秒殺 10:00 時段 早上 10 點的限時特賣商品 秒殺10點 4 筆 / tab,共 4 tab = 16 筆

什麼時候開始動 Google Sheets?

Wireframe 完成、模組清單確認、section 代碼決定——這三件事完成後,就可以開始動 Google Sheets。 不需要等 HTML 建好,不需要等設計稿定稿。 Google Sheets 的資料準備越早完成,你在建 HTML 時就能即時看到真實商品的排版效果,減少後期的 debug 循環。

特別是複雜情境(Tab 切換、時段資料),資料結構一定要在 Google Sheets 裡先跑通,再寫 HTML—— 否則你很容易建了一整套 tab UI,最後才發現資料根本無法支撐這個設計,白費時間。

TEMPLATE  ·  CSV

Google Sheets Staging 範本

新專案直接取用 · 不需要從空白欄位開始建

範本包含

  • 標準 12 欄 Staging 結構(source_url, name, price, tag1/tag2, section…)
  • 6 筆範例商品資料,涵蓋相機、耳機、降價、秒殺時段等 section 分類示範
  • 6 列空白商品列,貼入 Yahoo 商品網址後執行 Apps Script 即可匯入
↓ 下載範本 CSV 匯入 Google Sheets 即可使用

三步驟
快速開始

1

下載 CSV → Google Sheets 新建試算表 → 選單「檔案 → 匯入」→ 上傳 CSV

2

替換 source_url 欄為你的 Yahoo 商品網址,section 欄填入你的模組代碼

3

安裝 Apps Script → 執行 🔄 強制重新匯入 → 商品資料自動填入 → 📤 匯出 JSON

設定

Apps Script 安裝設定:新專案一次完成

Google Sheets + Apps Script 的組合是這套工作流程的核心。 Apps Script 負責從 Yahoo 商品頁面抓取資料、填入 Staging 工作表、以及匯出 products.json—— 這些工作完全自動完成,設計師只需要在最初做一次設定,之後每天執行幾個選單指令即可。 這個章節帶你在 15 分鐘內完成設定。

1 次安裝,永久有效
5 步驟完成設定
~15 分鐘(含授權)

開始前確認

已完成:已下載 Staging 範本 CSV(見上方 Section 02 的下載區塊)。
需要:一個 Google 帳號,以及 Google Sheets 和 Apps Script 的基本存取權限。
不需要:寫程式的能力。整個安裝流程只需要複製貼上和點按幾個確認按鈕。

步驟 1 / 5 建立 Google Sheets 並匯入範本

新建 Google 試算表

前往 sheets.google.com → 點「+」建立空白試算表 → 把試算表名稱改成你的專案名稱(例如「SHP 電商首頁概念 2026-06」)。 試算表名稱不影響功能,只是方便你之後找到它。

匯入 CSV 範本

選單 檔案 → 匯入 → 上傳 → 選擇你下載的 shp-staging-template.csv

匯入設定請選:
• 匯入位置:取代試算表
• 分隔符號類型:逗號
• 將文字轉換為數字、日期和公式:(避免價格被誤轉)

點「匯入資料」完成。

確認工作表名稱是「Staging」

畫面底部的工作表標籤應該顯示「Staging」。 這個名稱非常重要——Apps Script 靠它識別工作表,名稱不對就找不到資料。

如果顯示的是「工作表1」或其他名稱:右鍵點工作表標籤 → 重新命名 → 輸入 Staging(注意大寫 S)。

步驟 2 / 5 開啟 Apps Script 編輯器

開啟 Apps Script

在 Google Sheets 選單點 擴充功能 → Apps Script。 瀏覽器會在新分頁開啟 Apps Script 編輯器。

如果找不到「擴充功能」選單,確認你已登入 Google 帳號,以及試算表是「我的雲端硬碟」裡的檔案(不是他人分享的唯讀連結)。

清空預設程式碼

編輯器裡預設會有一段 function myFunction() {} 的空函數。 全選(Ctrl/Cmd+A)→ 刪除,把整個編輯區清空, 準備貼入完整的 SHP 商品管理程式碼。

步驟 3 / 5 貼入程式碼並儲存

APPS SCRIPT  ·  .JS

SHP 商品管理程式碼

完整可用的 Apps Script · 複製貼入即可執行

程式碼包含

  • 自訂選單建立(📥 匯入 / 🔄 強制重新匯入 / 📤 匯出 JSON)
  • 從 Yahoo 商品頁面自動抓取資料的解析邏輯
  • 強制重新匯入時保留 section 欄不覆蓋的保護機制
  • 匯出至 _JSON_Export 工作表並顯示下一步提示
↓ 下載程式碼 .js 複製全部 → 貼入編輯器

貼入
步驟

1

開啟下載的 .js 檔案 → Ctrl/Cmd+A 全選 → Ctrl/Cmd+C 複製全部內容

2

回到 Apps Script 編輯器 → 點編輯區 → Ctrl/Cmd+V 貼上

3

Ctrl/Cmd+S 儲存 → 確認左上角出現「已儲存變更」(可改名稱為「SHP 商品管理」)

貼入後,你應該會看到編輯器左側的函數清單出現 onOpenimportNewProductsforceReimportAllexportProductsJson 等函數。 如果編輯器顯示紅色錯誤標示,通常是貼入時有多餘空白或 BOM 字元——重新全選刪除再貼一次即可。

步驟 4 / 5 執行授權

Apps Script 需要你的授權才能存取 Google Sheets 和外部網路(用來抓取 Yahoo 商品資料)。 這個授權只需要做一次,之後每次使用不需要重複。 以下是詳細的授權步驟——Google 的授權介面設計比較繞,請按照步驟操作:

選擇 onOpen 並執行

在編輯器頂部的函數下拉選單(預設顯示「選取函式」), 選擇 onOpen。 點選左側的 ▶ 執行 按鈕。

點「查看權限」開始授權

系統會彈出「需要授權」對話框 → 點 「查看權限」。 接著選擇你的 Google 帳號(即擁有這份試算表的帳號)。

通過「Google 尚未驗證」警告

Google 會顯示「Google 尚未驗證這個應用程式」的警告頁面。 這是正常的——你自己寫的 Script 都會出現這個畫面,不代表程式有問題。

點左下角的 「進階」 展開隱藏選項 → 點 「前往 SHP 商品管理(不安全)」(名稱取決於你的專案名稱)。

點「允許」完成授權

確認權限要求頁面(會列出 Apps Script 需要的權限: 存取試算表、以你的身份連接外部服務)→ 點 「允許」

授權完成後,畫面會回到 Apps Script 編輯器, 底部執行紀錄應顯示「執行完成」。

步驟 5 / 5 確認選單出現

回到 Google Sheets 並重新整理

切回 Google Sheets 的分頁 → 按 Cmd+R(或 F5)重新整理頁面。 授權完成後,onOpen() 函數才會在頁面載入時執行,建立選單。

確認「商品管理」選單

重新整理後,頂部選單列應該出現 「商品管理」 選項。 點開確認有三個指令:
• 📥 匯入商品資料(只補空白名稱)
• 🔄 強制重新匯入全部
• ─────────────
• 📤 匯出商品 JSON

出現這三個選項代表安裝完成。

三個選單指令:什麼時候用哪個

📥

匯入商品資料(只補空白名稱)

掃描 Staging 工作表,只抓取 name 欄為空白的列。 用途:新專案剛貼入 source_url 後,第一次把商品資料填進來。
不適合:更新已有名稱的商品價格——那些列會被跳過,不會更新。

🔄

強制重新匯入全部

重新抓取所有有 source_url 的列,不管 name 欄有沒有值。 section 欄的值不會被覆蓋。

用途:每次想更新最新商品資料前(評審前、每日更新)一律用這個。 一次抓取多筆商品需要 1–5 分鐘,抓取中請勿關閉瀏覽器。

📤

匯出商品 JSON

把 Staging 工作表的所有有效商品資料轉成 JSON 格式, 寫入 _JSON_Export 工作表的 A1 儲存格。

用途:每次強制重新匯入後都要執行一次,然後把 A1 的內容複製貼入本機 data/products.json

安裝完成驗收

安裝驗收清單
工作表標籤名稱是「Staging」(S 大寫,非 Sheet1 / 工作表1)
必要
標題列欄位包含 source_urlnamesection(全小寫)
必要
Google Sheets 頂部出現「商品管理」選單
必要
商品管理選單裡有三個指令(📥 匯入 / 🔄 強制重新匯入 / 📤 匯出 JSON)
必要
將一個 Yahoo 商品網址填入 source_url 欄 → 執行 📥 匯入 → 確認 name 欄被自動填入商品名稱
執行 📤 匯出 JSON → 確認 _JSON_Export 工作表 A1 出現 JSON 格式資料

常見問題

「商品管理」選單沒出現:確認授權有完成(回 Apps Script 執行 onOpen 看有無報錯) → 重新整理 Google Sheets 頁面。

授權時找不到「進階」按鈕:往下捲動警告頁面,「進階」通常在頁面底部。不同瀏覽器介面略有不同。

執行時出現「找不到 Staging 工作表」:確認工作表標籤名稱完全正確(Staging,S 大寫,不是 stagingSTAGING)。

匯入後 name 欄仍是空白:確認 source_url 是完整的 Yahoo 商品網址(以 https://tw.buy.yahoo.com 開頭),商品尚在架。可打開 Apps Script → 查看「執行記錄」取得詳細錯誤訊息。

抓取速度很慢或中途失敗:Apps Script 每次抓取有 6 分鐘的執行時間上限。一次匯入不要超過 15–20 筆,可以分批執行。

03

Google Sheets 資料建構:從情境到執行

section 欄位是設計師在 Google Sheets 裡的「分類語言」——你決定哪些商品屬於哪個模組, products.json 忠實記錄這些分類,HTML 按照分類篩選顯示。 無論面對多複雜的設計概念,都能用這個機制找到對應的資料建構方式。

新專案?從範本開始,不要從空白開始

每次新專案都要從空白 Google Sheets 手動建欄位很浪費時間。 下載 Staging 範本 CSV ↓—— 匯入後欄位結構即完整,6 筆範例資料涵蓋 section 分類示範(相機、降價、秒殺時段等)。 替換 source_url、調整 section 欄值,執行 Apps Script 即可開始。

第一次建立 section 欄位的設定步驟請看下方 3-A。

3-A 第一次使用:在 Staging 建立 section 欄位

在 Staging tab 標題列找一個空白欄,填入欄位名稱

欄位標題輸入 section(全英文小寫)。 不能改成中文「模組」或其他名稱——這個名稱直接對應 products.json 的 key,系統要靠它識別欄位。 位置在哪一欄都可以。這個步驟只需要做一次。

為每件商品填入 section 標籤值

對應你的 Wireframe 模組清單,為每件商品填入對應的 section 代碼。 一件商品可同時屬於多個 section,用逗號分隔(不加空格):降價,推薦。 不屬於任何設計概念模組的商品,section 欄留空。

⚠️ Apps Script 🔄 強制重新匯入不會覆蓋 section 欄——設定一次後,每日資料更新都不需要重填。

執行 📤 匯出 JSON,更新本機 data/products.json

商品管理 → 📤 匯出商品 JSON → 開啟 _JSON_Export 工作表 → 點 A1 → 全選複製 → 貼入本機 data/products.json(完整取代整個檔案)。 section 欄的值會自動包含在每筆商品資料裡,例如 "section": "相機,降價"

「section 欄是 Apps Script 不會碰的地方。
它是設計師的分類語言,只有設計師決定它的值。」

情境 A — 基礎多模組:同頁三個垂直商品區

最常見的設計概念場景:同一頁面有多個垂直排列的商品區塊,每個區塊顯示不同語意的商品。 這是 section 機制最直接的應用,也是所有設計師最先需要掌握的情境。

商品 Staging section 欄值 出現在哪個模組
FUJIFILM X-HF1 相機,推薦 相機精選 + 你可能會喜歡(兩個模組同時出現)
SONY RX100VII 相機,降價 相機精選 + 最新降價
Sony WH-1000XM5 推薦 你可能會喜歡
LG 4K 電視 降價 最新降價

情境 A — HTML 結構(三模組,各自 section 篩選)

<div data-api="../data/products.json"
     data-filter="section:降價"
     data-label="最新降價"></div>

<div data-api="../data/products.json"
     data-filter="section:相機"
     data-max="4"
     data-label="相機精選"></div>

<div data-api="../data/products.json"
     data-filter="section:推薦"
     data-max="6"
     data-label="你可能會喜歡"></div>

情境 B — 複雜情境:秒殺時時樂(Tab 切換 × 時段資料)

電商首頁的「秒殺時時樂」模組有 4 個橫向 tab,對應一天內 4 個不同時段的特賣商品(10:00、12:00、14:00、18:00)。 使用者點擊 tab 可以瀏覽不同時段的優惠,商品內容每天早上 10 點更新。 這個複雜互動在設計概念裡要如何處理?

設計概念的「資料誠實」原則

設計概念不需要呈現真實的時間觸發邏輯(10 點時才顯示 10 點的商品,14 點後才開放 14 點 tab)。 你的目標是讓評審看到:每個 tab 的商品樣貌是什麼、tab 切換的互動感、時段標籤的視覺呈現。 真實的時間觸發是工程師在正式上線時實作的——設計概念只需要靜態地呈現「每個 tab 是什麼樣子」。

因此,你需要為每個 tab 準備一組代表性商品:每組 3–4 筆,4 個時段共需 12–16 筆商品(分別標入不同 section 代碼)。

Google Sheets 建構方式:為每個時段 tab 建立一個獨立的 section 代碼。 每件商品通常只屬於一個時段(除非同一商品確實在多個時段出現,再用逗號分隔)。

Tab 名稱 Section 代碼 所需商品數 設計代表的商業邏輯
10:00 時段 秒殺10點 4 筆 早間限時特賣
12:00 時段 秒殺12點 4 筆 午間限時特賣
14:00 時段 秒殺14點 4 筆 下午限時特賣
18:00 時段 秒殺18點 4 筆 晚間限時特賣

情境 B 的 Staging 設定範例

商品名稱 section 欄值 說明
Apple Watch Ultra 秒殺10點 只出現在早間 tab
Dyson V15 吸塵器 秒殺12點 只出現在午間 tab
Sony WH-1000XM5 秒殺14點,降價 出現在下午 tab + 另一個降價模組
Samsung Galaxy S25 秒殺18點 只出現在晚間 tab

情境 B — HTML 結構(Tab UI + 各時段各自的 data-filter)

<!-- 秒殺時時樂:Tab 切換列 -->
<div class="flash-tabs">
  <button class="tab active" data-tab="tab-10">10:00</button>
  <button class="tab"        data-tab="tab-12">12:00</button>
  <button class="tab"        data-tab="tab-14">14:00</button>
  <button class="tab"        data-tab="tab-18">18:00</button>
</div>

<!-- 各時段商品容器:每個 panel 各自用 data-filter 載入對應 section -->
<div id="tab-10" class="tab-panel active">
  <div data-api="../data/products.json"
       data-filter="section:秒殺10點"
       data-max="4" data-label="秒殺10點"></div>
</div>
<div id="tab-12" class="tab-panel" hidden>
  <div data-api="../data/products.json"
       data-filter="section:秒殺12點"
       data-max="4" data-label="秒殺12點"></div>
</div>
<!-- 14點、18點 panel 結構相同,section 代碼對應替換 -->

Tab 切換的 JavaScript:設計概念允許的例外

Tab 切換的互動邏輯(點擊哪個 tab 就顯示對應 panel)需要幾行 JavaScript——這是 UI 互動邏輯,不是商品資料邏輯,所以被允許。

區分的原則很簡單:「控制哪個 panel 顯示」的 JS 是 UI 互動,可以寫;「控制商品資料如何載入」的 JS 禁止自己寫,交給 product-loader.js。

Tab 切換範例:document.querySelectorAll('.tab').forEach(btn => btn.addEventListener('click', () => { /* show/hide panels */ }))

Do & Don't — 複雜情境資料規劃原則

✓ Do

先確認每個 tab 都有足夠商品再動手

4 個 tab × 4 筆商品 = 至少需要 16 筆商品標入各時段 section。先在 Staging 確認數量可行,再開始建 HTML tab UI。

✕ Don't

同一批商品重複標入所有時段

為了讓每個 tab 有商品,把同樣 4 件商品同時標成 秒殺10點,秒殺12點,秒殺14點,秒殺18點——4 個 tab 顯示一樣的商品,讓評審看不出 tab 切換的設計意義。

✓ Do

Tab 互動做靜態切換就夠了

設計概念的 tab 只需要「點哪個就顯示哪個 panel」。評審不需要看到「10 點前 tab 要 disabled」這種時間邏輯——那是工程師的工作,設計概念不需要這個精確度。

✕ Don't

花時間實作時間觸發邏輯

在設計概念 JS 裡寫「10 點之後才能點這個 tab」——這是正式上線的功能實作,不是設計概念的工作範圍,花時間寫這個等於在錯誤的地方投資。

✓ Do

每次評審前做一次每日更新

section 標籤設定好後,每天評審前用 🔄 強制重新匯入更新商品資料,tab 裡的商品就是最新的價格和優惠——不需要修改任何 HTML。

✕ Don't

資料不夠就在 HTML 硬編碼商品

「Staging 裡 18 點時段商品不夠,我直接在 HTML 裡補幾筆假的」——一旦硬編碼,這個模組就永遠顯示假資料,評審無法對它的商業邏輯做有效判斷。資料不夠時,調整設計或多找商品,不是補假資料。

04

先搞懂這件事:資料從哪裡來?

在動手之前,先理解整個資料流。知道資料的來源和流向, 才知道設計師的工作邊界在哪裡——什麼需要你做,什麼已經有人負責。

FIG.01 · 商品資料流架構

Google Sheets
Staging tab
Apps Script
自動抓取
_JSON_Export
工作表 A1
data/products.json
本機檔案
examples/*.html
商品卡渲染

↑ 設計師只需要知道最後兩個節點:products.json 是資料來源,HTML 是使用端

從 Yahoo 商品頁面抓取到 Google Sheets,再匯出為 JSON 存到本機—— 這整個流程由 Apps Script 自動完成。設計師不需要碰這個流程, 只需要假設 data/products.json 永遠是最新的。

product-loader.js 是什麼?從哪裡來?

scripts/product-loader.js 是 SHP 設計系統的一部分, 已經預先存在於 codebase 的 scripts 目錄下。設計師不需要自己建立這個檔案,也不應該修改它。 你只需要在 HTML 裡引入它,它就會自動偵測頁面上有 data-api 屬性的容器, 讀取 products.json,並把商品卡渲染進去。

product-loader.js 內建了三個設計師不需要關心但需要知道的機制: stale-while-revalidate 快取(避免每次重整都重新 fetch)、 圖片載入失敗的 fallback(顯示 purple-50 背景 + 灰色 icon,不會出現破圖)、 以及資料格式驗證(JSON 格式錯誤時在 console 輸出警告而非靜默失敗)。

products.json 的欄位結構

欄位 說明 範例值
id 商品唯一識別碼 P001
name 商品名稱(從頁面 h1 擷取) Sony WH-1000XM5 無線降噪耳機
price 當前售價(純數字) 8990
original_price 原價(有折扣時顯示) 11900
image_url 商品主圖 URL https://…
rating 評分(最高 5.0) 4.8
reviews 評論數量 1,243
sales 月銷量文字 已售出 500+
tag1 / tag2 優惠券標籤(pink 或 red 前綴) pink:折 $200
category 商品分類 audio
section 模組分類標籤(設計師手動維護,逗號分隔多值) camera, price-drop
TEMPLATE  ·  CSV

Products 商品資料範本

對應 products.json 欄位 · 可直接匯入 Google Sheets

範本包含

  • 標準 12 欄結構(source_url, name, price, discount, promo, tag1/tag2, rating, sales, image_url, section)
  • 3 筆真實格式範例商品,涵蓋相機、太陽眼鏡、耳機等 section 示範
  • 空白商品列,貼入 Yahoo 商品網址後由 Apps Script 自動填入其餘欄位
↓ 下載 Products CSV 對應 products.json 欄位結構

使用
方式

1

下載 CSV → Google Sheets 新建試算表 → 「檔案 → 匯入 → 上傳」

2

source_url 欄替換為你的 Yahoo 商品網址,section 欄填入模組代碼

3

執行 Apps Script 🔄 強制重新匯入 → 📤 匯出 JSON → 貼入本機 data/products.json

05

三條核心規則:背起來,少出錯

這三條規則是這份工作流程的核心。違反任何一條, 要嘛會造成資料不更新,要嘛會讓多個概念的行為不一致,要嘛會在 code review 時被退件。

「三條規則的核心邏輯只有一個:
讓 product-loader.js 做它該做的事,不要跟它搶工作。」

R1

一律引入 product-loader.js,禁止重新實作載入邏輯

所有設計概念一律在 <head> 或 body 底部加上這行: <script src="../scripts/product-loader.js"></script>禁止自己重寫 buildCard()、快取邏輯、或 fetch 載入機制。 product-loader.js 已經處理了 stale-while-revalidate 快取、錯誤處理、圖片 fallback—— 你重寫一遍只會比它差,而且每次更新都要同步修改兩個地方。

R2

商品容器只加 data-api 屬性,不寫任何 JS

商品卡的容器元素只需要一個屬性:data-api="../data/products.json"。 product-loader.js 會自動偵測這個屬性、讀取資料、渲染商品卡。 不需要、也不應該在 HTML 裡寫任何 JavaScript 來控制商品載入。 如果你發現自己在 HTML 裡寫 fetch()buildCard(),代表你走錯了路。

R3

禁止在 HTML 內硬編碼任何商品資料

商品名稱、價格、圖片 URL、標籤文字——這些全部禁止硬寫在 HTML 裡。 一旦硬編碼,你的概念就永遠卡在那個時間點的資料。 商品下架、價格調整、圖片更新,你的 prototype 都不會知道。 評審時看到的就是一份「說謊」的設計概念。

正確的 HTML 結構

正確示範 — 只需要這樣

<!-- 1. 引入 loader(一次,通常在 body 底部)-->
<script src="../scripts/product-loader.js"></script>

<!-- 2. 商品容器只加 data-api 屬性 -->
<div class="product-grid"
     data-api="../data/products.json">
  <!-- product-loader.js 會自動填入商品卡 -->
</div>
06

data-filter 與 data-max:語法速查

product-loader.js 透過兩個獨立屬性讓你控制每個模組的顯示內容: data-filter 負責篩選哪些商品, data-max 負責限制顯示數量。 兩個屬性分開寫、分開管——沒有 sort、category、has 等其他語法,也不要把數量寫進 data-filter。

使用情境 語法 說明
指定模組資料來源 data-filter="section:price-drop" 只顯示 section 欄位含有 price-drop 的商品
限制顯示數量 data-max="6" 最多顯示 6 筆(獨立屬性,不是寫在 data-filter 裡)
模組篩選 + 數量限制 data-filter="section:camera"
data-max="4"
相機模組,最多顯示 4 筆
AND 條件(同時符合) data-filter="section:camera section:price-drop" 同時帶有兩個 section 標籤的商品(空格分隔,兩條件都要符合)
不篩選(預設) 不加 data-filter 顯示 products.json 裡的所有商品

不存在的語法——請勿使用

以下語法不存在於 product-loader.js。寫了不會報錯,篩選條件會被靜默忽略,導致顯示全部商品:

data-filter="limit:4" → 數量要用獨立的 data-max="4"
data-filter="category:mobile" → 沒有 category 語法,要用 section
data-filter="has:discount" → 沒有 has: 語法
data-filter="sort:rating-desc" → 沒有 sort: 語法

data-filter + data-max 正確用法

<!-- ✅ 正確:section 篩選 + data-max 限制數量 -->
<div data-api="../data/products.json"
     data-filter="section:camera"
     data-max="4"></div>

<!-- ❌ 錯誤:limit 不可寫在 data-filter 內 -->
<div data-filter="section:camera,limit:4"></div>

<!-- AND 條件:空格分隔,同時符合兩個 section -->
<div data-api="../data/products.json"
     data-filter="section:camera section:price-drop"></div>

section 值從哪裡來?命名規則是什麼?

data-filter="section:xxx" 裡的 xxx, 對應 Google Sheets Staging tab 的 section 欄位值。 這個欄位由設計師手動維護——Apps Script 強制重新匯入時不會覆蓋它。

命名規則:欄位標題必須是英文 section(全小寫),這個名稱會直接成為 products.json 的 key,不能改成中文或其他名稱。 但欄位的值可以是中文(例如 降價相機推薦)——只要 HTML 的 data-filter 值與 Staging 欄值完全一致即可。 中文值對設計師來說可讀性更好,是日常作業的推薦方式。

下一章(04)說明完整的 Staging 設定流程與多模組設計概念的建置方式。

07

section 標籤:多模組資料指定

一個設計概念頁面通常不只有一個商品區塊。 首頁可能同時有「最新降價」、「相機精選」、「你可能會喜歡」三個模組, 每個模組需要不同的商品集合。 這一章說明如何在 Google Sheets Staging 建立 section 欄位, 讓 HTML 裡的每個模組都能精準指定自己的資料來源。

先搞清楚:哪些事只做一次,哪些事每天重複

多模組資料串接有兩類工作,性質完全不同,混淆了就會做重複的事或搞錯順序:

一次性(設定好後不需重做):
→ HTML 的 data-filter 屬性 — 設計概念完成後就不用動
→ Google Sheets Staging 的 section 欄填值 — Apps Script 強制重新匯入不會覆蓋這個欄

每日重複(每次想看最新商品資料都要做):
→ Apps Script 🔄 強制重新匯入 → 📤 匯出 JSON → 貼入本機 products.json → 瀏覽器 Cmd+Shift+R
這四步是每日例行,約 5–7 分鐘。

「一份 products.json,N 個模組——
section 欄位是設計師的分類語言,HTML 用它來聆聽。」

4-A 全流程架構:從 Staging 到頁面模組

多模組資料指定的全流程由三個環節組成: 設計師在 Google Sheets Staging 裡填入 section 標籤, 匯出後 section 值進入 products.json, HTML 的 data-filter="section:xxx" 再依此篩選。

FIG.02 · 多模組資料指定全流程

Staging
section 欄填入「camera」
📤 匯出 JSON
section 值進入 products.json
products.json
section: "camera,price-drop"
data-filter=
"section:camera"

同一份 products.json,不同模組各自用不同的 section 值篩選,互不干擾

4-B Google Sheets Staging:section 欄位設定步驟

section 欄位是設計師手動維護的標籤系統, 第一次使用前需要在 Staging tab 新增這個欄位。 Apps Script 的強制重新匯入不會覆蓋 section 欄位—— 設定一次,之後每次資料更新都不會被清掉。

在 Staging tab 新增 section 欄位(一次性設定)

在 Google Sheets Staging tab 的標題列找一個空白欄,輸入欄位標題 section(全英文小寫)。 欄位標題不能改成中文或其他名稱——這個名稱會直接成為 products.json 的 key,必須跟系統對得起來。 位置在哪一欄都可以。

這個步驟只需要做一次。之後 Apps Script 強制重新匯入時,section 欄的值不會被覆蓋——這正是 section 欄的設計意圖:讓設計師有一個 Apps Script 不會碰的自訂分類空間。

為每個商品填入 section 標籤值

決定每個商品屬於哪個設計概念模組,在 section 欄填入對應的標籤值。值可以是中文,推薦用中文——可讀性好,設計師日常維護更直覺。

單一模組:直接填入,例如 相機降價
屬於多個模組:逗號分隔(不加空格),例如 相機,降價
不屬於任何模組:留空即可,不影響其他商品

填入範例:FUJIFILM X-HF1 → 相機,推薦 SONY RX100VII → 相機,降價

匯出 JSON(section 值會一起帶出)

section 欄填完後,執行正常的匯出流程: 商品管理 → 📤 匯出商品 JSON → 複製 _JSON_Export A1 內容 → 貼入本機 data/products.json。 section 欄的值會自動包含在每筆商品資料裡,例如: "section": "camera,price-drop"

在 HTML 用 data-filter="section:xxx" 篩選

products.json 更新後,HTML 裡的 data-filter="section:camera" 就能正確篩選出有 camera 標籤的商品。 product-loader.js 使用包含比對(contains)—— section 值為 camera,price-drop 的商品,用 section:camera 篩選時也會被篩到。

Staging section 欄值 會被哪些 data-filter 篩到 說明
camera section:camera 只屬於 camera 模組
camera,price-drop section:camerasection:price-drop、AND 條件 section:camera section:price-drop 同時屬於兩個模組
(空白) 任何 section 篩選都篩不到 沒有 section 標籤的商品只出現在無 data-filter 的全量容器

4-C 多模組設計概念 — 完整程式碼範例

正確示範 — 一頁三模組,各自指定 section(中文值)

<!-- ① 引入 loader(一次即可,放在 body 底部)-->
<script src="../scripts/product-loader.js"></script>

<!-- ② 模組 A:最新降價(Staging section 欄填「降價」)-->
<section class="section-price-drop">
  <h2>最新降價</h2>
  <div class="product-grid"
       data-api="../data/products.json"
       data-filter="section:降價"
       data-label="最新降價"></div>
</section>

<!-- ③ 模組 B:相機精選(Staging section 欄填「相機」,最多 4 筆)-->
<section class="section-camera">
  <h2>相機精選</h2>
  <div class="product-grid"
       data-api="../data/products.json"
       data-filter="section:相機"
       data-max="4"
       data-label="相機精選"></div>
</section>

<!-- ④ 模組 C:你可能會喜歡(Staging section 欄填「推薦」,最多 6 筆)-->
<section class="section-recommended">
  <h2>你可能會喜歡</h2>
  <div class="product-grid"
       data-api="../data/products.json"
       data-filter="section:推薦"
       data-max="6"
       data-label="你可能會喜歡"></div>
</section>

<!-- 📌 Staging section 欄對應填入:  -->
<!--    FUJIFILM X-HF1    → 相機,推薦     -->
<!--    SONY RX100VII     → 相機,降價     -->
<!--    某款耳機         → 推薦          -->

兩個獨立 JSON 的情境(邊界案例)

絕大多數設計概念只需要一份 products.json。 只有商品真的來自兩個完全不同的資料來源時(例如不同 BU 各自維護的 Google Sheets),才需要用兩個 data-api:

<div data-api="../data/products-camera.json" data-filter="section:camera"></div>
<div data-api="../data/products-glasses.json" data-filter="section:sunglasses"></div>

如果只是想分模組顯示,用同一份 JSON + 不同 section 標籤就夠了。 不要為了分模組而分 JSON 檔——那會讓匯出和維護的成本翻倍。

4-D 多模組頁面的建置流程

多模組頁面最常見的失敗模式:HTML 都寫好了,才發現某個模組因為 Staging 的 section 欄是空的而沒有資料。 正確的流程是先完成兩件一次性的工作(決定 section 標籤代碼、在 Staging 填入值),再寫 HTML 的 data-filter——資料先行,HTML 跟上。

定義模組與 section 標籤代碼(動手前)

列出設計概念的所有模組,為每個模組決定一個 section 標籤代碼。 例如:最新降價 → price-drop、相機精選 → camera、你可能會喜歡 → recommended

標籤代碼建議用英文小寫加連字號,語意清晰即可。中文也可以,但 Staging 欄值和 HTML data-filter 值必須完全一致(包含大小寫)。

在 Staging 填入 section 值並匯出 JSON(動手前)

打開 Google Sheets Staging tab,確認 section 欄位已存在(第一次使用需要手動新增欄)。 為每個商品填入對應的 section 值,執行 📤 匯出 JSON,更新本機 data/products.json。

⚠️ 最常踩到的坑:忘了更新 products.json,導致 HTML 篩不到任何資料。先完成這個步驟,才能確認 data-filter 寫對了。

寫 HTML:data-filter + data-max + data-label

Staging 資料確認後,在每個模組容器加上對應的 data-filter="section:xxx"、 視需要加 data-max 限制數量, 以及 data-label 標示模組名稱(方便 console debug)。

真實資料驗證(建置後)

在 browser 開 DevTools,確認每個模組都正確載入了預期數量的商品。 如果某個模組顯示 0 筆,先檢查 Staging 的 section 欄是否已填值並重新匯出 JSON,再排查 HTML 語法。 空白模組在評審時會造成版面塌陷,及早發現及早修正。

4-E 多模組資料指定的設計原則

P1

section 標籤代碼反映模組的語意,而非技術的方便

標籤代碼是設計師和資料之間的語言。 用 price-drop 而不是 module1; 用 recommended 而不是 test好的標籤代碼讓六個月後的你看到 data-filter 就知道這個模組在幹嘛,不需要翻文件。

P2

section 欄先填,HTML 後寫——資料先行

在 Staging 填完 section 值並更新 products.json 之後,再動手寫 HTML 的 data-filter。 反過來先寫 HTML 後填 Staging,會導致在本機看不到商品、無法即時驗證, 然後花時間排查「為什麼空白」。 正確的順序節省 90% 的 debug 時間。

P3

不同模組的 section 標籤應有明確差異

如果「今日推薦」和「你可能會喜歡」兩個模組用了相同的 section 值, 它們就會顯示一模一樣的商品——兩個模組存在的理由就消失了。 每個模組應有獨立的 section 標籤,代表獨立的商業邏輯和使用者價值。

P4

一份 JSON,多個 section——不要為了分模組而分 JSON 檔

多模組設計概念不需要多份 JSON 檔。 section 欄位的設計目的就是讓一份 products.json 服務多個模組。 只有商品真的來自兩個完全不同資料來源時,才需要用兩個 data-api。 分 JSON 只會增加匯出次數和維護負擔。

4-F Do & Don't

✓ Do

先在 Staging 填 section 值,再寫 HTML

資料先行。確認 Staging 有值、products.json 已更新後,再寫 data-filter——每個模組都能立即看到真實商品,省下反覆 debug 的時間。

✕ Don't

data-filter 寫好了才想到 section 欄是空的

HTML 都寫完了,打開瀏覽器全部空白,才去 Staging 補 section 值。這個順序會讓你的開發驗證循環多繞一圈,浪費時間。

✓ Do

一個商品可屬於多個 section

一件商品同時屬於「降價」和「相機」兩個模組?在 section 欄填 price-drop,camera。它就會同時出現在兩個模組的篩選結果,不需要重複建資料。

✕ Don't

把 limit 寫進 data-filter

data-filter="section:camera,limit:4" 是錯的。limit 不是 data-filter 的一部分,要改用獨立的 data-max="4" 屬性。

✓ Do

多模組頁面一律加 data-label

每個容器加 data-label="模組名稱",console log 載入訊息會帶上模組名稱。多模組 debug 時,一眼就知道哪個容器出問題。

✕ Don't

為了讓評審好看而把不相關商品標入 section

真實商品數量不夠,就把不相關的商品也標成這個 section 讓畫面填滿——這讓設計概念的資料故事失去意義。真實資料不夠時,調整模組設計,不是調整資料。

08

常見錯誤與禁區:這些坑前人都踩過

以下是在 code review 和設計概念 QA 中反覆出現的錯誤。 每一條都有真實的背景——不是為了限制你,而是因為這些做法在實際運作時會出問題。

重寫 buildCard()——「我覺得我的版本更好」

最常見的錯誤。設計師複製 product-loader.js 裡的 buildCard() 邏輯,在自己的 HTML 裡修改。 問題:product-loader.js 更新時,你的版本不會自動跟著更新。商品卡的 DOM 結構、class 名稱、 fallback 邏輯一旦分叉,之後的維護就是兩條平行線。 正確做法:用 CSS 覆寫樣式,不要碰 JS 邏輯。

用 <script> 手寫商品陣列——「測試用的」

在 HTML 裡宣告一個 JavaScript 陣列存放假商品資料,然後用 for loop 渲染。 問題:「測試用」的假資料最後往往留在 prototype 裡被拿去評審。 評審看到的價格、圖片、標籤全是你寫死的,不反映真實商品狀態。 正確做法:直接用 data-api + products.json,沒有「測試版」和「正式版」之分。

把 product-loader.js 的路徑寫錯

src="scripts/product-loader.js"(少了 ../)是最常出現的 typo。 問題:載入失敗但瀏覽器不一定顯示明顯錯誤,容器會空白,設計師以為是資料問題去查 JSON,繞了一大圈。 正確路徑:確認你的 HTML 在 examples/ 目錄下,路徑應為 ../scripts/product-loader.js

用 file:// 直接開 HTML——「雙擊就能看」

瀏覽器的安全限制讓 file:// 協議下的 fetch() 呼叫失敗,商品資料完全讀不到。 問題:設計概念看起來正常(結構在),但商品卡是空的。 正確做法:一律用 python3 -m http.server 8088 啟動本地 server, 再從 http://localhost:8088 開啟。

在 product-card 之外自定義商品卡樣式

設計師認為 product-card 元件「不夠好看」,自己設計一套商品卡 HTML + CSS, 然後用 JS 填入資料。 問題:脫離設計系統的商品卡在跨 prototype 的比較評審中造成「這個方向怎麼商品卡長不一樣」的疑惑,評審焦點從設計概念的差異移到元件差異上。 正確做法:如需調整商品卡樣式,修改 components/product-card.css,讓改動對所有概念生效。

最根本的判斷原則

如果你在設計概念的 HTML 裡寫了任何與商品資料相關的 JavaScript,幾乎可以確定你走偏了。設計概念的 HTML 應該只有結構(HTML)和樣式(CSS),商品資料的一切邏輯都在 product-loader.js 裡。

09

每日更新流程:五步驟讓資料保持最新

products.json 不會自己更新——需要有人執行 Google Sheets 的匯出流程。 這個流程通常由負責商品管理的人執行,但設計師需要知道整個流程, 才能在「資料看起來不對」時知道問題在哪個環節。

1

確認 Staging tab 的 source_url

每列的 source_url 欄位必須是有效的 Yahoo 商品網址。如果某個商品已下架,這一列要移除或更換 URL,否則重新匯入時會失敗並產生空白資料。

2

選擇正確的匯入指令

更新現有商品(價格/標籤)→ 🔄 強制重新匯入全部(所有有 source_url 的列都重抓)。
新增商品(name 欄位空白)→ 📥 匯入商品資料。
⚠️ 最常見錯誤:用 📥 匯入試圖更新價格——它只處理 name 為空的列,有名稱的商品會被跳過。每日更新一律用 🔄 強制重新匯入。

3

目視確認 Staging 資料正確

重新匯入完成後,快速掃一眼 name、price、tag1、tag2 欄位是否正確。特別注意 tag1/tag2——Apps Script 只抓未登入狀態下可見的優惠券,個人化優惠不會出現(這是正常行為,不是 bug)。

4

匯出 JSON 並更新本機檔案

商品管理 → 📤 匯出商品 JSON → 開啟 _JSON_Export 工作表 → 點 A1 → 全選複製 → 貼入本機 data/products.json(完整取代整個檔案內容)。

5

強制重新整理瀏覽器確認更新生效

http://localhost:8088Cmd+Shift+R(強制重新整理)——這會清除 10 分鐘的 stale-while-revalidate 快取,確保看到最新資料。 普通的 Cmd+R 可能因為快取而仍顯示舊資料,如果更新後看起來沒有改變,先試試 Cmd+Shift+R

常見問題排查

商品卡是空白的:先確認 localhost 是否啟動(不是 file://)、product-loader.js 路徑是否正確、products.json 是否存在且格式正確。

資料沒有更新:兩個常見原因——① 用了 📥 匯入而非 🔄 強制重新匯入全部;② 瀏覽器快取未清除。先試 Cmd+Shift+R,若還是舊資料再確認匯入指令是否正確。

某個模組顯示空白:Staging 的 section 欄還沒填這個模組的值,或填完後忘了重新匯出 JSON 更新本機。

tag1/tag2 是空的:該商品目前沒有公開優惠券,這是正確行為。

10

完成前驗收清單:每次建立概念都跑一遍

這份清單是今天這個工作流程的濃縮版。 建立任何包含商品資料的設計概念前後,各跑一遍——前置確認資料正確, 完成後確認實作無誤。

建立前 — 資料確認
products.json 已是最新版本——若超過 24 小時未更新,重新執行 🔄 強制重新匯入(不是 📥 匯入)
必要
已確認設計概念所需的 section 值在 products.json 中有對應商品(開 JSON 搜尋 section 欄值)
本地 server 已啟動(python3 -m http.server 8088),不是用 file:// 開啟
必要
建立中 — 實作確認
product-loader.js 已引入,路徑為 ../scripts/product-loader.js
必要
所有商品容器已加 data-api="../data/products.json" 屬性
必要
HTML 中無任何硬編碼的商品名稱、價格、圖片 URL
必要
HTML 中無自定義的 buildCard() 或商品載入 JavaScript
必要
若有使用 data-filter,篩選條件語法正確,且對應資料存在
多模組頁面專屬確認(適用時)
Staging 的 section 欄位已填值,且已重新匯出並更新本機 data/products.json
必要
每個容器的 data-filter="section:xxx" 值與 Staging section 欄的值一致(拼寫、大小寫相符)
必要
數量限制使用 data-max 獨立屬性,而非 data-filter="limit:xxx"
必要
每個容器都加了 data-label 屬性,方便 console debug
不同模組的 section 標籤不同,顯示的商品集合有明顯差異
必要
每個模組在真實資料下都能載入預期數量的商品(無版面塌陷或商品數量不足)
必要
完成後 — 視覺確認
商品卡正常渲染,顯示真實商品名稱、價格、圖片
必要
商品名稱長度不一時,排版沒有破版(特別注意 30 字以上的長名稱)
必要
無圖片的商品顯示 purple-50 背景 + fallback icon,非空白或破圖
有優惠券的商品標籤顏色正確(pink/red 依 tag1/tag2 前綴)
Mobile / Tablet / Desktop 三個斷點都正常顯示

設計概念與 Figma 建置的分工

設計概念(HTML prototype)用於快速探索和評選方向,側重視覺組合的可能性,資料是真實的但實作是快速的。 Figma 建置用於精修後的正式設計,側重精確規格、元件品質、以及交付工程師的 Handoff 品質。

正確的流程是:先用設計概念探索 3–5 個方向 → 三方評選 → 選定方向後按照 Part 1(Brief Basics)的框架撰寫 Brief,進入 Figma 建置 → 建置過程中按照 Part 3(Quality Check)做品質確認。 設計概念的真實資料讓評選決策更可靠;Part 1–3 的流程讓 Figma 建置有系統可依循。兩個流程相輔相成,不互相取代。

「看完就能上手、不看就容易出錯——這是這份指南的設計目標。
真正的設計能力在於你為這些商品創造的體驗,而不是你如何取得這些商品的資料。」