Launch Week Day 1: Socket for Jira Is Now Available.Learn More
Socket
Book a DemoSign in
Socket

saltfish

Package Overview
Dependencies
Maintainers
1
Versions
246
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

saltfish

An interactive video-guided tour system for web applications

latest
Source
npmnpm
Version
0.3.87
Version published
Weekly downloads
452
-27.56%
Maintainers
1
Weekly downloads
 
Created
Source

Saltfish

Interactive video-guided tours for web applications. Create engaging onboarding experiences with synchronized video playback, interactive overlays, and smart triggering.

npm version License

Features

  • 🎥 Video-Guided Tours - Synchronized video content with interactive UI overlays
  • 🎯 Smart Triggers - Automatic playlist triggering based on URL, user behavior, and custom conditions
  • 📱 Responsive - Automatically adapts to different screen sizes and devices
  • 🎨 Shadow DOM - Complete style isolation prevents CSS conflicts
  • 📊 Analytics - Built-in tracking for user engagement and completion rates
  • 🔄 State Persistence - Resume tours where users left off
  • 🌐 Multi-language - User-specific language preferences
  • Lightweight - Minimal bundle size with efficient loading

Installation

<script src="https://storage.saltfish.ai/player/player.js"></script>

NPM

npm install saltfish

Quick Start

Basic Setup (CDN)

<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  <h1>Welcome to My App</h1>

  <!-- Load Saltfish -->
  <script src="https://storage.saltfish.ai/player/player.js"></script>
  <script>
    // 1. Initialize with your token
    saltfish.init({
      token: 'YOUR_TOKEN_HERE',
      enableAnalytics: true
    });

    // 2. Identify the user
    saltfish.identify('user-123', {
      email: 'user@example.com',
      name: 'John Doe',
      language: 'en'
    });

    // 3. (Optional) Manually start a playlist
    saltfish.startPlaylist('playlist-id');
  </script>
</body>
</html>

NPM/ES Modules

import saltfish from 'saltfish';

// Initialize
saltfish.init({
  token: 'YOUR_TOKEN_HERE',
  enableAnalytics: true
});

// Identify user
saltfish.identify('user-123', {
  email: 'user@example.com',
  language: 'en'
});

// Start playlist
saltfish.startPlaylist('playlist-id');

API Reference

saltfish.init(config)

Initialize the Saltfish player. Must be called before any other methods.

Parameters:

  • config (Object or String):
    • If string: Your API token
    • If object:
      • token (String, required): Your API token from Saltfish dashboard
      • enableAnalytics (Boolean, optional): Enable/disable analytics tracking (default: true)

Returns: Promise<void> (can be called without await)

Examples:

// Simple initialization with token only
saltfish.init('YOUR_TOKEN_HERE');

// With configuration object
saltfish.init({
  token: 'YOUR_TOKEN_HERE',
  enableAnalytics: false  // Disable analytics for development
});

// Using async/await
await saltfish.init('YOUR_TOKEN_HERE');

// Using events
saltfish.on('initialized', () => {
  console.log('Saltfish ready!');
});
saltfish.init('YOUR_TOKEN_HERE');

saltfish.identify(userId, attributes)

Identify the current user. This enables playlist triggers, progress tracking, and personalized experiences.

Parameters:

  • userId (String, required): Unique identifier for the user
  • attributes (Object, optional):
    • email (String): User's email address
    • name (String): User's display name
    • language (String): Language preference ('en', 'sv', 'es', 'fr', 'de', or 'auto' for browser detection)
    • Any custom attributes you want to track

Examples:

// Basic identification
saltfish.identify('user-123');

// With email and name
saltfish.identify('user-123', {
  email: 'user@example.com',
  name: 'John Doe'
});

// With language preference
saltfish.identify('user-123', {
  email: 'user@example.com',
  language: 'sv'  // Swedish
});

// Auto-detect language from browser
saltfish.identify('user-123', {
  language: 'auto'
});

// With custom attributes
saltfish.identify('user-123', {
  email: 'user@example.com',
  plan: 'premium',
  signupDate: '2024-01-15'
});

saltfish.identifyAnonymous(attributes)

Identify anonymous users without backend communication. Uses localStorage for progress tracking and trigger evaluation.

Parameters:

  • attributes (Object, optional): Same as identify() method

Examples:

// Anonymous user with language preference
saltfish.identifyAnonymous({
  language: 'en'
});

// Anonymous user with no data
saltfish.identifyAnonymous();

// With custom tracking data
saltfish.identifyAnonymous({
  language: 'auto',
  theme: 'dark'
});

