⚠️ Important: Whenever you use this prompt, attach the skills.md file first, then start the prompt.

This file is a complete context reference for writing NavigateMe guides. It covers every key, every guide type, and every step property with examples. Use this as the source of truth when creating or editing guides.

Top-Level Structure

All guides live in the guides array. Each object in the array is one guide.

const guides = [
  { /* guide object */ },
  { /* guide object */ },
];

Guide-Level Keys

These keys are set at the top of each guide object, not inside steps.

`id` *(string, required)*

A unique identifier for this guide. Used to launch it programmatically via NavigateMe.startGuide("your-id"). Use lowercase with hyphens.

id: "create-tax-config"

`type` *(string, required)*

Determines which engine runs this guide. Must be one of three values:

Value Engine
"navigate" Guided tour — clicks UI elements and shows messages
"splash" Onboarding questionnaire — fullscreen tile-based steps
"survey" Feedback survey — bottom-sheet, one question per screen
type: "navigate"

`subType` *(string, optional)*

An optional modifier that changes the behaviour of the engine selected by type. Currently supported value:

Value Used With Behaviour
"tour" "navigate" Highlights UI elements in place without clicking them. Steps usehighlight instead of selector.
subType: "tour"

When subType is "tour", the guide engine does not click elements. Instead it draws a highlight overlay over the matched element and shows the showMessage bubble alongside it. Use this for read-only walkthroughs of a dashboard or screen where the user should not be driven through a workflow.

Omit this key for standard click-driven navigate guides.

`title` *(string, required)*

The label shown in the Navigate Me menu. Keep it short and action-oriented.

title: "Create Tax Configuration"

`hide` *(boolean, optional)*

When true, this guide does not appear in the Navigate Me menu. It can only be launched programmatically. Use this for splash screens (first-login only), guided flows triggered from a help button, or any guide that should not be user-initiated.

hide: true

Omit this key entirely if you want the guide to appear in the menu.

`steps` *(array, required)*

An array of step objects. The engine runs them in order from index 0. The contents of each step object depend on the guide type (and subType). See per-type step references below.

Guide Type: `navigate`

Each step in a navigate guide is an object that can carry any combination of the following keys. All keys are optional — a step can be as minimal as {} if it only needs a wait.

Step Keys — `navigate`

`selector` *(string)*

A CSS selector for the UI element this step should click. The engine waits up to 10 seconds for the element to appear, then clicks it. If the element never appears, the tour stops and clears its state.

{ selector: ".ant-menu-title-content:contains(Manage Workspace)" }

Special selector syntax:

:contains(text) — matches elements whose text content includes the given string.

selector: "button:contains(Create New Configuration)"
// Finds a <button> whose text includes "Create New Configuration"

:contains(text):exact — matches elements whose text content exactly equals the given string. Use this when a partial match would hit the wrong element.

selector: ".ant-alert-action button:contains(Save):exact"
// Only matches a button whose text is exactly "Save", not "Save Draft" etc.

The base selector before :contains is a standard CSS selector (button, .classname, div, etc.).

`showMessage` *(string)*

Displays a floating message bubble to the user at this step. The message appears for 5 seconds then fades out. Can be used with or without selector.

{ showMessage: "Complete this form to create tax configuration" }

When used with selector: the element is clicked first, then the message appears. When used without selector: only the message is shown and the step is done. Useful for narration-only steps.

// Message-only step (no click)
{ showMessage: "Starting with tax configuration", wait: 2000 }

`wait` *(number — milliseconds)*

Pauses execution for this many milliseconds before the step runs. Use it to give the UI time to animate or load after a previous click.

{ selector: ".ant-menu-title-content:contains(Tax Configuration)", wait: 4000 }
// Waits 4 seconds before looking for this element

Also used on message-only steps to control pacing:

{ showMessage: "Now create a rental", wait: 2000 }

`proceedOn` *(string — selector)*

Pauses the tour and waits for the user to click a specific element before continuing. The tour does not advance on its own — it watches for this click event.

Use this whenever a step requires the user to fill in a form before the tour can continue. The selector follows the same :contains / :exact rules as selector.

