New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

obi-loader

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

obi-loader

Lightweight loader for Obi Assistant

latest
npmnpm
Version
0.8.3
Version published
Maintainers
1
Created
Source

Obi Loader

A lightweight loader for the Obi Assistant widget. This package is designed to be as small as possible while still providing the functionality to load the full Obi Assistant from a CDN.

Why Use This Package?

Lightweight Loader: Use this small package to dynamically load the full SDK from a CDN

Benefits of the lightweight loader:

  • Significantly smaller bundle size (~5KB vs the full SDK)
  • Always loads the latest version of Obi (no need to update for bug fixes)
  • Simple API that matches the full SDK's initialization

Installation

npm install obi-loader

TypeScript Support

The package includes full TypeScript support with type definitions for all configuration options.

Using Types with NPM Installation

import { initObi, updateObi, openObiCourses, type ObiAssistantConfig, type ObiUpdateConfig } from "obi-loader"

// Type-safe configuration
const config: ObiAssistantConfig = {
  apiKey: "your-api-key",
  position: "bottom-right",
  user: {
    id: "user-123",
    email: "user@example.com",
    first_name: "John",
    last_name: "Doe",
    company: "Acme Corp",
    metadata: {
      plan: "premium",
    },
  },
}

initObi(config)

// Type-safe updates using the dedicated function (NPM only)
updateObi({
  position: "bottom-left",
  primaryColor: "#ff6b35",
  user: {
    id: "user-123",
    email: "updated@example.com",
    first_name: "Jane",
    last_name: "Smith",
    company: "TechCorp Inc",
    metadata: { plan: "enterprise" },
  },
  // apiKey: "new-key" // ❌ TypeScript error - cannot update apiKey
})

// Open course menu with one function call
openObiCourses()

// Or use the global function if preferred
window.ObiSDK("update", {
  position: "top-right",
  primaryColor: "#e91e63",
})

Using Types with CDN Script

If you're using the CDN script approach but want TypeScript support in your development environment, you can install the package just for types:

npm install --save-dev obi-loader

The package now includes global type declarations, so you automatically get type safety for both configuration and updates:

// Your TypeScript code with full type safety
window.obiWidgetConfig = {
  apiKey: "your-api-key", // ✅ Type-safe
  position: "bottom-right", // ✅ Autocomplete works
  user: {
    id: "user-123",
    metadata: { plan: "premium" },
  },
}

// Type-safe updates (apiKey automatically excluded)
window.ObiSDK("update", {
  position: "top-right", // ✅ Autocomplete for valid positions
  primaryColor: "#e91e63", // ✅ Type-checked
  // apiKey: "new-key" // ❌ TypeScript error - cannot update apiKey
})

TypeScript Support for Updates

For detailed TypeScript type information and usage examples, see the TypeScript Support section above.

Usage

import { initObi } from "obi-loader"

// Initialize Obi with your configuration
initObi({
  apiKey: "your-api-key",
  position: "bottom-right",
  user: {
    id: "user-123",
    email: "user@example.com",
    metadata: {
      plan: "premium",
    },
  },
})

API Methods

initObi(config: ObiAssistantConfig)

Initializes the Obi widget with the provided configuration. This should be called once when your application loads.

updateObi(config: Partial<ObiUpdateConfig>) (NPM only)

Updates the widget configuration after initialization. This is a type-safe alternative to using window.ObiSDK("update", config).

import { updateObi } from "obi-loader"

updateObi({
  position: "bottom-left",
  primaryColor: "#ff6b35",
  user: {
    id: "user-123",
    email: "updated@example.com",
  },
})

Note: The apiKey, urlBlacklist, and linkOnlyAccess options cannot be updated after initialization.

openObiCourses() (NPM only)

Opens the Obi course menu programmatically. This is a convenience function equivalent to updateObi({ showMenu: true }).

import { openObiCourses } from "obi-loader"

// In React
function TrainingButton() {
  return <button onClick={openObiCourses}>View Training Courses</button>
}

// In Vue
export default {
  methods: {
    openCourseMenu: openObiCourses,
  },
}

// In vanilla JavaScript
document.getElementById("training-btn").addEventListener("click", openObiCourses)

For CDN users: Use window.ObiSDK("update", { showMenu: true }) instead.

