ลองใช้ driver.js เพื่อทำ product tours

วันนี้ผมมาแชร์การใช้งาน driver.js เอามาทำ product tours เพื่อแนะนำการใช้งานเว็บ หรือ app ของเราครับ

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.