{
  selector: "button:contains(Create New Configuration)",
  showMessage: "Complete this form to create tax configuration",
  proceedOn: ".ant-alert-action button:contains(Save):exact"
}

Flow of a step with proceedOn:

  1. The engine clicks the element in `selector` (opens the form)
  2. The message from `showMessage` appears
  3. The tour **stops** and waits
  4. When the user clicks the element matching `proceedOn`, the tour resumes the next step after a 2.5 second buffer

The proceedOn timeout is 30 seconds. If the element is never found, the tour stops and clears state.

`mousedown` *(boolean)*

When true, the engine dispatches a mousedown event on the element in addition to a regular click. Use this for UI components that respond to mousedown rather than click (e.g. certain dropdown/select components).

{ selector: ".ant-select-selector", mousedown: true }

`canSkip` *(boolean)*

When true, if the element in selector is not found within the wait period, the step is silently skipped rather than stopping the tour. Use for optional or context-dependent steps that may not always be present.

{ selector: ".some-optional-banner", wait: 2000, canSkip: true }

Note: when canSkip is true, the timeout used is the value of wait (not the default 10 seconds), so always pair it with a wait.

Full `navigate` Guide Example

{
  id: "create-tax-config",
  type: "navigate",
  title: "Create Tax Configuration",
  steps: [
    { selector: ".ant-menu-title-content:contains(Manage Workspace)" },
    { selector: ".ant-space-item:contains(Workspace Settings)" },
    { selector: ".ant-menu-title-content:contains(Tax Configuration)", wait: 4000 },
    {
      selector: "button:contains(Create New Configuration)",
      showMessage: "Complete this form to create tax configuration",
      proceedOn: ".ant-alert-action button:contains(Save):exact"
    }
  ]
}

Chaining Workflows (End-to-End Tours)

You can chain multiple sub-workflows in a single navigate guide by just continuing the steps array. Use a message-only step with wait as a transition between sections.

{
  id: "end-to-end",
  type: "navigate",
  title: "End To End",
  steps: [
    // Section 1 — Tax config
    { showMessage: "Starting with tax configuration", wait: 2000 },
    { selector: ".ant-menu-title-content:contains(Manage Workspace)" },
    // ... more steps ...

    // Section 2 — Create rental
    { selector: ".ant-menu-item:nth-child(1)", showMessage: "Now create a rental", wait: 2000 },
    // ... more steps ...
  ]
}

Guide SubType: `navigate` + `tour`

When subType: "tour" is set on a navigate guide, the engine switches from click-driven navigation to a read-only highlight walkthrough. Each step points a highlight overlay at a UI element and shows an explanatory message bubble. No clicks are fired.

Use tour guides to explain an existing screen to a user — dashboards, summary panels, settings pages — without driving them through a workflow.

Step Keys — `navigate` / `tour`

`highlight` *(string)*

A CSS selector for the element to highlight at this step. The engine waits for the element to appear, then renders an overlay around it and displays the showMessage bubble nearby.

Supports the same :contains / :exact syntax as selector, as well as standard CSS pseudo-selectors like :nth-child().

{ highlight: "div.stat-card:nth-child(1)", showMessage: "Total number of users." }

Note: :nth(n) (jQuery-style) is converted internally to :nth-child(n+1). Prefer standard CSS :nth-child() for clarity.

`showMessage` *(string)*

The explanatory text displayed in the message bubble next to the highlighted element. Required on every tour step — a step with no message provides no value.

{ highlight: "div.stat-card:nth-child(2)", showMessage: "Total number of equipments." }

`wait` *(number — milliseconds)*

Pauses execution before the step runs, giving animated or lazy-loaded elements time to appear.

{ highlight: ".chart-container", showMessage: "Revenue over time.", wait: 1500 }

`selector` *(string)*

A pure navigation step. Use { selector: "..." } inside a tour guide to click through to a page or panel before highlighting begins, or to move between pages mid-tour. No highlight overlay is drawn.

{ selector: ".ant-menu-title-content:contains(Dashboard)", wait: 3000 }

Full `tour` Guide Example

