โปรเจกต์
ohfork.dev
เว็บที่คุณกำลังดูอยู่นี่แหละ
เริ่ม · อัปเดต
- ก็หน้านี้แหละเว็บไซต์นี้

มันคืออะไร
สนามเด็กเล่นและพอร์ตโฟลิโอส่วนตัว รวมโปรเจกต์ การทดลอง และมุกต่างๆ ทั้งภาษาอังกฤษและไทย ดีไซน์เนี้ยบแบบนิตยสาร ส่วนมุกตลกแบบ dev ขอแทรกไว้ตามขอบ
ทำไมถึงสร้าง
ไม่อยากได้พอร์ตโฟลิโอทางการที่เรียงแค่รูปโปรเจกต์กับ tech stack อยากได้เว็บที่คนเข้ามาแล้วจำได้ทั้งผลงานและตัวคนทำ
ลองใช้ได้ไหม
ใช้อยู่นี่ไง
ฉบับเต็ม
โจทย์ลิงก์ไปยังหัวข้อนี้
ดูดีระดับ design studio แต่พูดจาแบบ dev ที่มีอารมณ์ขัน เอกสาร concept ให้ตัวเลขไว้เลยว่า ดีไซน์เนี้ยบแบบมืออาชีพ 80% มุก dev ที่ไม่ทันตั้งตัวอีก 20% มุกเป็นของแถม ไม่ต้องเก็ตมุกก็ใช้เว็บได้
ทำไมถึงสร้างลิงก์ไปยังหัวข้อนี้
ไม่อยากได้พอร์ตโฟลิโอทางการที่เรียงแค่รูปโปรเจกต์กับ tech stack อยากได้เว็บที่คนเข้ามาแล้วจำได้ทั้งผลงานและตัวคนทำ
การตัดสินใจที่ทำให้เว็บเป็นแบบนี้ลิงก์ไปยังหัวข้อนี้
- self-host และไม่เปิด port ขาเข้า เว็บรันเป็น Docker container บนเซิร์ฟเวอร์ที่บ้าน ออกสู่อินเทอร์เน็ตผ่าน Cloudflare Tunnel ซึ่งเป็นการเชื่อมต่อขาออกอย่างเดียว เซิร์ฟเวอร์เลยไม่ต้องเปิด port ไหนเลย merge เข้า
mainเมื่อไหร่ก็ deploy เอง - static เป็นค่าเริ่มต้น Next.js (App Router) prerender ทุกหน้า รวมถึงหน้าโปรเจกต์แต่ละตัวทั้งสองภาษา JavaScript ฝั่ง client มีแค่ตรงที่ต้องโต้ตอบจริงๆ
- อังกฤษและไทยแบบตั้งใจ ภาษาอังกฤษอยู่ที่
/ภาษาไทยอยู่ที่/thภาษาไทยเขียนแบบที่ dev ไทยพูดกันจริง ไม่แปลคำต่อคำ และไม่บังคับ redirect คนที่ใช้เบราว์เซอร์ภาษาไทย ส่วนมุกของแบรนด์อย่างOh fork.หรือWORKS ON MY MACHINEคงเป็นภาษาอังกฤษไว้ เพราะแปลมุกเมื่อไหร่ มุกก็ตาย - build คอยบังคับให้ซื่อสัตย์ ทุกโปรเจกต์มีสถานะจริง (shipped, in progress, experiment, archived) กับ label ขำๆ ที่ใส่หรือไม่ใส่ก็ได้ แต่มุกห้ามขัดกับความจริง ถ้าขัด การตรวจ content จะทำให้ build พังทันที
export const FLAVOR_STATUSES = {
"somehow-works": ["shipped", "wip", "experiment"],
"works-on-my-machine": ["shipped", "wip"],
"wip-forever": ["wip"],
} as const satisfies Record<StatusFlavor, readonly ProjectStatus[]>;
- ของ private ก็ต้อง private ถ้าลิงก์ไปยัง repo ที่อยู่ในรายชื่อ private build ก็พังเหมือนกัน อะไรที่ยังขาดจะถูกมาร์กว่า
TODO(owner)และขึ้นบนหน้าเว็บเป็นกรอบเส้นประพร้อมป้ายPLACEHOLDERจะได้หลุดขึ้น production แบบเงียบๆ ไม่ได้ - มุกปิดได้ ที่อยู่ใน roadmap คือ Recruiter Mode ที่กดสวิตช์เดียวแล้วมุกหายหมด และ Easter egg ที่ต้องตั้งใจเล่นถึงจะเจอ โหลดเมื่อจำเป็น เคารพการตั้งค่าลดการเคลื่อนไหว และไม่ขวางทางใครที่แค่อยากดูโปรเจกต์
เรื่องที่ยาก (หรือฮา) กว่าที่คิดลิงก์ไปยังหัวข้อนี้
- concept, roadmap และคำสั่งสำหรับ coding agent เสร็จก่อนจะมีเว็บด้วยซ้ำ commit แรกไม่มีโค้ดสักบรรทัด
- พอใช้ Cache Components ของ Next หน้า "not found" ที่เรนเดอร์ตอนมีคนขอกลายเป็นหน้า error ว่างเปล่า ตอนนี้เลยส่งที่อยู่โปรเจกต์ที่ไม่มีอยู่จริงไปหน้า 404 ก่อนเริ่มเรนเดอร์
/projects/typoจึงได้หน้า 404 ฉบับเต็มที่ยังช่วยหาทางกลับได้ - ภาษาไทยมีสระกับวรรณยุกต์ซ้อนอยู่ทั้งบนและล่างบรรทัด หน้าภาษาไทยเลยต้องเพิ่มระยะบรรทัดทุกจุดไม่ให้ตัวอักษรโดนตัด
- footer จะขึ้นว่า
on a Friday. Pray for me.ก็ต่อเมื่อ build เกิดขึ้นวันศุกร์จริงๆ ตามเวลากรุงเทพฯ - หน้านี้อยู่ในโชว์เคสของตัวเอง และปุ่มเดโมก็บอกแค่ว่า "ก็หน้านี้แหละ" แทนที่จะลิงก์วนกลับมาที่เดิม