CDN Script Alternative

If you prefer not to install the npm package, you can use the CDN script approach directly in your HTML. This method has the same lightweight benefits and automatically loads the latest Obi SDK.

CDN Setup

<!DOCTYPE html>
<html>
  <head>
    <title>Your Website</title>
  </head>
  <body>
    <!-- Your website content -->

    <!-- Configure Obi -->
    <script>
      window.obiWidgetConfig = {
        apiKey: "your-api-key",
        position: "bottom-right",
      }
    </script>

    <!-- Load Obi Loader Script -->
    <script>
      !(function () {
        "use strict"
        var t = window
        !(function () {
          var n, o
          try {
            ;(n = new URLSearchParams(location.search)),
              (o = {}),
              n.forEach(function (t, n) {
                o[n] = t
              }),
              Object.keys(o).length && localStorage.setItem("obi-url-params", JSON.stringify(o))
          } catch (t) {}
          ;(t.ObiSDK =
            t.ObiSDK ||
            function () {
              return (t.ObiSDK.q = t.ObiSDK.q || []), t.ObiSDK.q.push(arguments)
            }),
            t.ObiSDK("update", t.obiWidgetConfig || {}),
            fetch("https://registry.npmjs.org/obi-sdk/latest")
              .then(function (t) {
                return t.json()
              })
              .then(function (t) {
                return t.version
              })
              .catch(function () {
                return "latest"
              })
              .then(function (t) {
                var n = document.createElement("script")
                ;(n.defer = !0),
                  (n.src = "https://unpkg.com/obi-sdk@" + t + "/dist/obi-sdk.standalone.iife.js"),
                  document.head.appendChild(n)
              })
        })()
      })()
    </script>
  </body>
</html>

CDN Script Benefits

  • No build step required: Just add scripts to your HTML
  • Zero bundle impact: Scripts load asynchronously without affecting your app's bundle size
  • Always up-to-date: Automatically uses the latest Obi SDK version
  • Backwards compatible: Works with any website, framework, or CMS
  • Lightweight: The loader script itself is under 2KB

Configuration Options

The initObi function accepts the following configuration options:

OptionTypeRequiredDescription
apiKeystringYesYour Obi API key
positionstringNoWidget position on the screen. Options: 'bottom-right', 'bottom-left', 'bottom-center', 'top-right', 'top-left', 'top-center', 'middle-left', 'middle-right'. Default: 'bottom-right'
userobjectNoUser information object containing:
- id: string (required) - Unique identifier for the user
- email: string (optional) - User's email address
- first_name: string (optional) - User's first name
- last_name: string (optional) - User's last name
- company: string (optional) - User's company name
- metadata: object (optional) - Additional custom user data
isActivebooleanNoWhether the widget should be active on load. Can be used to filter experience to certain users. Default: true
linkOnlyAccessbooleanNoHide the widget unless accessed via a session link. Perfect for trial periods where only customers with direct links should see the widget. Initialization only - cannot be updated after widget loads. Default: false
showMenubooleanNoManually show the widget menu. If the widget is not mounted, it will mount the widget and show the menu. Default: false
primaryColorstringNoCustom primary color (hex code, e.g. '#9500ff'). Default: '#9500ff'
urlBlackliststring[]NoArray of URL glob patterns where the widget should not appear. Supports wildcards (* and **) for flexible URL matching. Initialization only - cannot be updated after widget loads. Default: []

Example with All Options

initObi({
  apiKey: "your-api-key",
  position: "bottom-right",
  isActive: true,
  linkOnlyAccess: false, // Set to true for trial mode
  showMenu: false, // Set to true to mount widget and show menu immediately
  primaryColor: "#123456", // Custom primary color
  urlBlacklist: [
    "example.com/admin*", // Block all admin pages
    "example.com/private/**", // Block all private section pages
    "*/checkout", // Block checkout pages on any subdomain
    "staging.*.com/**", // Block all staging environments
  ],
  user: {
    id: "user-123",
    email: "user@example.com",
    first_name: "John",
    last_name: "Doe",
    company: "Acme Inc", // Now a primary field!
    metadata: {
      plan: "premium",
      role: "admin",
      // ... any additional custom user data
    },
  },
})

URL Blacklisting

