Install Flowbite on Rails 8
Flowbite เป็นชุด component บน Tailwind CSS ที่มีทั้งแบบ free และ pro มีจำนวน component และ template ค่อนข้างเยอะ ทำงานด้วย vanilla JavaScript จึงเข้ากันได้ดีกับ Rails ที่ใช้ Hotwire โพสต์นี้พาติดตั้ง Flowbite บน Rails 8 ใหม่ที่ใช้ Tailwind v4 และ Bun พร้อมแก้จุดที่ component หยุดทำงานหลัง Turbo navigation
Prerequisites
- Ruby 3.3+
- Rails 8
- ติดตั้ง Bun บนเครื่อง dev
- ความคุ้นเคยกับ Tailwind CSS เบื้องต้น
สร้าง Rails app
1
rails new blog -c tailwind -j bun
-c tailwind— ใช้ cssbundling-rails กับ Tailwind (ได้ Tailwind v4 มาเลย)-j bun— ใช้ jsbundling-rails กับ Bun แทน esbuild หรือ rollup
ย้าย Tailwind entrypoint
ค่า default ของ Rails จะวาง application.tailwind.css ไว้ใน app/assets/stylesheets/ ซึ่งเป็น folder เดียวกับ asset อื่นๆ ของแอป ย้ายไปแยกใน app/assets/tailwind/ เพื่อให้ source CSS ของ Tailwind ไม่ปนกับ stylesheet ของแอป:
1
2
mkdir app/assets/tailwind
mv app/assets/stylesheets/application.tailwind.css app/assets/tailwind/application.css
อัปเดต path ใน build:css script ของ package.json ให้ตรงกับ entrypoint ใหม่:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "app",
"private": true,
"scripts": {
"build": "bun bun.config.js",
- "build:css": "bunx @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify"
+ "build:css": "bunx @tailwindcss/cli -i ./app/assets/tailwind/application.css -o ./app/assets/builds/application.css --minify"
},
"dependencies": {
"@hotwired/stimulus": "^3.2.2",
"@hotwired/turbo-rails": "^8.0.13",
"@tailwindcss/cli": "^4.1.3",
"tailwindcss": "^4.1.3"
}
}
ติดตั้ง Flowbite
1
bun add flowbite
ประกาศให้ Tailwind รู้จัก Flowbite ใน entrypoint CSS:
1
2
3
4
5
@import "../../../node_modules/flowbite/src/themes/default";
@plugin "../../../node_modules/flowbite/plugin";
@source "../../../node_modules/flowbite";
อธิบายแต่ละ directive:
@import ".../flowbite/src/themes/default"— โหลด design token เริ่มต้น (สี, spacing, typography) ของ Flowbite เข้ามา ถ้าอยาก customize theme ก็ override ตัวแปร CSS ที่อยู่ในนี้@plugin ".../flowbite/plugin"— register Flowbite เป็น Tailwind plugin (syntax ของ Tailwind v4) เพื่อให้ utility class ของ Flowbite ถูก generate ออกมาตอน build@source ".../flowbite"— บอก Tailwind v4 ให้ scan class ในไฟล์ของ Flowbite ด้วย ไม่งั้น class ที่ปรากฏแค่ใน JS หรือ template ของ Flowbite จะถูก purge ออก
Import Flowbite JS และผูกกับ Turbo
Import Flowbite ใน JavaScript entrypoint:
1
import "../../node_modules/flowbite/dist/flowbite"
Flowbite init component ครั้งเดียวตอน page load ถ้าใช้ Turbo แล้ว navigate ข้ามหน้า DOM ใหม่จะไม่ได้รับการ init ทำให้ dropdown, modal, tooltip ฯลฯ หยุดทำงาน ต้องเรียก
initFlowbite()ใหม่ทุกครั้งที่ Turbo render
เพิ่ม event listener สำหรับ Turbo:
1
2
3
4
5
6
7
8
9
import { initFlowbite } from "flowbite"
document.addEventListener("turbo:load", () => {
initFlowbite()
})
document.addEventListener("turbo:render", () => {
initFlowbite()
})
turbo:load ครอบ navigation ปกติ ส่วน turbo:render ครอบกรณี Turbo Frame หรือ Turbo Stream ที่ update DOM แค่บางส่วน
ทดสอบ
สร้าง home controller สำหรับลอง component:
1
rails g controller home index
Copy markup component อย่าง Dropdown หรือ Modal จาก Flowbite docs มาวางใน app/views/home/index.html.erb แล้วชี้ root route ไปที่ home#index
รัน Rails server พร้อม watcher ของ Tailwind และ Bun:
1
bin/dev
เปิด http://localhost:3000 ทดสอบ component ที่มี state เช่น dropdown และ navigate ระหว่างหน้าผ่าน link เพื่อยืนยันว่า Flowbite ยังทำงานหลัง Turbo navigation
Conclusion
Rails 8 app พร้อมใช้ Flowbite component ได้แล้ว สิ่งที่ต้องระวังคือ initFlowbite() ต้องถูกเรียกใหม่ทุกครั้งหลัง Turbo render ไม่งั้น component ที่ต้องใช้ JS จะหยุดทำงานหลัง navigate
จะเลือก Flowbite หรือ Preline ขึ้นอยู่กับ:
- License + budget — Flowbite มี tier pro ที่ต้องจ่ายเงินสำหรับ component และ template ขั้นสูง ส่วน Preline เป็น open-source ทั้งหมด
- Design language — ลองเทียบ visual style ของทั้งสองแล้วเลือกที่เข้ากับโปรเจกต์มากกว่า
- Ecosystem — Flowbite เก่ากว่า มี community และ template สำเร็จเยอะกว่า ส่วน Preline ออกแบบให้รัน autoInit ง่ายและ component crisp กว่า