Skip to content
Watchara NoisriphanAI Builder

พิมพ์เพื่อเริ่มค้นหา

ใช้งานอยู่

AI Builder OS — เว็บไซต์ส่วนตัวที่สร้างจาก spec เดียว

เว็บไซต์ส่วนตัวแบบ static ที่สร้างด้วย Astro โดยเขียน spec ให้ครบก่อนแล้วค่อยสร้างตามทีละเฟส ทุกหน้าเป็น HTML ที่ build ไว้ล่วงหน้า มีระบบค้นหา RSS sitemap และชุดทดสอบอัตโนมัติที่รันบน CI

ปัญหา
งานที่ทำและสิ่งที่เรียนรู้กระจายอยู่บนแพลตฟอร์มของคนอื่น ค้นย้อนหลังไม่ได้และไม่มีที่ที่เป็นของตัวเองจริง ๆ
วิธีแก้
เว็บไซต์ static ที่เก็บเนื้อหาเป็นไฟล์ Markdown ใน git มี schema บังคับความถูกต้องตั้งแต่ตอน build และ deploy อัตโนมัติจากการ push

เทคโนโลยีที่ใช้

  • Astro
  • TypeScript
  • Tailwind CSS
  • Markdown
  • Zod
  • Pagefind
  • Vitest
  • Playwright
  • GitHub Actions
  • Vercel

ผลลัพธ์

  • build ออกมาเป็นหน้า static 37 หน้าโดยไม่มี client-side framework (pnpm build ณ วันที่เขียน)
  • unit test 57 เคสใน 6 ไฟล์ ผ่านทั้งหมด (pnpm test)
  • end-to-end test 38 เคสใน 4 ไฟล์ รันทั้ง desktop และ mobile profile (pnpm exec playwright test --list)
  • Pagefind สร้าง search index ครอบคลุมทุกหน้าที่ build ในขั้นตอนเดียวกัน (log จาก pnpm build)

ปัญหาคืออะไร

งานที่ทำและบันทึกสิ่งที่เรียนรู้ระหว่างทางกระจายอยู่บนแพลตฟอร์มของคนอื่น — โพสต์บน social media, ข้อความในแชท, ไฟล์ในเครื่อง เมื่ออยากกลับไปหาว่าเคยแก้ปัญหาเรื่องหนึ่งไว้ อย่างไร ก็ค้นไม่เจอ และเนื้อหาเหล่านั้นก็ขึ้นอยู่กับว่าแพลตฟอร์มจะยังอยู่และยังแสดงผลให้ใคร เห็นหรือไม่

อีกด้านหนึ่งคือเรื่องความน่าเชื่อถือ การจะบอกว่าทำอะไรได้บ้าง ต้องมีที่ให้คนเข้ามาดูงานจริง ไม่ใช่แค่รายการทักษะ

ใครเจอปัญหานี้

คนที่สร้างของและอยากให้งานของตัวเองค้นเจอได้ในระยะยาว — developer, freelance, คนที่ทำงานสาย AI ที่ต้องอธิบายงานให้ลูกค้าหรือผู้ร่วมงานเข้าใจ

ในกรณีนี้ผู้ใช้คนแรกและคนหลักคือตัวผมเอง เว็บไซต์นี้เป็นทั้งที่เก็บงานและเป็นตัวอย่างงาน ในตัวเดียวกัน

สร้างอะไรขึ้นมา

เว็บไซต์ส่วนตัวแบบ static ประกอบด้วยหน้าแรก, about, บทความ, โปรเจกต์, builder log, experiments, talks, products, newsletter, contact และหน้า archive ที่ generate อัตโนมัติแยกตาม category กับ tag รวมแล้ว 37 หน้า ณ ตอนที่เขียนบทความนี้ — จำนวน จะเพิ่มเองทุกครั้งที่มีเนื้อหาใหม่

ทุกหน้าถูก build เป็นไฟล์ HTML ล่วงหน้าตั้งแต่ตอน deploy ไม่มีเซิร์ฟเวอร์ที่ต้อง render ตอนมีคนเข้า และไม่มีฐานข้อมูล

จุดตั้งต้นของโปรเจกต์นี้ไม่ใช่โค้ด แต่เป็นไฟล์ spec (AGENTS.md) ที่เขียนขอบเขต version หนึ่ง, สิ่งที่ตั้งใจ ไม่ ทำ, และลำดับการสร้างหกเฟสไว้ก่อนจะเริ่มเขียนบรรทัดแรก เฟสหนึ่งถึงหกคือ foundation, content system, core pages, discovery, quality และ launch — git history ของ repo นี้เดินตามลำดับนั้นตรง ๆ

ทำงานอย่างไร