{
  id: "tour-show",
  type: "navigate",
  subType: "tour",
  title: "Dashboard Tour",
  steps: [
    {
      selector:'button.dashboard',
      wait:3000
    },
    {
      highlight: "div.stat-card:nth-child(1)",
      showMessage: "This shows the total number of users."
    },
    {
      highlight: "div.stat-card:nth-child(2)",
      showMessage: "This displays the total number of equipments."
    },
    {
      highlight: "div.stat-card:nth-child(3)",
      showMessage: "This indicates the total number of mappings."
    },
    {
      highlight: "div.stat-card:nth-child(4)",
      showMessage: "This shows the number of active equipments."
    }
  ]
}

Patterns to note:

`navigate` vs `navigate` + `tour` — When to Use Which

Scenario Use
Navigate user to a page and drive a workflow type: "navigate"
Click through menus and open forms for the user type: "navigate"
Explain elements on a screen the user is already on type: "navigate", subType: "tour"
Walk through a dashboard without triggering any actions type: "navigate", subType: "tour"
Onboarding intro to a summary or stats panel type: "navigate", subType: "tour"

Guide Type: `splash`

A fullscreen, multi-step tile questionnaire. Each step is one question with a set of tile options. The user must select a tile before they can continue.

Step Keys — `splash`

`question` *(string, required)*

The heading text shown at the top of the step.

question: "What are you renting out?"

`tooltip` *(string, required)*

A subtitle shown below the question heading. Use it to add context or instructions.

tooltip: "Pick the closest match"

`name` *(string, required)*

The key under which this step's answer is stored in the payload sent to the API. Each step must have a unique name.

name: "type"
// The API receives: { type: "vehicles" }

`options` *(array, required)*

An array of tile objects the user can choose from. Each tile has:

Key Type Description
val string The value sent to the API when this tile is selected
icon string An emoji shown inside the tile
label string The display text shown below the icon
options: [
  { val: "vehicles",    icon: "🚗", label: "Vehicles" },
  { val: "equipment",   icon: "🔧", label: "Equipment" },
  { val: "spaces",      icon: "🏢", label: "Spaces" },
  { val: "tools",       icon: "🧰", label: "Tools" },
  { val: "electronics", icon: "💻", label: "Electronics" },
  { val: "others",      icon: "📦", label: "Other items" }
]

Full `splash` Guide Example

{
  id: "onboarding",
  type: "splash",
  title: "Setup Workspace",
  hide: true,
  steps: [
    {
      question: "What are you renting out?",
      tooltip: "Pick the closest match",
      name: "type",
      options: [
        { val: "vehicles",    icon: "🚗", label: "Vehicles" },
        { val: "equipment",   icon: "🔧", label: "Equipment" },
        { val: "spaces",      icon: "🏢", label: "Spaces" }
      ]
    },
    {
      question: "How big is your operation?",
      tooltip: "Helps configure defaults",
      name: "size",
      options: [
        { val: "solo",       icon: "👤", label: "Just me" },
        { val: "micro",      icon: "👥", label: "2–5 people" },
        { val: "enterprise", icon: "🏭", label: "200+ people" }
      ]
    }
  ]
}

What gets sent to the API on completion:

{ "type": "vehicles", "size": "solo" }

What gets sent if the user clicks Skip:

null

Guide Type: `survey`

A bottom-sheet survey. Each step is one question. The user must answer before they can proceed to the next question.

Step Keys — `survey`

`question` *(string, required)*

The question text shown at the top of the step.

question: "How likely are you to recommend this product?"

`type` *(string, required)*

The input type for this question. Must be one of:

Value Description
"numeric" A row of numbered buttons (0 toscale). Auto-labels as Detractor / Passive / Promoter
"star" Clickable star icons (1 toscale). Shows sentiment labels on hover and selection
"review" A free-text textarea with a character counter

`scale` *(number, optional)*

Used by numeric and star types to set the maximum value.

{ question: "How likely are you to recommend this product?", type: "numeric", scale: 10 }
{ question: "How was your overall experience?",              type: "star",    scale: 5  }

`maxLength` *(number, optional)*

Used by the review type. Sets the maximum number of characters the user can type. Defaults to 500 if omitted.

{ question: "Do you think we are missing something?", type: "review", maxLength: 300 }

NPS Scoring Logic (numeric type)

