skills.md file first, then start the prompt.
NavigateMe — Guide Authoring Reference
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:
- The engine clicks the element in `selector` (opens the form)
- The message from `showMessage` appears
- The tour **stops** and waits
- 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:
- No `selector` keys — tour steps never click anything
- Every step has both `highlight` and `showMessage` — the highlight without a message is meaningless
- `:nth-child()` is used to target successive sibling cards by position
- `subType: "tour"` is the only flag needed to switch the engine into highlight mode
`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.
- For `numeric`: defaults to `10`. Creates buttons 0 through `scale`.
- For `star`: defaults to `5`. Creates `scale` number of stars.
{ 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:
- Auto-launch the onboarding splash on first login
- Trigger a tour from a help button or tooltip
- Start a post-action survey after a user completes a workflow
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:
- Section transitions use a `{ showMessage, wait }` step with no selector — narration only
- `wait: 4000` on the Tax Configuration menu item gives the settings panel time to load after the previous click
- `proceedOn` uses `:exact` on Save buttons to avoid matching "Save Draft" or similar variants
- The final step is a message-only step confirming completion to the user
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:
- `mousedown: true` on the select component because Ant Design's Select doesn't respond to a plain `click`
- `hide: true` — this tour is triggered from a specific button in the app, not listed in the menu
- The final `showMessage`-only step gives the user confirmation without navigating anywhere
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:
- The last step has no `selector` — it only shows a message and sets a `proceedOn` watch. The tour is just waiting for the Save click, not driving any navigation itself.
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:
- `subType: "tour"` is the only addition needed at the guide level — `type` stays `"navigate"`
- `highlight` replaces `selector` — no click is ever fired
- Every step has a `showMessage` — a highlight with no message provides no context to the user
- `:nth-child()` targets each stat card positionally — update selectors to match your actual DOM structure
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:
- NPS first (numeric) → CSAT second (star) → open text last. This ordering is intentional: quantitative questions first, qualitative last.
- The `review` step has no `maxLength` — it defaults to 500 characters.
- All three question types are represented, making this a good copy-paste base for any feedback survey.
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:
- The entire call is wrapped in `try/catch` so a NavigateMe failure never breaks the host app
- `workspaceId` is read from `sessionStorage` at init time, so it captures the active workspace for every event automatically
- `"Content-Type": "text/plain"` + `mode: "no-cors"` is the correct combination for posting to a Google Apps Script endpoint without a CORS preflight