เนื้อหาทุกชิ้นเป็นไฟล์ Markdown ที่อยู่ใน git โดยแยกโฟลเดอร์ตามประเภท แต่ละประเภทมี schema ของตัวเองเขียนด้วย Zod ใน src/content.config.ts เวลา build Astro จะ ตรวจ frontmatter ทุกไฟล์กับ schema — ถ้าพิมพ์ชื่อ field ผิดหรือใส่ค่าที่ไม่อยู่ในชุดที่ กำหนด build จะพังทันที ไม่ปล่อยให้หน้าเว็บออกมาเสียแล้วค่อยมาเจอทีหลัง

จุดที่ตั้งใจออกแบบไว้คือ field ที่พูดถึงผลลัพธ์จริง เช่น results เป็น optional ทั้งหมด เพราะถ้าบังคับให้กรอก มันจะกลายเป็นแรงกดดันให้เขียนตัวเลขที่ยังไม่มี

ขั้นตอนตั้งแต่เขียนจนขึ้นเว็บคือ: เขียนไฟล์ Markdown → commit → push → GitHub Actions รัน lint, type check, unit test, build และ end-to-end test → Vercel build แล้ว deploy หน้าใหม่ ไม่มีขั้นตอนที่ต้องเข้าไปกดใน admin panel

ระบบค้นหาใช้ Pagefind ซึ่งทำ index หลังจาก Astro build เสร็จ ตัว index เป็นไฟล์ static ที่โหลดเฉพาะตอนผู้ใช้เปิดกล่องค้นหา ไม่มี search API อยู่เบื้องหลัง

ธีมสว่าง/มืดถูก apply ด้วย inline script ก่อน first paint เพื่อไม่ให้เห็นหน้าจอกระพริบ ตอนโหลด และ markup เขียนโดยยึดแนวทาง WCAG — heading เรียงลำดับ, ทุก interactive element ใช้คีย์บอร์ดได้, มี skip link

ใช้เทคโนโลยีอะไร

  • Astro 7 — เลือกเพราะ output เป็น static HTML ล้วนโดยไม่ต้องแลกกับการเขียน component แบบเก่า ๆ และไม่ส่ง JavaScript framework ไปหาผู้ใช้
  • TypeScript (pin ไว้ที่ 6.x) — type check ทั้ง .astro และ .ts
  • Tailwind CSS v4 — ตั้ง design token ไว้ที่ src/styles/global.css ที่เดียว ไม่มีไฟล์ config แยก
  • Markdown + Zod ผ่าน Astro content collections — เนื้อหาอยู่ใน git, schema บังคับความถูกต้องตั้งแต่ build
  • Pagefind — search index แบบ static
  • RSS, sitemap, JSON-LD, OG image ที่ generate ตอน build — สำหรับ SEO และการแชร์
  • Vitest สำหรับ unit test และ Playwright สำหรับ end-to-end
  • GitHub Actions สำหรับ CI และ Vercel สำหรับ hosting โดยตั้ง CSP กับ security header ไว้ใน vercel.json

เจออุปสรรคอะไรบ้าง

TypeScript 7 ใช้ไม่ได้ — ตอนตั้งโปรเจกต์ TypeScript 7 ออกแล้ว แต่ทั้ง @astrojs/check และ typescript-eslint ยังกำหนด peer dependency ไว้ต่ำกว่า สุดท้าย pin TypeScript ไว้ที่ 6.x และเขียนหมายเหตุไว้ใน README ว่าเป็นการรอ เครื่องมือ ไม่ใช่การเลือกเอง

ระบบค้นหาพังเพราะ Vite — script ที่ import Pagefind ถูก Vite แปลง dynamic import() เป็น helper ชื่อ __vitePreload แต่สำหรับ script ที่ Astro inline ลงใน HTML อาร์กิวเมนต์ __VITE_PRELOAD__ ไม่ถูกแทนค่า ทำให้โยน ReferenceError ก่อน จะได้ import ด้วยซ้ำ และ catch ที่ครอบอยู่ก็รายงานผิดเป็น “index ยังไม่ได้ build” ทางแก้คือย้ายไปใช้ is:inline script ซึ่ง Astro ปล่อยออกมาตามที่เขียนโดยไม่ผ่าน Vite — คำอธิบายอยู่ในคอมเมนต์เหนือ script ใน SearchDialog.astro

CSP บล็อก WebAssembly — หลังเพิ่ม CSP ค้นหาบนเว็บจริงพังทันที เพราะ Pagefind compile WASM module ซึ่ง script-src บล็อกถ้าไม่มี 'wasm-unsafe-eval' ที่แย่กว่านั้น คือมองไม่เห็นตอน dev เลย เพราะ dev server และ preview server ไม่ได้ใส่ CSP — มีแต่ host ที่ใส่ ทางแก้คือเพิ่ม 'wasm-unsafe-eval' (ซึ่งอนุญาตเฉพาะ WebAssembly ไม่รวม eval ธรรมดา) แล้วเขียน unit test ล็อกไว้ว่า policy ต้องมี directive ที่เว็บ พึ่งพาอยู่ครบและต้องเหมือนกันทั้ง vercel.json กับ public/_headers

