ปัญหาที่เจอ
แบรนด์เสื้อผ้าลินินที่โตมาจาก Instagram อยากมีหน้าร้านที่ดูพรีเมียมและค้นหาง่ายกว่า feed — แต่ยังไม่พร้อมทำ e-commerce เต็มรูปแบบ
ลูกค้าเจอลุคสวยใน IG แต่พอจะสั่ง ต้องเลื่อน feed หากลับ ถามซ้ำว่ารุ่นไหน มีไซซ์อะไร สีอะไร ราคาเท่าไหร่ ของหมดยัง — แบรนด์ตอบเดิมทุกวัน ส่วนระบบตะกร้า/ตัดบัตร กลับหนักและเกินจำเป็นสำหรับการขายที่จบด้วยการ "คุยกันใน LINE" อยู่แล้ว
ขายผ่าน IG feed อย่างเดียว — หาสินค้าไม่เป็นระบบ
ลูกค้าต้องเลื่อน feed หาลุคที่เห็น ไม่มีหมวดหมู่ ไม่มีหน้าสินค้าเป็นเรื่องเป็นราว collection เก่าจมหายไปกับโพสต์ใหม่
ทักแชทถามซ้ำ ๆ ทุกวัน
ไซซ์ไหน สีอะไร เนื้อผ้าเป็นยังไง ราคาเท่าไหร่ ของหมดยัง — คำถามเดิมวนซ้ำ เพราะข้อมูลไม่ได้อยู่รวมที่เดียว แอดมินตอบมือจนล้า
ระบบตะกร้า/ตัดบัตร หนักและเกินจำเป็น
การขายจริงจบที่การคุยใน LINE อยู่แล้ว — checkout, payment gateway, ระบบสมาชิก กลายเป็นภาระที่ไม่ได้ใช้ และเพิ่มจุดที่ลูกค้าหลุด
อัปเดตสินค้าเองไม่ได้ ต้องรอ dev
เพิ่มสินค้าใหม่ แก้ราคา ปรับสถานะ "ของหมด" ทุกครั้งต้องจ้างคนแก้โค้ด — ทีมแบรนด์อยากคุมเนื้อหาเองแบบไม่ต้องแตะโค้ด
เทมเพลตสำเร็จรูปสวย แต่ผูกกับ commerce engine ของมันเอง
ดีไซน์ fashion template ที่ถูกใจ มากับระบบตะกร้า/สินค้าแบบตายตัว — เอามาต่อกับข้อมูลจริงและช่องทาง LINE ตรง ๆ ไม่ได้
วิธีแก้ปัญหา
ทำ catalog ให้เป็นระบบ + เปลี่ยน "ปุ่มสั่งซื้อ" ให้เป็น deep-link เข้าแชท ตัด checkout ทิ้ง แล้วให้แบรนด์คุมทุกอย่างจากหลังบ้าน
Catalog เป็นระบบ ค้นง่ายกว่า feed
สินค้าแยกหมวดหมู่ มีหน้า collection กรองตามหมวด มีสถานะ (พร้อมขาย/พรีออเดอร์/ของหมด) และป้าย badge — ลูกค้าหาลุคที่เห็นเจอใน 2-3 คลิก
Chat-to-Order: กดสั่ง → เด้ง LINE พร้อมข้อความ
เลือกสี+ไซซ์ ระบบประกอบเป็นข้อความสั่งซื้อ (ชื่อสินค้า + ตัวเลือกที่เลือก + ลิงก์) แล้ว deep-link เข้า LINE OA ของแบรนด์แบบ pre-filled — ลูกค้าแค่กดส่ง
ไม่มี checkout — เหลือแค่ "สอบถาม"
ตัด cart / payment / ระบบสมาชิกทิ้งทั้งหมด เหลือ inquiry flow อย่างเดียว — เบา เร็ว และตรงกับพฤติกรรมจริงที่ปิดการขายในแชท
Headless CMS — แบรนด์คุมเนื้อหาเอง
Payload CMS ในตัว ที่ /admin — เพิ่ม/แก้สินค้า ราคา สถานะ หมวดหมู่ รูป และแม้แต่ช่องทาง LINE/ข้อความตั้งต้น ได้เองแบบไม่ต้องแตะโค้ด
Rewire เทมเพลตสวย ให้ data-driven
เอา fashion template มาแยก HTML/CSS/JS ออก แล้ว "ฉีด" การ์ดสินค้าจริงจาก CMS เข้าไปแทน — เก็บดีไซน์และแอนิเมชันไว้ ทิ้ง commerce engine เดิม
วิธีทำงาน — 4 จังหวะ
ตั้งแต่เปิดเว็บ จนถึงข้อความสั่งซื้อเด้งเข้าแชท
Explore
เปิดเว็บดูคอลเลกชัน กรองตามหมวดหมู่ เห็นสถานะสินค้าแต่ละชิ้น
Consider
เข้าหน้าสินค้า ดูรูปหลายมุม ราคา เนื้อผ้า และรายละเอียด
เลือกสี / ไซซ์
กดเลือก variant ระบบประกอบข้อความสั่งซื้ออัตโนมัติ real-time
Inquire ผ่าน LINE
กดสั่งซื้อ → เด้งเข้า LINE พร้อมข้อความ pre-filled แค่กดส่ง
Tech Stack & Architecture
หน้าร้าน RSC-first + headless CMS + deep-link ออกแชท — ไม่มี payment layer
โจทย์ตั้งต้นคือ CMS แบบ WordPress — แต่เลือก Next.js 16 + Payload CMS 3 แทน เพราะ Payload ให้ admin UI ในตัว (ปรับ label เป็นภาษาไทยได้) พร้อม REST/GraphQL อัตโนมัติ และรันบน serverless เดียวกับหน้าร้าน · React Server Components ดึงข้อมูลตรงจาก DB ไม่ต้องมี API กลาง · PostgreSQL ให้ schema เป็นระเบียบ (auto-push ตอน dev) · ที่สำคัญ — ไม่มี payment layer เลย จุดปิดการขายคือ deep-link ออก LINE ทำให้ทั้งระบบเบาและ maintain ง่าย
สิ่งที่สร้าง — 8 ความสามารถหลัก
ครบ loop ตั้งแต่ catalog หลังบ้าน ถึงข้อความสั่งซื้อในแชท
Chat-to-Order Deep Link
ประกอบข้อความจาก template ({product}/{url}) แล้วสร้างลิงก์ line.me/R/oaMessage + Telegram พร้อม encode ปลอดภัย
Variant Picker → Message
เลือกสี/ไซซ์ (client component) → ต่อเป็น "ชื่อสินค้า (สี: …, ไซซ์: …)" เข้าข้อความสั่งซื้อทันทีแบบ real-time
Template Rewire Engine
อ่านหน้า fashion template มาแยก inline styles / body / scripts ตามลำดับ แล้ว cache ไว้ parse ครั้งเดียวใช้ซ้ำทุก request
Balanced-Tag DOM Transforms
ชุดฟังก์ชันแทนที่ inner HTML ของ element ตาม class/tab แบบนับ depth ของ tag คู่เปิด-ปิด — ฉีดข้อมูลจริงลง markup ที่ nest ลึกได้แม่น
Commerce Stripper
ตัด node ตะกร้า/add-to-cart (data-node-type) ออกจากเทมเพลตทั้งก้อน แล้วเสียบจุด mount ปุ่ม LINE/Telegram เข้าแทน
CMS Catalog
Products/Categories/Media — สถานะ, badge, สินค้าแนะนำ, ราคาก่อนลด, รูปหลายภาพ, slug auto จากชื่อ (hook beforeValidate)
Brand Settings Global
LINE OA / Telegram / Instagram / ข้อความสั่งซื้อตั้งต้น / รูป banner — แก้จากหลังบ้านทั้งหมด ไม่มีอะไร hardcode
Runtime Re-init
โหลด lib ของเทมเพลตครั้งเดียวต่อ session แล้ว re-fire reveal animation ทุกครั้งที่เปลี่ยนหน้า + safety net กัน element ค้างซ่อน
หน้าตา Product + Buy Panel
เลือกสี/ไซซ์ → ข้อความสั่งซื้อประกอบให้อัตโนมัติ → กดปุ่มเดียวเด้งเข้าแชท
Audrey Linen Midi Dress (สี: Sand, ไซซ์: M)
…/products/audrey-linen-midi-dress
งานออกแบบ UI & Design System
มองจากมุม Product Designer — วางระบบดีไซน์ lime-on-dark ที่คมและคอนทราสต์สูง แล้วออกแบบ flow ให้ลูกค้าเดินจาก "เห็นลุคที่ใช่" ไปถึง "ทักแชทสั่ง" ด้วยแรงเสียดทานน้อยที่สุด
--ln-*) — ดีไซน์แฟชั่นดาร์ก + accent สว่างจัด เพื่อให้สินค้าและปุ่มสั่งเด่นที่สุดAudrey Linen Midi Dress (สี: Sand, ไซซ์: M)
…/products/audrey-linen-midi-dress
ออกแบบจอ 393 ก่อน แล้วค่อยขยายไป 768 / 1440
ลูกค้าแฟชั่นเลื่อนดูจากมือถือเป็นหลัก — เลย์เอาต์ตั้งต้นเป็นกริดสินค้า 2 คอลัมน์ รูป aspect 3/4 และปุ่มสั่งซื้อเต็มความกว้าง จอใหญ่ค่อยขยายเป็น 3-4 คอลัมน์ ไม่ใช่ย่อ desktop ลงมา
Microcopy ประกอบข้อความสั่งซื้อให้ล่วงหน้า
แทนปุ่ม "หยิบใส่ตะกร้า" ด้วย "สั่งซื้อผ่าน LINE" ที่พาไปถึงบทสนทนาจริง พร้อมข้อความ pre-filled ("สนใจสั่งซื้อ… + ชื่อสินค้า + สี/ไซซ์ + ลิงก์") — ลูกค้าแค่กดส่ง ลด friction จาก "อยากได้" เหลือคลิกเดียว
Variant pill มี default / active / sold-out ชัดเจน
ปุ่มเลือกสี-ไซซ์ตัวที่เลือกเป็น lime ตัวหนัง (active) ตัวอื่นเป็นเส้นขอบจาง (default) — ต่างกันด้วยสีพื้น ไม่ใช่แค่เส้นขอบ ส่วนสถานะ "ของหมด" ยังกดทักแชทถามรอบหน้าได้ ไม่ปิดตาย
Lime-on-dark คอนทราสต์สูง + touch target ≥ 44px
ตัวหนังสือครีมและ accent lime บนพื้นดำ #0d0d0d ให้คอนทราสต์เกิน 4.5:1 สบาย ๆ (ผ่าน WCAG AA) ปุ่ม CTA จงใจใช้ตัวหนังสือดำบนพื้น lime ไม่ใช่ขาว และปุ่มสั่งซื้อสูง ~44px กดง่ายด้วยนิ้วโป้ง
Hack กับปัญหา
6 โจทย์ที่ต้องคิดทางแก้เอง — ระหว่างเอาเทมเพลตสำเร็จรูปมาเชื่อมกับข้อมูลจริง + ช่องทางแชท
เทมเพลตผูกกับ commerce — เอามาใช้กับข้อมูลจริงไม่ได้
markup ของเทมเพลตซ้อนกันลึกและมี node ตะกร้าฝังอยู่ — จะแทนที่การ์ดสินค้าด้วย regex ธรรมดามันจับ tag ปิดผิดตัวทันทีเมื่อมี <div> ซ้อน
<div> +1, </div> −1) หา inner ที่ถูกต้องแล้วค่อยแทน — ฉีดการ์ดจริง, ตัด commerce node, สลับ hero banner ได้แม่นแม้ markup nest ลึกแอนิเมชันของเทมเพลตไม่เล่นหลัง hydration
reveal animation ตั้ง element เป็น opacity:0 แล้วรอ event load — แต่เราฉีด script หลัง React hydrate (เลย load ไปแล้ว) พอเปลี่ยนหน้าแบบ SPA element เลยค้างซ่อนทั้งหน้า
load/readystatechange เอง — บวก safety net ที่กวาด reveal ทุก element ที่ยังซ่อนภายใน 1 วินาที กันพลาดข้อความมี emoji / ช่องว่าง / ขึ้นบรรทัดใหม่ → deep-link พัง
ข้อความสั่งซื้อมี emoji 🛍️ เว้นวรรค และ \n — เอาต่อท้าย URL ตรง ๆ ลิงก์ LINE/Telegram แตกทันที
encodeURIComponent() ก่อนประกอบเป็น deep-link + normalize prefix (@ ของ LINE, ตัด @ ของ Telegram) ให้แบรนด์กรอกแบบไหนก็ทำงานcommerce ของเทมเพลตยิง /api/cart ชนกับ CMS
runtime เดิมของเทมเพลตพยายาม fetch /api/... (ตะกร้า) ซึ่งชน endpoint /api ของ CMS → เด้ง error CSRF + alert "site unsecured" โผล่หน้าลูกค้า
window.alert กรองข้อความ cart/checkout/unsecured ทิ้ง + ดัก unhandledrejection/error ที่เป็น noise ของ commerce (CSRF, Failed to fetch) ให้เงียบ — เหลือแต่ flow จริงที่เราคุมหน้า dynamic re-parse ไฟล์ใหญ่ทุกครั้งที่เปิด
หน้าเป็น force-dynamic (ข้อมูลสด) แต่ต้องอ่าน + regex แกะไฟล์เทมเพลตหลักร้อย KB ทุก navigation — เปลืองและช้า
Map (in-memory) — ไฟล์เทมเพลตเป็น static design ที่ไม่เปลี่ยน parse ครั้งเดียวใช้ซ้ำ ส่วนข้อมูลสินค้ายังดึงสดจาก CMS ทุก request แยกกันชัดเจนโจทย์ขอ WordPress + คิดว่าต้องมี e-commerce
ความคาดหวังตั้งต้นคือ CMS แบบ WordPress พร้อมระบบตะกร้า — แต่การขายจริงจบในแชท ระบบ checkout จะกลายเป็น dead weight
Design Decision ที่ตั้งใจเลือก
ขอบเขตที่จงใจ "ไม่ทำ" สำคัญพอ ๆ กับสิ่งที่ทำ
เว็บนี้ทำหน้าที่เดียว: เป็น catalog ที่พาลูกค้าเข้าสู่บทสนทนาใน LINE ให้เร็วและเนียนที่สุด — มันไม่มีตะกร้า ไม่มี payment ไม่เก็บ order เอง จุดปิดการขายคือแชทของแบรนด์ ขอบเขตที่คมตั้งแต่ต้น = implement ตรง เบา และส่งมอบให้แบรนด์ดูแลต่อเองได้จริง
Chat-to-order ไม่มี checkout
ปิดการขายในแชท — เว็บแค่พาไปให้ถึงเร็วที่สุด
Rewire ไม่ rebuild
เก็บดีไซน์เทมเพลตไว้ ทิ้งแค่ commerce engine
CMS-first ไม่ hardcode
สินค้า/ช่องทาง/ข้อความ แก้จากหลังบ้านหมด
Deep-link ตรงถึงแบรนด์
เข้า LINE OA ของแบรนด์เอง ไม่มีตัวกลาง
Knowledge Domain ที่แข็งขึ้น
5 พื้นที่ความรู้ที่ระดับเราขยับขึ้นจริงจากการทำโปรเจกต์นี้
เข้าใจ pattern ของ non e-commerce ที่ปิดการขายผ่าน chat — การประกอบข้อความ pre-filled, deep-link เข้า LINE OA / Telegram, และ UX ที่ลด friction จาก "อยากได้" ถึง "ทักแชท" ให้เหลือคลิกเดียว บทเรียน: บางธุรกิจ "ตะกร้า" ไม่ใช่คำตอบ — บทสนทนาต่างหากที่ปิดการขาย
ออกแบบ collections/globals, ใช้ field hooks (beforeValidate สร้าง slug อัตโนมัติ), access control, และปรับ label/description ของ admin ให้ทีมแบรนด์ใช้เป็นภาษาไทย — เข้าใจว่า headless CMS ให้ทั้ง data model และ back-office ในตัวเดียว บทเรียน: ของดีสำหรับลูกค้า = แก้เนื้อหาเองได้โดยไม่ต้องเรียก dev
ฝึกแยก head styles / body / scripts จากหน้าเทมเพลต และเขียน transform ที่นับ depth ของ tag เปิด-ปิดเพื่อหา inner HTML ที่ถูกต้อง แทนการพึ่ง DOM library — เข้าใจว่าทำไม regex ธรรมดาแตกกับ markup ที่ nest บทเรียน: การแกะ HTML ให้ถูกต้องคือเรื่องของ balancing ไม่ใช่ pattern matching
เข้าใจ RSC + force-dynamic, การ inject runtime ภายนอก (jQuery/animation engine) เข้า React lifecycle ให้ทำงานถูกลำดับหลัง hydration และ client-side navigation รวมถึงการดัก error ของโค้ดที่เราไม่ได้เขียนเอง บทเรียน: การพา legacy runtime มาอยู่ในโลก React ต้องคุม lifecycle ให้ขาด
รับโจทย์ "WordPress + ระบบขาย" แล้วกลั่นเป็นสิ่งที่ลูกค้าต้องการจริง (catalog + แก้เองได้ + ปิดการขายในแชท) เลือก stack และ "ตัด" ฟีเจอร์ที่ไม่จำเป็นออก บทเรียน: หน้าที่ของเราไม่ใช่ทำตามคำขอทุกตัวอักษร แต่คือส่งมอบผลลัพธ์ที่ตอบโจทย์ด้วยความซับซ้อนที่น้อยที่สุด