The numeric type auto-classifies answers. The thresholds are:

Score range Label
0–60% of scale Detractor
61–80% of scale Passive
81–100% of scale Promoter

For a scale of 10: 0–6 = Detractor, 7–8 = Passive, 9–10 = Promoter.

Full `survey` Guide Example

{
  id: "user-feedback",
  type: "survey",
  title: "User Feedback",
  hide: true,
  steps: [
    {
      question: "How likely are you to recommend this product?",
      type: "numeric",
      scale: 10
    },
    {
      question: "How was your overall experience?",
      type: "star",
      scale: 5
    },
    {
      question: "Do you think we are missing something?",
      type: "review"
    }
  ]
}

What gets sent to the API on completion:

{
  "guideId": "user-feedback",
  "type": "survey",
  "answers": { "0": 9, "1": 4, "2": "Better export options would be great" },
  "status": "completed"
}

What gets sent if the user cancels mid-survey:

{
  "guideId": "user-feedback",
  "type": "survey",
  "answers": { "0": 9 },
  "status": "cancelled"
}

Note: answer keys are the step index (0, 1, 2…), not the question text.

API Configuration

Configured once via window.navigateme_apiconfig. Set this before calling initNavigateMe().

window.navigateme_apiconfig = {
  url: "https://your-endpoint.com/collect",   // required — POST target
  headers: { "Content-Type": "text/plain" },  // optional — request headers
  prebody: {                                  // optional — merged into every payload
    app: "my-app",
    env: "production",
    workspaceId: sessionStorage.getItem("selectedWorkspace")
  },
  params: { mode: "no-cors" }                 // optional — extra fetch options
}

prebody fields are merged with the event payload on every call, so you don't need to repeat them per guide. Use it for app name, environment, user ID, workspace ID, etc.

Launching Guides Programmatically

NavigateMe.startGuide("guide-id")

Use this to:

Initialisation

function initNavigateMe() {
  window.navigateme_guides = guides;
  window.navigateme_apiconfig = { /* your config */ };
  NavigateMe.loader();
}

Call initNavigateMe() once your app is ready. The loader attaches the floating button to the page.

Quick Key Reference

Guide-level keys

Key Type Required Used In Purpose
id string all Unique identifier, used for programmatic launch
type string all navigate, splash, or survey
subType string navigate "tour" switches engine to highlight-only mode
title string all Label shown in the menu
hide boolean all Hides guide from menu whentrue
steps array all The list of step objects

Step keys — `navigate`

Key Type Purpose
selector string CSS selector of element to click
showMessage string Message bubble text to display
wait number (ms) Delay before this step runs
proceedOn string Selector to wait for user click before continuing
mousedown boolean Also fires a mousedown event on the element
canSkip boolean Skip this step silently if element not found withinwait

Step keys — `navigate` + `subType: "tour"`

Key Type Purpose
highlight string CSS selector of element to highlight (no click fired)
showMessage string Explanatory message bubble shown beside the highlighted element
wait number (ms) Delay before this step runs

Step keys — `splash`

Key Type Purpose
question string Heading text
tooltip string Subtitle / helper text
name string API payload key for this step's answer
options array Array of{ val, icon, label } tile objects

Step keys — `survey`

Key Type Purpose
question string Question text
type string numeric, star, or review
scale number Max value for numeric (default 10) or star (default 5)
maxLength number Max characters for review type (default 500)

Real-World Examples

These are complete, production guides taken directly from a live implementation. Use them as copy-paste starting points or as a reference for patterns.

Example 1 — End-to-End Tour (chained multi-workflow)

The most complex guide type. Chains tax setup → type creation → rental creation → agreement into one continuous flow. Notice how showMessage + wait steps are used as section dividers, and proceedOn gates each form submission.