saltfish.startPlaylist(playlistId, options)

Manually start a specific playlist. If a playlist is already running, it will be reset and the new one started.

Parameters:

  • playlistId (String, required): The playlist ID from your Saltfish dashboard
  • options (Object, optional):
    • startNodeId (String): Start from a specific step instead of the beginning
    • position (String): Player position ('bottom-left' or 'bottom-right')

Returns: Promise<void> (can be called without await)

Examples:

// Basic usage
saltfish.startPlaylist('playlist-123');

// Start from a specific step
saltfish.startPlaylist('playlist-123', {
  startNodeId: 'step-5'
});

// With custom position
saltfish.startPlaylist('playlist-123', {
  position: 'bottom-right'
});

// Using async/await
await saltfish.startPlaylist('playlist-123');

// Using events
saltfish.on('playlistStarted', (data) => {
  console.log('Started:', data.playlist.id);
});
saltfish.startPlaylist('playlist-123');

Event Listeners

Listen to player events using on() and remove listeners with off().

saltfish.on(eventName, handler)

Register an event listener.

Available Events:

  • 'initialized' - Player initialized successfully
  • 'playlistStarted' - Playlist has started playing
  • 'playlistEnded' - Playlist completed
  • 'playlistDismissed' - User dismissed/closed the playlist
  • 'stepStarted' - New step/video started
  • 'stepEnded' - Step/video completed
  • 'error' - An error occurred

Examples:

// Listen for playlist completion
saltfish.on('playlistEnded', (data) => {
  console.log('Playlist completed:', data.playlist.id);
  console.log('Completion rate:', data.completionRate);
});

// Listen for step changes
saltfish.on('stepStarted', (data) => {
  console.log('Now on step:', data.step.id);
});

// Listen for errors
saltfish.on('error', (data) => {
  console.error('Player error:', data.message);
});

// Listen for initialization
saltfish.on('initialized', () => {
  console.log('Player ready!');
});

saltfish.off(eventName, handler)

Remove an event listener.

Returns: boolean - true if listener was removed, false if not found

Example:

function onPlaylistEnd(data) {
  console.log('Playlist ended:', data.playlist.id);
}

// Add listener
saltfish.on('playlistEnded', onPlaylistEnd);

// Remove listener
saltfish.off('playlistEnded', onPlaylistEnd);

Other Methods

saltfish.getSessionId()

Get the current session ID.

Returns: String

const sessionId = saltfish.getSessionId();
console.log('Session ID:', sessionId);

saltfish.getRunId()

Get the current run ID (unique per playlist execution).

Returns: String | null

const runId = saltfish.getRunId();
console.log('Run ID:', runId);

saltfish.resetPlaylist()

Reset the current playlist to its initial state.

saltfish.resetPlaylist();

saltfish.destroy()

Destroy the player instance and clean up all resources.

saltfish.destroy();

saltfish.version()

Get the current Saltfish player version.

Returns: String

const version = saltfish.version();
console.log('Saltfish version:', version);

Playlist Triggers

Playlists can be automatically triggered based on conditions you configure in the Saltfish CMS. No code changes needed!

Trigger Types

URL-Based Triggers

Automatically show playlists when users visit specific URLs:

// Just initialize and identify - triggers happen automatically
saltfish.init('YOUR_TOKEN');
saltfish.identify('user-123');

// Playlist will auto-trigger when user navigates to configured URLs
// e.g., "/dashboard", "/pricing", "/features/*"