Vercel ไม่อ่าน public/_headers — ไฟล์นั้นใช้กับ Cloudflare Pages และ Netlify เท่านั้น พอ deploy ขึ้น Vercel จริงแล้วไปเช็ค header ที่ตอบกลับมา พบว่ามีแค่ HSTS ของ Vercel เอง ไม่มี CSP, X-Content-Type-Options, Referrer-Policy, X-Frame-Options หรือ Permissions-Policy เลย ทางแก้คือเพิ่ม vercel.json ที่มี เนื้อหาตรงกับ public/_headers เพื่อให้ย้าย host ได้โดยไม่เสีย policy

บทเรียนร่วมของสองข้อหลังคือ config ที่ทำงานเฉพาะบน production เป็นจุดบอดที่การ ทดสอบในเครื่องมองไม่เห็น

ผลลัพธ์ที่ได้

ตัวเลขทั้งหมดนี้มาจากการรันคำสั่งใน repo:

  • pnpm build — build สำเร็จเป็นหน้า static 37 หน้า ไม่มี client-side framework (ตัวเลขนี้โตตามเนื้อหาที่เพิ่ม)
  • pnpm test — unit test 57 เคสใน 6 ไฟล์ ผ่านทั้งหมด
  • pnpm exec playwright test --list — end-to-end 38 เคสใน 4 ไฟล์ รันบนทั้ง desktop และ mobile profile
  • log จาก pnpm build — Pagefind ทำ search index ครอบคลุมทุกหน้าที่ build

ทั้งหกเฟสตาม AGENTS.md §34 ทำครบและเว็บ deploy ขึ้น production แล้ว

สิ่งที่ยัง ไม่มี ตัวเลข: จำนวนผู้เข้าชม, ผู้สมัคร newsletter, และรายได้ — analytics ต่อผ่าน environment variable ไว้แล้วแต่ยังไม่มีข้อมูลย้อนหลังพอที่จะรายงาน เมื่อมี ตัวเลขจริงจะกลับมาอัปเดตตรงนี้

จะปรับปรุงอะไรต่อ

สิ่งที่ยังค้างอยู่คือส่วนที่ต้องใช้บัญชีจริงและเวลาสะสม:

  • ต่อ newsletter provider จริง — ตอนนี้ฟอร์มยังแสดงสถานะ disabled ที่ระบุชัดว่ายัง ไม่พร้อม
  • เก็บข้อมูล analytics จนพอที่จะรายงานได้อย่างซื่อสัตย์
  • เขียนเนื้อหาให้ครบตามที่วางไว้ — ตอนนี้ collection หลายอันยังว่างและ project ส่วนใหญ่ยังเป็นโครงที่มีสถานะ idea หรือ building
  • ถอด pin TypeScript ออกเมื่อ @astrojs/check และ typescript-eslint รองรับ version 7
  • เพิ่มการวัด performance เป็นตัวเลขจริง แทนที่จะอ้างว่าเร็วเพราะเป็น static

ลองใช้ได้ที่ไหน

เว็บไซต์อยู่ที่ site.aiparuay.com — หน้าที่คุณกำลังอ่านอยู่นี้ คือส่วนหนึ่งของระบบที่กำลังอธิบาย ถ้าอยากลองส่วนที่น่าสนใจที่สุด ให้ลองกดค้นหา (ปุ่มค้นหาบน header) แล้วสังเกตว่ามันตอบทันทีโดยไม่มี request ไปหาเซิร์ฟเวอร์ใด ๆ หรือสลับธีมสว่าง/มืดแล้ว reload ดูว่าไม่มีการกระพริบ

ซอร์สโค้ดอยู่ที่ไหน

repository ยังเป็น private อยู่ จึงไม่มีลิงก์ให้ในตอนนี้ รายละเอียดเชิงเทคนิคที่พอจะ แบ่งปันได้ถูกเขียนไว้ในหัวข้อ “เจออุปสรรคอะไรบ้าง” ข้างบน และจะทยอยเขียนเพิ่มใน builder log

รับบทเรียน AI ที่ใช้ได้จริง ทางอีเมล

หนึ่งบทเรียน AI ที่ใช้ได้จริง การแกะโปรเจกต์ หรือข้อคิดจากการสร้างของ สัปดาห์ละครั้ง

ไม่มีสแปม ยกเลิกได้ทุกเมื่อ