{
  id: "end-to-end",
  type: "navigate",
  title: "End To End",
  steps: [

    // ── Section 1: Tax Configuration ──
    {
      showMessage: "Starting with tax configuration",
      wait: 2000
    },
    {
      selector: ".ant-menu-title-content:contains(Manage Workspace)"
    },
    {
      selector: ".ant-space-item:contains(Workspace Settings)"
    },
    {
      selector: ".ant-menu-title-content:contains(Tax Configuration)",
      wait: 4000
    },
    {
      selector: "button:contains(Create New Configuration)",
      showMessage: "Complete this form to create tax configuration",
      proceedOn: ".ant-alert-action button:contains(Save):exact"
    },

    // ── Section 2: Create a Type ──
    {
      showMessage: "create a new type by mapping the created tax configuration",
      wait: 2000
    },
    {
      selector: ".ant-menu-title-content:contains(Manage Workspace)"
    },
    {
      selector: ".ant-space-item:contains(Workspace Settings)"
    },
    {
      selector: ".ant-menu-title-content:contains(Types)",
      showMessage: "Click Add and complete the form to create a new type",
      proceedOn: ".ant-alert-action button:contains(Save):exact"
    },

    // ── Section 3: Create a Rental ──
    {
      selector: ".ant-menu-item:nth-child(1)",
      showMessage: "Now create a rental",
      wait: 2000
    },
    {
      selector: "button:contains(Create)",
      showMessage: "Complete this form to create rental",
      proceedOn: "button:contains(Submit):exact"
    },

    // ── Section 4: Select Rental & Add Agreement ──
    {
      selector: ".ant-menu-item:nth-child(1)",
      showMessage: "Click on the newly created rental"
    },
    {
      selector: ".ant-btn-color-purple span:contains(Add)",
      showMessage: "Complete the form to continue",
      proceedOn: "button:contains(Submit)"
    },

    // ── Done ──
    {
      showMessage: "Agreement created successfully"
    }
  ]
}

Patterns to note:

Example 2 — Create Tax Configuration (focused single-workflow tour)

A short, focused tour. No proceedOn on navigation steps — only on the final form submission. This is the typical pattern for a "get me to X and let me fill it in" tour.

{
  id: "create-tax-config",
  type: "navigate",
  title: "Create Tax Configuration",
  steps: [
    { selector: ".ant-menu-title-content:contains(Manage Workspace)" },
    { selector: ".ant-space-item:contains(Workspace Settings)" },
    { selector: ".ant-menu-title-content:contains(Tax Configuration)" },
    {
      selector: "button:contains(Create New Configuration)",
      showMessage: "Complete this form to create tax configuration",
      proceedOn: "button:contains(Save)"
    }
  ]
}

Example 3 — Custom License Request (uses `mousedown` for a dropdown)

Shows how to handle a dropdown component that requires mousedown to open. The float button opens a panel, the select needs mousedown to trigger its open state, then a specific option is clicked.

{
  id: "customlicense",
  type: "navigate",
  hide: true,
  title: "customlicense",
  steps: [
    { selector: ".ant-float-btn-content" },
    { selector: ".ant-select-selector", mousedown: true },
    {
      selector: ".ant-select-item-option[title=\"Custom License Request\"]",
      showMessage: "please fill this and submit",
      proceedOn: "button[type=\"submit\"]"
    },
    { showMessage: "Thanks for submitting , We'll get back to you soon" }
  ]
}

Patterns to note:

Example 4 — Create New Type (navigation + user proceeds independently)

A tour that navigates to the right section but then hands control fully to the user — no selector on the final step, just a showMessage + proceedOn. The tour doesn't click anything to open the form; it trusts the user to click Add themselves while watching for the Save.

{
  id: "create-type",
  type: "navigate",
  title: "Create New Type",
  steps: [
    { selector: ".ant-menu-title-content:contains(Manage Workspace)" },
    { selector: ".ant-space-item:contains(Workspace Settings)" },
    {
      showMessage: "Click Add and complete the form to create a new type",
      proceedOn: "button:contains(Save)"
    }
  ]
}

Patterns to note:

Example 5 — Create Webhook (deep menu navigation)

Demonstrates navigating three levels deep through a menu before reaching the action. Each step is a simple selector with no extra options — pure navigation chain.

{
  id: "create-webhook",
  type: "navigate",
  title: "Create Webhook",
  steps: [
    { selector: ".ant-menu-title-content:contains(Manage Workspace)" },
    { selector: ".ant-space-item:contains(Auto Posting)" },
    { selector: ".ant-menu-title-content:contains(Webhooks for App Events)" },
    {
      selector: "button:contains(Create Webhook)",
      showMessage: "Complete this form to create webhook",
      proceedOn: "button:contains(Save)"
    }
  ]
}