CMS Configuration Examples:

  • Exact match: /dashboard - Only triggers on exactly /dashboard
  • Contains: /dashboard with "contains" mode - Triggers on /dashboard, /dashboard/settings, etc.
  • Wildcard: /products/* - Triggers on any product page
  • Regex: /playlist-[0-9]+ - Triggers on /playlist-1, /playlist-42, etc.

Element Click Triggers

Trigger playlists when users click specific elements:

<button id="help-button">Help</button>
<button class="support-btn">Support</button>
<button data-action="guide">Guide</button>

<script>
  saltfish.init('YOUR_TOKEN');
  saltfish.identify('user-123');

  // Configure in CMS with CSS selector:
  // #help-button, .support-btn, [data-action="guide"]
</script>

Conditional Triggers

Configure complex trigger logic in the CMS:

  • Once per user: Show playlist only once, never again
  • Seen/Not seen: Trigger based on whether user has seen other playlists
  • A/B Testing: Show different playlists to different user segments
  • Combine conditions: URL + click + seen/not seen with AND/OR logic

Manual Override

You can always manually start a playlist even if triggers are configured:

// Manually start any playlist
saltfish.startPlaylist('onboarding-tour');

Common Use Cases

Onboarding Flow

// Initialize on page load
saltfish.init({
  token: 'YOUR_TOKEN',
  enableAnalytics: true
});

// Identify user after signup
saltfish.identify(userId, {
  email: userEmail,
  language: 'auto',
  plan: 'free'
});

// Backend triggers will automatically show onboarding
// when configured in CMS for new users

Feature Announcement

saltfish.init('YOUR_TOKEN');
saltfish.identify(userId);

// Configure in CMS to trigger on /new-feature page
// Playlist auto-plays when user visits

Help Button

<button id="help-btn">Help</button>

<script>
  saltfish.init('YOUR_TOKEN');
  saltfish.identify(userId);

  // Configure in CMS with element selector: #help-btn
  // Playlist auto-triggers when user clicks
</script>

Context-Specific Tours

// Different tours for different pages
saltfish.init('YOUR_TOKEN');
saltfish.identify(userId);

// Configure in CMS:
// - "/dashboard" → dashboard-tour
// - "/settings" → settings-tour
// - "/billing" → billing-tour

// Tours trigger automatically based on URL

Framework Integration

React

import { useEffect } from 'react';
import saltfish from 'saltfish';

function App() {
  useEffect(() => {
    // Initialize Saltfish
    saltfish.init({
      token: process.env.REACT_APP_SALTFISH_TOKEN,
      enableAnalytics: true
    });

    // Identify user when auth state changes
    if (user) {
      saltfish.identify(user.id, {
        email: user.email,
        name: user.name,
        language: 'auto'
      });
    }

    // Cleanup on unmount
    return () => {
      saltfish.destroy();
    };
  }, [user]);

  return <div>Your App</div>;
}

Vue

<template>
  <div>Your App</div>
</template>

<script>
import saltfish from 'saltfish';

export default {
  mounted() {
    saltfish.init({
      token: process.env.VUE_APP_SALTFISH_TOKEN,
      enableAnalytics: true
    });

    if (this.user) {
      saltfish.identify(this.user.id, {
        email: this.user.email,
        language: 'auto'
      });
    }
  },
  beforeUnmount() {
    saltfish.destroy();
  }
};
</script>

Angular

import { Component, OnInit, OnDestroy } from '@angular/core';
import saltfish from 'saltfish';

@Component({
  selector: 'app-root',
  template: '<div>Your App</div>'
})
export class AppComponent implements OnInit, OnDestroy {
  ngOnInit() {
    saltfish.init({
      token: environment.saltfishToken,
      enableAnalytics: true
    });

    if (this.authService.user) {
      saltfish.identify(this.authService.user.id, {
        email: this.authService.user.email,
        language: 'auto'
      });
    }
  }

  ngOnDestroy() {
    saltfish.destroy();
  }
}

Next.js

// app/layout.js or pages/_app.js
'use client';

import { useEffect } from 'react';
import saltfish from 'saltfish';

export default function RootLayout({ children }) {
  useEffect(() => {
    if (typeof window !== 'undefined') {
      saltfish.init({
        token: process.env.NEXT_PUBLIC_SALTFISH_TOKEN,
        enableAnalytics: true
      });

      // Identify user if logged in
      // saltfish.identify(userId, { email, language: 'auto' });
    }

    return () => {
      if (typeof window !== 'undefined') {
        saltfish.destroy();
      }
    };
  }, []);

  return <html><body>{children}</body></html>;
}

TypeScript Support

Full TypeScript definitions included:

import saltfish, { SaltfishAPI } from 'saltfish';

// All methods are fully typed
saltfish.init({
  token: 'YOUR_TOKEN',
  enableAnalytics: true
});

saltfish.identify('user-123', {
  email: 'user@example.com',
  language: 'en'
});

saltfish.startPlaylist('playlist-id', {
  startNodeId: 'step-2'
});

// Event handlers are typed
saltfish.on('playlistEnded', (data) => {
  console.log(data.playlist.id); // Fully typed
  console.log(data.completionRate);
});

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Opera 76+

Getting Started

  • Sign up at saltfish.ai
  • Get your token from the dashboard
  • Create playlists using the CMS
  • Configure triggers (optional) for automatic playback
  • Install Saltfish in your app

Support

License

PROPRIETARY - See LICENSE file for details.

Made with ❤️ by Saltfish AB

Keywords

onboarding

FAQs

Package last updated on 13 Apr 2026

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