The urlBlacklist option allows you to specify URL patterns where the widget should not appear. This is useful for excluding admin pages, checkout flows, or other sensitive areas of your website.

Glob Pattern Support

The blacklist supports glob patterns for flexible URL matching:

  • * - matches any characters except forward slashes
  • ** - matches any characters including forward slashes
  • ? - matches any single character

Examples

window.obiWidgetConfig = {
  apiKey: "YOUR_API_KEY",
  urlBlacklist: [
    "example.com/admin*", // Block all admin pages
    "example.com/checkout/**", // Block entire checkout flow
    "*/login", // Block login pages on any subdomain
    "staging.*.com/**", // Block all staging environments
    "example.com/dashboard/billing", // Block specific billing page
  ],
}

Behaviour

  • The widget will not render on pages matching any blacklist pattern
  • URL matching is case-insensitive
  • Patterns are matched against both full URLs and domain-relative URLs
  • In single-page applications, the widget will show/hide dynamically as users navigate
  • Blacklist is set at initialization and cannot be changed at runtime for security

Updating Configuration After Mount

Once the Obi widget is loaded, you can dynamically update its configuration using the global ObiSDK function.

TypeScript Support for Updates

For detailed TypeScript type information and usage examples, see the TypeScript Support section above.

Using the Global ObiSDK Function

// Update user information
window.ObiSDK("update", {
  user: {
    id: "user-456",
    email: "updated@example.com",
    metadata: {
      subscription: "premium",
      lastActivity: Date.now(),
    },
  },
})

// Update widget position
window.ObiSDK("update", {
  position: "bottom-left",
})

// Toggle widget visibility
window.ObiSDK("update", {
  isActive: false,
})

// Show menu (will mount widget if not already mounted)
window.ObiSDK("update", {
  showMenu: true,
})

// Update primary colour
window.ObiSDK("update", {
  primaryColor: "#ff6b35",
})

// Update multiple config options at once
window.ObiSDK("update", {
  position: "top-right",
  primaryColor: "#00bcd4",
  isActive: true,
  showMenu: true,
  user: {
    id: "user-123",
    email: "newemail@example.com",
    metadata: {
      plan: "enterprise",
      lastLogin: new Date().toISOString(),
    },
  },
})

Using After NPM Installation

When using the npm package, you can use either the dedicated updateObi function or the global function:

import { initObi, updateObi } from "obi-loader"

// After initialization
initObi({
  apiKey: "your-api-key",
  user: { id: "user-123" },
})

// Option 1: Use the dedicated updateObi function (cleaner for TypeScript)
updateObi({
  user: {
    id: "user-123",
    email: "newemail@example.com",
    first_name: "John",
    last_name: "Doe",
    company: "Enterprise Corp",
    metadata: {
      plan: "enterprise",
    },
  },
  position: "bottom-left",
  primaryColor: "#ff6b35",
  showMenu: true, // Mount widget and show menu
})

// Option 2: Use the global function (works everywhere)
window.ObiSDK("update", {
  position: "top-right",
  primaryColor: "#00bcd4",
})

CDN Script Configuration Updates

When using the CDN script approach, you can update configuration using the global ObiSDK function:

<script>
  // Update configuration dynamically
  window.ObiSDK("update", {
    primaryColor: "#e91e63",
    position: "middle-right",
    isActive: true,
    showMenu: false,
  })

  // Update user context
  window.ObiSDK("update", {
    user: {
      id: "current-user-id",
      email: "user@company.com",
      first_name: "Alex",
      last_name: "Johnson",
      company: "Tech Solutions Inc",
      metadata: {
        role: "admin",
        department: "engineering",
      },
    },
  })
</script>

Configuration Update Options

All configuration options from the initial setup can be updated dynamically:

Updatable OptionMethodDescription
userupdate({ user })Update user ID, email, and metadata
positionupdate({ position })Change widget position on screen
isActiveupdate({ isActive })Show/hide widget
showMenuupdate({ showMenu })Show widget menu (mounts widget if needed)
primaryColorupdate({ primaryColor })Change the widget's primary colour

Note: The apiKey, urlBlacklist, and linkOnlyAccess cannot be updated after initialization. If you need to change these values, you'll need to reinitialize the widget.

Programmatic Commands