Example 6 — Upgrade To Premium (single-step navigation, message only)

The simplest possible navigate guide — one step, no form, no proceedOn. Just navigate and tell the user what to do.

{
  id: "upgrade-pricing",
  type: "navigate",
  title: "Upgrade To Premium",
  steps: [
    {
      selector: ".ant-menu-title-content:contains(Upgrade & Pricing)",
      showMessage: "Choose a plan to upgrade"
    }
  ]
}

Example 7 — Dashboard Highlight Tour (subType: "tour")

A read-only walkthrough of a stats dashboard. Each step highlights one card and explains it. No navigation, no form interaction — purely explanatory.

{
  id: "tour-show",
  type: "navigate",
  subType: "tour",
  title: "Dashboard Tour",
  steps: [
    {
      highlight: "div.stat-card:nth-child(1)",
      showMessage: "This shows the total number of users."
    },
    {
      highlight: "div.stat-card:nth-child(2)",
      showMessage: "This displays the total number of equipments."
    },
    {
      highlight: "div.stat-card:nth-child(3)",
      showMessage: "This indicates the total number of mappings."
    },
    {
      highlight: "div.stat-card:nth-child(4)",
      showMessage: "This shows the number of active equipments."
    }
  ]
}

Patterns to note:

Example 8 — Onboarding Splash (full two-step profile questionnaire)

The complete onboarding splash from production. Two questions, six options each, both marked hide: true so it only appears programmatically on first login.

{
  id: "onboarding",
  type: "splash",
  title: "Setup Workspace",
  hide: true,
  steps: [
    {
      question: "What are you renting out?",
      tooltip: "Pick the closest match",
      name: "type",
      options: [
        { val: "vehicles",    icon: "🚗", label: "Vehicles" },
        { val: "equipment",   icon: "🔧", label: "Equipment" },
        { val: "spaces",      icon: "🏢", label: "Spaces" },
        { val: "tools",       icon: "🧰", label: "Tools" },
        { val: "electronics", icon: "💻", label: "Electronics" },
        { val: "others",      icon: "📦", label: "Other items" }
      ]
    },
    {
      question: "How big is your operation?",
      tooltip: "Helps configure defaults",
      name: "size",
      options: [
        { val: "solo",       icon: "👤", label: "Just me" },
        { val: "micro",      icon: "👥", label: "2–5 people" },
        { val: "small",      icon: "👨‍👩‍👧‍👦", label: "6–15 people" },
        { val: "growing",    icon: "📈", label: "16–50 people" },
        { val: "mid",        icon: "🏢", label: "50–200 people" },
        { val: "enterprise", icon: "🏭", label: "200+ people" }
      ]
    }
  ]
}

Example 9 — User Feedback Survey (NPS + star + open text)

A three-question post-usage survey combining all three question types. Marked hide: true — triggered programmatically after a key workflow completes.

{
  id: "user-feedback",
  type: "survey",
  title: "User Feedback",
  hide: true,
  steps: [
    {
      question: "How likely are you to recommend this product?",
      type: "numeric",
      scale: 10
    },
    {
      question: "How was your overall experience?",
      type: "star",
      scale: 5
    },
    {
      question: "Do you think we are missing something?",
      type: "review"
    }
  ]
}

Patterns to note:

Example 10 — Production `initNavigateMe` Setup

The full initialisation block from a production app, including API config with prebody, no-cors mode, and session-based workspace ID.

function initNavigateMe() {
  try {
    window.navigateme_guides = guides;
    window.navigateme_apiconfig = {
      url: "https://script.google.com/macros/s/YOUR_SCRIPT_ID/exec",
      prebody: {
        app: "my-app",
        env: "production",
        workspaceId: sessionStorage.getItem("selectedWorkspace")
      },
      headers: {
        "Content-Type": "text/plain"
      },
      params: { mode: "no-cors" }
    };
    NavigateMe.loader();
  } catch (e) {
    console.error("cannot start navigateme");
  }
}

Patterns to note: