Skip to content
Development
Skill

/wp-guided-tour

Use when adding a guided onboarding or feature-discovery tour to a WordPress admin plugin using Driver.js v1 — setting up the IIFE bundle (window.driver.js.driver), PHP backend tour config arrays (autoStart, pages, steps, element, popover), JS scope detection from URL pathname +

From plugin
wp-dev-skills
2819 skills1 command

Claude Code

$ npx -y skills add mralaminahamed/wp-dev-skills --skill wp-guided-tour --agent claude-code

SKILL.md

wp-guided-tour.SKILL.md
name: wp-guided-tour
description: "Use when adding a guided onboarding or feature-discovery tour to a WordPress admin plugin using Driver.js v1 — setting up the IIFE bundle (window.driver.js.driver), PHP backend tour config arrays (autoStart, pages, steps, element, popover), JS scope detection from URL pathname + hash (getCurrentScope, hashchange listener), localStorage-based completion tracking, CSS selector rules for WP admin elements including Tailwind bracket-notation escaping, testing selectors in browser console, and generating/updating the POT file for tour strings. Triggers: \"add a guided tour to my plugin\", \"onboarding walkthrough in WP admin\", \"Driver.js setup\", \"highlight this admin element\", \"step-by-step tutorial in WP admin\", \"tour not starting\", \"tour completion not saving\", \"scope detection for admin pages\", \"add tooltips to my settings page\", \"first-run wizard\", \"window.driver.js.driver\", \"getCurrentScope()\", \"hashchange listener for tour\", \"localStorage tour tracking\", \"Tailwind selector escaping in PHP\", \"Driver.js popover\", \"autoStart tour config\", \"tour step element not found\", \"verify selector in browser console\", \"tour i18n POT file\". Not for: front-end SPAs or non-WordPress apps; guided tours in themes."

WordPress Admin Guided Tours (Driver.js)

> **Model note:** IIFE bundle setup and PHP config scaffolding are mechanical (`haiku`). JS scope detection from URL + hash, and debugging selector mismatches against live DOM, need `sonnet`.

When to use

  • "Add a guided tour to my plugin", "set up Driver.js in WordPress admin".
  • "Wire up tour scopes by URL/hash", "detect which page the user is on for tour routing".
  • "Track tour completion correctly", "fix tour firing on dismiss instead of Done".
  • "Test tour selectors against live DOM".

**Not for:** Front-end-only SPAs or non-WordPress JS apps — requires WP admin backend context. Guided tours in themes — this skill targets plugin-owned admin pages only.

Setup

1 — Vendor Driver.js

Download the Driver.js v1 IIFE build (NOT the ESM build):

  • `driver.js.iife.js` → `assets/admin/js/driverjs/driver.js.iife.js`
  • `driver.css` → `assets/admin/js/driverjs/driver.css`

The IIFE build exposes `window.driver.js.driver` (double namespace). Always call it as:

window.driver.js.driver({ ... })

2 — Enqueue in Asset.php

// Enqueue on all admin pages (is_admin() block)
$this->enqueue_script(
    'shopflow_guided_tour_driverjs',
    SHOPFLOW_ASSETS_URL . 'admin/js/driverjs/driver.js.iife.js',
    array()
);
$this->enqueue_style(
    'shopflow_guided_tour_driverjs',
    SHOPFLOW_ASSETS_URL . 'admin/js/driverjs/driver.css',
    array()
);
$this->enqueue_script(
    'shopflow_guided_tour',
    SHOPFLOW_ASSETS_URL . 'admin/js/guided-tour.js',
    array( 'shopflow_guided_tour_driverjs' )
);

// Add tour configs to the main localized object
$localized['tours'] = shopflow_get_tour_configs();

The `$localized` array must be passed to `localize_script()` on the **main SPA script** (not the tour script) so `window.SHOPFLOW.tours` is available before `guided-tour.js` runs.

---

PHP Tour Config (`functions.php`)

function shopflow_get_tour_configs() {
    return apply_filters( 'shopflow_tour_configs', array(

        'dashboard' => array(
            'autoStart' => true,          // only one scope should be true
            'pages'     => array( 'shopflow' ),
            'steps'     => array(
                array(
                    // Centered popover — no element key
                    'popover' => array(
                        'title'       => __( 'Welcome!', 'my-plugin' ),
                        'description' => __( 'Quick intro text.', 'my-plugin' ),
                        'side'        => 'bottom',
                    ),
                ),
                array(
                    // Element-targeted step
                    'element' => '#my-stable-id',
                    'popover' => array(
                        'title'       => __( 'Step Title', 'my-plugin' ),
                        'description' => __( 'Step description.', 'my-plugin' ),
                        'side'        => 'right',
                    ),
                ),
            ),
        ),

    ) );
}

**Rules:**

  • Only one scope should have `autoStart: true` (the primary onboarding page)
  • Always use `__()` on title and description — run `makepot` after adding new steps
  • `side` values: `top`, `bottom`, `left`, `right`
  • Do NOT set `align: 'start'` — it's the default; explicit is noise
  • `pages` array is metadata only; actual detection is done by JS `getCurrentScope()`

---

JS Scope Detection (`guided-tour.js`)

function getCurrentScope() {
    const urlParams = new URLSearchParams(window.location.search);
    const page = urlParams.get('page');

    if (!page || !page.startsWith('myprefix')) return null;

    // Non-SPA pages (full page reloads)
    if (page === 'myprefix-settings') return 'settings';
    if (page === 'myprefix-wizard')   return 'wizard';

    // Main SPA — differentiate by hash route
    // Strip pagination suffix like /page/2
    const hash = window.location.hash.replace('#', '').replace(/\/page\/\d+$/, '');

    if (!hash || hash === '/' || hash === '/dashboard') return 'dashboard';
    if (hash.startsWith('/products/add'))  return 'add-product';
    if (hash === '/orders/new')            return 'create-order';
    if (hash === '/orders')                return 'orders';
    if (hash === '/customers')             return 'customers';
    if (hash.startsWith('/reports'))       return 'reports';

    return null;
}

**Key points:**

  • Check `page.startsWith('myprefix')` — NOT `page.startsWith('myprefix-')` (would miss the bare slug `page=myprefix`)
  • Hash routes need explicit prefix matching (`.startsWith`) for pages with sub-routes
  • `hashchange` listener re-runs scope detection for SPA navigation:
  window.addEventListen
Read more
@mralaminahamed
Ships withwp-dev-skills

Covers the complete WordPress plugin development lifecycle — build, test, audit, release, and ship to WP.org — for Claude Code, Gemini CLI, Cursor, Windsurf, Cline, Codex, GitHub Copilot, opencode, and more.

Stars on GitHub

Momentum

stars in total
28
Star history of mralaminahamed/wp-dev-skills on GitHub, a chart by star-history.com

Other skills on wp-dev-skills.

wp-ci-qa

wp-ci-qa

Use when a pull request has QA failures, a \"Testing Failed\" label, or QA comments reporting broken features — reading QA…

wp-database

wp-database

Use when a WordPress plugin needs a custom database table — creating with dbDelta (strict SQL format: two spaces before PRIMARY…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about wp-guided-tour.

Which coding agents can use wp-guided-tour?
wp-guided-tour installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.