Beyond configuration updates, the Obi widget supports several programmatic commands for controlling sessions and interactions. These commands are available through the global window.ObiSDK() function.

Start Session

Start an onboarding session programmatically. You can optionally specify which plan to launch and whether to enable the microphone automatically.

NPM Installation:

// Start a session with a specific plan and enable microphone
window.ObiSDK("startSession", {
  planUuid: "your-plan-uuid-here",
  withMicrophone: true,
})

// Start a session without specifying a plan (user can choose)
window.ObiSDK("startSession")

// Start with microphone enabled but no specific plan
window.ObiSDK("startSession", { withMicrophone: true })

CDN Installation:

<!-- Button to start session with specific plan -->
<button onclick="window.ObiSDK('startSession', { planUuid: 'your-plan-uuid-here', withMicrophone: true })">
  Start Training
</button>

<!-- Button to start session without specific plan -->
<button onclick="window.ObiSDK('startSession')">Launch Obi</button>

Parameters:

  • planUuid (optional): The UUID of the specific onboarding plan to start. If not provided, the user can select from available plans.
  • withMicrophone (optional): Boolean to automatically enable the user's microphone when the session starts. Defaults to false.

Notes:

  • When planUuid is provided, the SDK validates it against available plans for the user. If the plan is not found or not accessible, a warning is logged.
  • Starting a session automatically sets isActive to true, making the widget visible.
  • If a session is already active, this command will start a new session.

Send Message

Send a text message to the Obi agent during an active session. This is useful for programmatically triggering specific interactions or providing context.

NPM Installation:

// Send a message to the agent
window.ObiSDK("say", "Can you help me with the dashboard features?")

// Send contextual help request
window.ObiSDK("say", "I'm stuck on the checkout page")

CDN Installation:

<!-- Button to request help on specific topic -->
<button onclick="window.ObiSDK('say', 'Show me how to create a new project')">Help: Create Project</button>

<!-- Link to ask about current page -->
<a href="javascript:window.ObiSDK('say', 'Explain this page to me')">Get Help</a>

Parameters:

  • message (required): A string containing the message to send to the agent.

Notes:

  • This command requires an active session. If no session is running, the message will be queued or ignored.
  • The message appears in the chat as if the user typed it.
  • Useful for contextual help triggers based on user actions.

Stop Session

End the current onboarding session programmatically.

NPM Installation:

// Stop the current session
window.ObiSDK("stopSession")

CDN Installation:

<!-- Button to end session -->
<button onclick="window.ObiSDK('stopSession')">End Training</button>

Parameters:

None.

Notes:

  • Cleanly disconnects from the agent and closes the session.
  • The widget remains mounted and visible unless isActive is also set to false.
  • Session state is cleared from local storage.

TypeScript Support

All commands are fully typed with function overloads for autocomplete and type safety:

// TypeScript will provide autocomplete and type checking
window.ObiSDK("update", { showMenu: true }) // ✓ Valid
window.ObiSDK("startSession", { planUuid: "uuid", withMicrophone: true }) // ✓ Valid
window.ObiSDK("say", "Hello") // ✓ Valid
window.ObiSDK("stopSession") // ✓ Valid

// TypeScript will catch errors
window.ObiSDK("unknownCommand") // ❌ TypeScript error
window.ObiSDK("say", 123) // ❌ TypeScript error - message must be string
window.ObiSDK("startSession", { invalidOption: true }) // ❌ TypeScript error

Common Use Cases

Contextual Help Triggers

Trigger help based on user actions or page context:

// React: Help button on specific page
function CheckoutPage() {
  const handleHelp = () => {
    window.ObiSDK("startSession", { withMicrophone: true })
    window.ObiSDK("say", "I need help completing my purchase")
  }

  return <button onClick={handleHelp}>Get Checkout Help</button>
}

// Vue: Contextual help link
export default {
  methods: {
    requestHelp() {
      window.ObiSDK("say", `Help me with ${this.currentFeature}`)
    },
  },
}

Custom Training Launcher

Create custom UI for launching specific training sessions:

// Training dashboard with multiple courses
const trainingCourses = [
  { id: "plan-uuid-1", name: "Getting Started", duration: "5 min" },
  { id: "plan-uuid-2", name: "Advanced Features", duration: "10 min" },
  { id: "plan-uuid-3", name: "Best Practices", duration: "8 min" },
]

