Product Tours คืออะไร ?
Product Tours วิธีการแนะนำการใช้งานแบบ Interactive เพื่อแนะนำให้ User เข้าใจวิธีการใช้งาน Product (Web / App) เพื่อลดความสับสน ลดสร้างความรู้สึกทีดีกับการใช้งาน โดย Product Tours จะมีชื่อเรียกอื่นๆ เช่น User Onboarding หรือ Feature Walkthrough โดยมีประโยชน์ ดังนี้
- ลดปัญหาในการเรียนรู้ (Learning Curve) - ช่วยให้ User เข้าใจระบบง่ายขึ้น โดยไม่ต้องเสียเวลาอ่านคู่มือหนาๆ
- เพิ่มอัตราการใช้งาน (Feature Adoption) - แนะนำให้ผู้ใช้รู้จัก Feature ใหม่ ที่ช่วยให้การใช้งานสะดวกขึ้น
- ลดภาระงานช่วยเหลือ (Support) - ถ้าเล่นระบบถูก มันจะช่วยลดคำถาม ปัญหาที่เข้ามาทาง Support น้อยลง
- เพิ่มอัตราการรักษาผู้ใช้งาน (Retention Rate) - ถ้า User ใช้งานถูก จะ Happy และกลับมาใช้งานต่อในระยะยาว
ข้อควรระวัง ควรเลือก Trigger ที่เหมาะสม เช่น แนะนำการใช้งานครั้งแรก
driver.js คืออะไร ?
driver.js - เป็น Library ที่มีขนาดเล็ก JavaScript และไม่มี Dependency กับ Lib อื่นทำให้ Lightweight เหมาะกับการเอามาสร้าง Product Tour โดยจากที่ลองใช้มาจุดเด่น Simple / Build-In Focus Effect ช่วยเน้นจุดสนใจแต่ละ Step ได้ / Keyboard Control / Responsive
Sample use
- Installation
# Using npm npm install driver.js # Using pnpm pnpm install driver.js # Using yarn yarn add driver.js # Using Bun bun add driver.js # cdn <script src="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.js.iife.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@latest/dist/driver.css"/>
- sample use ตัว hero-title / login-btn เป็น id ของ html element ที่ต้องการให้ driver.js ไปจับแสดง ToolTip ด้วย
import { driver } from "driver.js";
import "driver.js/dist/driver.css";
const driverObj = driver({
showProgress: true,
steps: [
{ element: '#hero-title', popover: { title: 'Welcome', description: 'This is the main title.' } },
{ element: '#login-btn', popover: { title: 'Sign In', description: 'Click here to log in.' } }
]
});
driverObj.drive();
กรณีที่ใช้จาก cdn ตอนสร้าง driver object ต่างนิดหน่อย ต้องไปใช้จาก windows แทนการ import
const driver = window.driver.js.driver; const driverObj = driver();
ลองใช้งานกับ nuxt 4
- Installation - ผมใช้ bun ก็ลงตามนี้
bun add driver.js - ใน page ที่ต้องการ
index.vueกำหนด Id ให้แต่ละ Element ที่จะเพิ่มชัดเจน เคสนี้ผมจะเพิ่ม access-key / build-info และ dotnet-options เป็นต้น
<div id="access-key" class="rounded-lg border border-default bg-default p-4 shadow-sm"> ... </div> <div id="build-info" class="rounded-lg border border-default bg-default p-4 shadow-sm"> ... </div> <div id="dotnet-options" class="rounded-xl border border-default bg-elevated/50 p-4"> ... </div>
- สร้าง Composable เพื่อแยก Logic ส่วนของ Product Tour ออกจาก Code หลัก จะได้ maintain ง่ายๆ อันนี้ import driver.js / css จากนั้นมากำหนด ลำดับของ Product Tour ในที่นี้จะเด้งจาก Id title-section > access-key > build-info > dotnet-options > gateway-options > vb6-options > template-save > submit-actions
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'
export default function useBuildInvSetTour() {
const startTour = () => {
const driverObj = driver({
showProgress: true,
animate: true,
steps: [
{
element: '#title-section',
popover: {
title: 'Build Request — Primary',
description: 'Welcome! This page allows you to create comprehensive build-request issues in Redmine for .NET projects, including optional Gateway and VB6 subtasks.',
side: 'bottom',
align: 'start',
},
},
{
element: '#access-key',
popover: {
title: 'Authentication',
description: 'Enter your Redmine Access Key here. You can also toggle "Use Server Token" if you want to use the pre-configured system token instead of your own.',
side: 'bottom',
align: 'start',
},
},
{
element: '#build-info',
popover: {
title: 'Build Details',
description: 'Select your layout (template), tracker, target version, and build branch. Use "Thisweek Release" to auto-fill current release information.',
side: 'bottom',
align: 'start',
},
},
{
element: '#dotnet-options',
popover: {
title: '.NET Options',
description: 'This is the primary build group. Configure flags like GEN_SBOM, SEND_NOTIFY, and CLEANUP_WS for Windows and Container builds.',
side: 'top',
align: 'start',
},
},
{
element: '#gateway-options',
popover: {
title: 'Gateway Subtask',
description: 'Enable this switch if your release needs a Gateway (Spring Boot) subtask created alongside the primary .NET build.',
side: 'top',
align: 'start',
},
},
{
element: '#vb6-options',
popover: {
title: 'VB6 Subtask',
description: 'Include a VB6 build subtask if needed by enabling this section.',
side: 'top',
align: 'start',
},
},
{
element: '#template-save',
popover: {
title: 'Save Template',
description: 'Check this to save your current configuration as a layout template for future use.',
side: 'top',
align: 'start',
},
},
{
element: '#submit-actions',
popover: {
title: 'Final Step',
description: 'Click Submit to create the issues in Redmine. All results and links will be displayed in a toast message upon completion.',
side: 'top',
align: 'center',
},
},
],
})
driverObj.drive()
}
return {
startTour,
}
}
- กลับมาที่
index.vueมาเพื่อ Import Composable ที่สร้างไว้มาในส่วน Script
import useBuildInvSetTour from '~/composables/useBuildInvSetTour' //อาจจะไม่จำเป็น Nuxt Auto Import
// เรียกใช้ Composable
const { startTour } = useBuildInvSetTour()
- ที่
index.vueทำปุ่มเพื่อเรียกใช้
<UButton
icon="i-heroicons-question-mark-circle"
color="neutral"
variant="ghost"
label="Help Tour"
@click="startTour"
/>
- ทดสอบครับ - พอกดปุ่ม Help มันจะมี Step แนะนำมา จริงตัว lib มันเลือกได้หลายแบบนะ อาทิ เช่น เข้ามาครั้งแรกเป็นต้น

สำหรับใครที่อยากดู Code เต็มๆ ดูจาก Commit 51e48d4 ได้เลยครับ
Reference
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.



