@mentoor/inline-guide
v0.4.0
Published
Browser SDK for Mentoor in-app product guidance, live UI navigation, and customer onboarding.
Downloads
568
Maintainers
Readme
Mentoor Inline Guide
Mentoor is a browser SDK for in-app product guidance. It adds a lightweight helper layer to your live product so users can ask for help, follow published guides, and get pointed to real controls without leaving the page.
Use it when you want product onboarding, feature discovery, release guidance, or contextual help inside the app your users already have open.
Install
npm install @mentoor/inline-guideOr load the hosted script:
<script src="https://mentoor.ai/sdk.js"></script>Quickstart
Create a project and public browser key in Mentoor Studio, add your app URL to the allowed origins, then initialize Mentoor from browser-side code:
import { Mentoor } from '@mentoor/inline-guide'
const mentoor = Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
environment: 'production',
chatEnabled: true,
privacy: 'balanced',
// Launcher pill / panel copy. Defaults to "Find anything".
launcherLabel: 'Find anything',
user: currentUser ? { id: currentUser.id } : undefined,
traits: { plan: 'trial' },
getRouteContext: () => ({
route: window.location.pathname + window.location.hash,
title: document.title,
url: window.location.href,
}),
})For script-tag installs:
<script src="https://mentoor.ai/sdk.js"></script>
<script>
window.Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
environment: 'production',
chatEnabled: true,
privacy: 'balanced',
getRouteContext: () => ({
route: window.location.pathname + window.location.hash,
title: document.title,
url: window.location.href,
}),
})
</script>Keep apiBase explicit. It should point to the Mentoor API host shown in Studio. That prevents app proxies, Next.js middleware, and same-path /api routes from accidentally receiving SDK calls.
Stable Anchors
Mentoor can learn from accessible labels, roles, layout, and route context, but important controls should have stable anchors:
<button data-mentoor="invite-teammate" data-mentoor-label="Invite teammate">
Invite teammate
</button>
<input data-mentoor="teammate-email" aria-label="Teammate email" />Use data-mentoor anywhere you want a durable product anchor.
Use data-mentoor-ignore around private or noisy regions that Mentoor should not inspect:
<section data-mentoor-ignore>
Private billing details
</section>Privacy Modes
privacy: 'essential' keeps explicit help useful without passive learning:
- Published guides can still run.
- Users can still ask questions from the current screen.
- Browser storage, visitor memory, guide memory, passive product learning, and personalization stay off unless you enable them.
privacy: 'balanced' enables the full product loop:
- Safe product-map learning from routes, labels, roles, anchors, and click/input events with values redacted.
- Guide memory and anonymous visitor continuity across page loads.
- Draft guide suggestions and personalization when your app passes user or trait data.
You can start in Essential mode and enable specific capabilities after your app has consent or another privacy basis:
const mentoor = Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
privacy: 'essential',
})
mentoor.setConsent({
storage: true,
productLearning: true,
visitorMemory: true,
guideMemory: true,
personalization: true,
})Hard storage overrides are also available:
storage: 'local': persistent browser storage.storage: 'memory': runtime-only storage.storage: 'none': no local visitor or guide state.
Runtime API
Mentoor.init() returns a runtime object:
await mentoor.ask('Where do I invite a teammate?')
await mentoor.startGuide('invite teammate')
await mentoor.identify({
id: 'your-user-id',
traits: { role: 'admin', plan: 'growth' },
})
await mentoor.setTraits({ onboarding: 'started' })
mentoor.open()
mentoor.close()
mentoor.sync()
mentoor.destroy()Experimental agent mode can perform bounded, human-paced UI actions when your app enables it:
const mentoor = Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
agent: {
enabled: true,
allowClicks: true,
allowTyping: true,
},
})
await mentoor.act('Invite teammate [email protected]')High-risk controls are blocked by default. If your app wants Mentoor to click one, mark that exact control:
<button
data-mentoor="regenerate-api-key"
data-mentoor-label="Regenerate API key"
data-mentoor-agent="allow"
>
Regenerate API key
</button>Your app still owns auth, permissions, validation, and destructive action checks.
Manual Guides
Most teams publish guides from Studio, but the SDK also exposes guide primitives:
import { createMentoorGuide } from '@mentoor/inline-guide'
const guide = createMentoorGuide({
name: 'Mentoor',
intro: {
title: 'Want a quick live guide?',
message: 'I can walk you through the invite flow while you use the product.',
},
steps: [
{
id: 'invite',
target: '[data-mentoor="invite-teammate"]',
action: 'click',
message: 'Start here.',
successMessage: 'Nice. I will follow you.',
},
{
id: 'email',
target: '[data-mentoor="teammate-email"]',
action: 'input',
message: 'Type their email here. I will wait.',
minChars: 3,
},
],
})
guide.start()Destroy a guide when the host route unmounts:
guide.destroy()Semantic Targets
Mentoor stores product intent and target evidence instead of relying only on brittle selectors.
import {
createMentoorRecorder,
createMentoorTargetFingerprint,
resolveMentoorTarget,
scoreMentoorTargetCandidate,
} from '@mentoor/inline-guide'
const recorder = createMentoorRecorder({
redactInputValues: true,
onAction(action) {
console.log(action.intent, action.fingerprint)
},
})
recorder.start()
const fingerprint = createMentoorTargetFingerprint(inviteButton)
const match = resolveMentoorTarget(fingerprint)
if (match && match.score >= 80) {
console.log('Use this target', match.element, match.reasons)
}
const scored = scoreMentoorTargetCandidate(fingerprint, candidateElement)Fingerprints can include:
data-mentoorordata-testidanchors.- Accessible names.
- Roles and tags.
- Semantic region and landmark paths.
- Link hrefs.
- Nearby labels, legends, and headings.
- Duplicate-label ordinals.
- Routes.
- Input types.
- Visible text.
Framework Notes
Initialize Mentoor only in browser-side code after window exists.
React:
import { useEffect } from 'react'
import { Mentoor, type MentoorAssistant } from '@mentoor/inline-guide'
export function MentoorProvider({ userId }: { userId?: string }) {
useEffect(() => {
const mentoor: MentoorAssistant = Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
user: userId ? { id: userId } : undefined,
getRouteContext: () => ({
route: window.location.pathname + window.location.hash,
}),
})
return () => mentoor.destroy()
}, [userId])
return null
}Next.js App Router:
'use client'
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'
import { Mentoor } from '@mentoor/inline-guide'
export function MentoorClient({ userId }: { userId?: string }) {
const pathname = usePathname()
useEffect(() => {
const mentoor = Mentoor.init({
projectId: 'your-project-id',
publicKey: 'pk_live_public_browser_key',
apiBase: 'https://mentoor.ai',
user: userId ? { id: userId } : undefined,
getRouteContext: () => ({
route: window.location.pathname + window.location.hash,
}),
})
return () => mentoor.destroy()
}, [pathname, userId])
return null
}TypeScript
Mentoor exports first-class Mentoor names for the public SDK:
import {
Mentoor,
createMentoorGuide,
type MentoorAssistant,
type MentoorAssistantOptions,
type MentoorGuideOptions,
type MentoorGuideStep,
type MentoorTargetFingerprint,
} from '@mentoor/inline-guide'The package exports Mentoor-named helpers and types for new installs.
Launch Checklist
- Use only the
pk_public browser key from Studio in frontend code. - Add every production app URL to the project's allowed origins.
- Keep
apiBasepointed at the Mentoor API host. - Mark stable controls with
data-mentoorso guides can find the right action. - Mark private regions with
data-mentoor-ignorewhen Mentoor should not read or guide inside them. - Keep authentication, permissions, forms, and destructive actions owned by your app.
Package Details
- ESM:
dist-lib/index.js - CommonJS/UMD:
dist-lib/index.umd.cjs - Types:
dist-lib/index.d.ts - Runtime dependencies: none
- Browser support: modern browsers with standard DOM APIs
Development
npm install
npm run build:lib
npm run lint
npm testThe hosted Mentoor app/API can be deployed separately. The npm package is only the browser SDK.