function TrainingDashboard() {
  const startCourse = (planUuid: string) => {
    window.ObiSDK("startSession", {
      planUuid,
      withMicrophone: true,
    })
  }

  return (
    <div>
      {trainingCourses.map((course) => (
        <button key={course.id} onClick={() => startCourse(course.id)}>
          {course.name} ({course.duration})
        </button>
      ))}
    </div>
  )
}

Timed Sessions

Automatically start or stop sessions based on time or user activity:

// Start onboarding after user has been inactive for 2 minutes
let inactivityTimer: NodeJS.Timeout

function resetInactivityTimer() {
  clearTimeout(inactivityTimer)
  inactivityTimer = setTimeout(() => {
    window.ObiSDK("startSession")
    window.ObiSDK("say", "It looks like you might need some help. How can I assist you?")
  }, 120000) // 2 minutes
}

// Reset timer on user activity
document.addEventListener("mousemove", resetInactivityTimer)
document.addEventListener("keypress", resetInactivityTimer)

// Auto-stop session after 30 minutes
function startTimedSession() {
  window.ObiSDK("startSession")

  setTimeout(() => {
    window.ObiSDK("stopSession")
    alert("Your training session has ended due to time limit.")
  }, 1800000) // 30 minutes
}

Interactive Help System

Build an interactive help system that guides users through tasks:

// Multi-step guided tour
const tourSteps = [
  "Let me show you around. First, let's look at your dashboard.",
  "Now, let me explain how to create a new project.",
  "Next, I'll show you how to invite team members.",
  "Finally, let's review the settings page.",
]

function startGuidedTour() {
  window.ObiSDK("startSession", { withMicrophone: false })

  tourSteps.forEach((message, index) => {
    setTimeout(() => {
      window.ObiSDK("say", message)
    }, index * 5000) // 5 seconds between steps
  })
}

// Error recovery helper
function onError(errorType: string, errorDetails: any) {
  window.ObiSDK("startSession")
  window.ObiSDK(
    "say",
    `I encountered an error: ${errorType}. Can you help me understand what went wrong? Details: ${JSON.stringify(errorDetails)}`
  )
}

Common Use Cases

Opening Course Menu from Navigation

NPM Installation:

import { openObiCourses } from "obi-loader"

// React
function NavigationBar() {
  return (
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
      <button onClick={openObiCourses}>Training</button>
    </nav>
  )
}

// Vue
export default {
  methods: {
    openTraining: openObiCourses,
  },
}

CDN Installation:

<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
  <a href="javascript:window.ObiSDK && window.ObiSDK('update', {showMenu: true})">Training</a>
</nav>

Dynamic User Context Updates

// Update user context when user logs in
function onUserLogin(userData) {
  updateObi({
    user: {
      id: userData.id,
      email: userData.email,
      metadata: {
        plan: userData.subscription.plan,
        joinDate: userData.createdAt,
      },
    },
  })
}

// Update user context when user upgrades plan
function onPlanUpgrade(newPlan) {
  updateObi({
    user: {
      id: currentUser.id,
      email: currentUser.email,
      metadata: {
        ...currentUser.metadata,
        plan: newPlan,
        upgradeDate: new Date().toISOString(),
      },
    },
  })
}

Conditional Widget Display

// Show widget only for certain user types
function updateWidgetVisibility(user) {
  updateObi({
    isActive: user.plan === "premium" || user.role === "admin",
  })
}

// Hide widget during checkout process
function enterCheckout() {
  updateObi({ isActive: false })
}

function exitCheckout() {
  updateObi({ isActive: true })
}

How It Works

This package doesn't bundle the full Obi SDK. Instead, it:

  • Queries the NPM registry to find the latest version of the obi-sdk package
  • Dynamically loads the standalone build from the UNPKG CDN
  • Creates and initializes the Obi widget with your configuration

This approach ensures your application always uses the latest version of Obi while keeping your bundle size minimal.

Bundle Size Comparison

PackageMinified Size
obi-sdk~200KB
obi-loader~5KB

License

See LICENSE.txt for details.

Keywords

obi

FAQs

Package last updated on 22 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts