npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ri-survey-sdk

v1.1.1

Published

Universal JavaScript SDK for RI Survey integration

Readme

RI Survey SDK

A universal JavaScript SDK for integrating surveys into external SaaS applications. This SDK handles user identification, survey targeting, and response collection with native JavaScript rendering for better control and performance.

Features

Native JavaScript Rendering - No iframe limitations, full control over survey appearance and behavior
Multiple Question Types - Text, multiple choice, rating, scale, yes/no, checkbox, matrix, and more
URL-Based Targeting - Automatic survey display based on current page URL
Smart Route Detection - Handles SPA navigation and route changes with debouncing
Progress Tracking - Visual progress bar and step indicators
Responsive Design - Works seamlessly on all devices
Customizable Styling - Theme colors, layout options, and branding
Real-time Validation - Form validation and error handling
Event Callbacks - Complete control over survey lifecycle events
Cross-browser Compatibility - Works in all modern browsers

Installation

npm install ri-survey-sdk

Quick Start

import RISurveySDK from 'ri-survey-sdk';

// Initialize the SDK with URL-based targeting
const sdk = new RISurveySDK({
  apiUrl: 'https://api.yoursurvey.com/backend/v1',
  token: 'your-api-token',
  autoFetchOnRouteChange: true,    // Enable automatic URL targeting
  routeChangeDebounceMs: 500       // Debounce route changes
});

// Identify the user
await sdk.identify({
  external_user_id: 'user123',
  external_user_email: '[email protected]',
  user_role: 'customer'
});

// Surveys will now automatically show based on URL targeting!
// Or manually show a specific survey:
await sdk.showSurvey('survey-id', {
  onComplete: (response) => {
    console.log('Survey completed:', response);
  },
  onError: (error) => {
    console.error('Survey error:', error);
  },
  skippable: true
});

API Reference

Initialization

const sdk = new RISurveySDK({
  apiUrl?: string,  // Optional, defaults to http://localhost:8000/backend/v1
  token: string     // Required API token
});

User Identification

await sdk.identify({
  external_user_id: string,
  external_user_email: string,
  user_role?: string,        // Optional, defaults to 'user'
  metadata?: Record<string, any>  // Optional additional user data
});

Showing Surveys

Modal Survey (showSurvey)

await sdk.showSurvey(surveyId, {
  onComplete?: (response: any) => void,
  onError?: (error: Error) => void,
  onClose?: () => void,
  skippable?: boolean,       // Allow users to close the survey
  userId?: string           // Override user ID for this survey
});

Embedded Survey (embedSurvey)

await sdk.embedSurvey(surveyId, 'container-id', {
  // All showSurvey options plus:
  width?: string,           // e.g., '100%', '600px'
  height?: string,          // e.g., '400px', '100vh'
  theme?: string,           // 'light' or 'dark'
  primaryColor?: string,    // e.g., '#3B82F6'
  showProgressBar?: boolean,
  allowBack?: boolean,      // Allow navigation back to previous questions
  borderRadius?: string,    // e.g., '8px'
  backgroundColor?: string   // e.g., '#ffffff'
});

Getting Survey Data

// Get all surveys for the current user
const surveys = await sdk.getSurveys(includeDrafts?: boolean);

// Get a specific survey
const survey = await sdk.getSurvey(surveyId);

// Submit a response manually
await sdk.submitResponse(surveyId, {
  survey_id: surveyId,
  responses: { questionId: 'answer' },
  metadata?: Record<string, any>
});

Question Types Supported

The SDK natively renders all major question types:

Text Input

  • Single-line text input
  • Multi-line textarea
  • Placeholder text support

Multiple Choice

  • Radio button selection
  • Checkbox multi-selection
  • Custom option styling

Rating

  • 1-5 star rating system
  • Visual star indicators
  • Hover effects

Scale

  • 1-10 numeric scale
  • Slider interface
  • Real-time value display

Yes/No

  • Simple binary choice
  • Radio button interface

Checkbox

  • Multiple selection
  • Array response format

Styling and Customization

Theme Colors

await sdk.embedSurvey(surveyId, 'container', {
  primaryColor: '#3B82F6',    // Blue
  backgroundColor: '#ffffff',   // White background
  theme: 'light'               // Light theme
});

Layout Options

await sdk.embedSurvey(surveyId, 'container', {
  width: '100%',
  height: '600px',
  borderRadius: '12px',
  showProgressBar: true,
  allowBack: true
});

Event Handling

Survey Lifecycle Events

await sdk.showSurvey(surveyId, {
  onComplete: (response) => {
    // Survey was completed successfully
    console.log('Responses:', response.responses);
    console.log('Metadata:', response.metadata);
  },
  
  onError: (error) => {
    // Survey encountered an error
    console.error('Survey error:', error.message);
  },
  
  onClose: () => {
    // Survey was closed (if skippable)
    console.log('Survey closed by user');
  }
});

Response Data Structure

{
  survey_id: 'survey-123',
  responses: {
    'question-1': 'User answer',
    'question-2': ['option1', 'option2'],
    'question-3': 5
  },
  metadata: {
    user_id: 'user-123',
    completed_at: '2024-01-15T10:30:00Z'
  }
}

Benefits Over Iframe Approach

🚀 Better Performance

  • No iframe loading overhead
  • Faster rendering and interactions
  • Reduced memory usage

🎨 Full Styling Control

  • Complete CSS customization
  • Consistent branding across your app
  • No cross-origin styling limitations

🔧 Enhanced Functionality

  • Direct DOM manipulation
  • Real-time validation
  • Custom event handling
  • Better accessibility

📱 Improved Mobile Experience

  • Native touch interactions
  • Better responsive behavior
  • No iframe scrolling issues

🔒 Security Benefits

  • No cross-origin communication needed
  • Direct API calls from your domain
  • Better CSP compliance

🛠 Developer Experience

  • Full TypeScript support
  • Better debugging capabilities
  • Direct access to survey state
  • Customizable validation logic

Browser Compatibility

  • ✅ Chrome 60+
  • ✅ Firefox 55+
  • ✅ Safari 12+
  • ✅ Edge 79+
  • ✅ Mobile browsers (iOS Safari, Chrome Mobile)

Error Handling

The SDK provides comprehensive error handling:

try {
  await sdk.showSurvey(surveyId, {
    onError: (error) => {
      // Handle specific survey errors
      if (error.message.includes('not found')) {
        console.log('Survey not available');
      }
    }
  });
} catch (error) {
  // Handle SDK initialization errors
  console.error('SDK error:', error);
}

Advanced Usage

Custom Validation

// The SDK handles basic validation automatically
// For custom validation, you can intercept responses:

await sdk.showSurvey(surveyId, {
  onComplete: (response) => {
    // Custom validation logic
    const hasRequiredFields = Object.values(response.responses)
      .every(value => value !== null && value !== '');
    
    if (!hasRequiredFields) {
      alert('Please complete all required fields');
      return;
    }
    
    // Submit to your backend
    submitToBackend(response);
  }
});

Survey Targeting

// Get surveys based on user context
const surveys = await sdk.getSurveys(false);

// Filter surveys based on your business logic
const relevantSurveys = surveys.filter(survey => {
  return survey.targeting_conditions?.some(condition => {
    // Custom targeting logic
    return condition.field === 'user_role' && 
           condition.value === user.role;
  });
});

Migration from Iframe

If you're migrating from the iframe approach:

  1. Replace iframe calls with native SDK methods
  2. Update event listeners to use SDK callbacks
  3. Customize styling using SDK options
  4. Test thoroughly across different browsers

Before (Iframe)

// Old iframe approach
const iframe = document.createElement('iframe');
iframe.src = 'https://survey.com/embed/survey-id';
container.appendChild(iframe);

// Listen for messages
window.addEventListener('message', (event) => {
  if (event.data.type === 'SURVEY_COMPLETED') {
    handleCompletion(event.data.response);
  }
});

After (Native SDK)

// New native approach
await sdk.embedSurvey('survey-id', 'container-id', {
  onComplete: (response) => {
    handleCompletion(response);
  }
});

Troubleshooting

Common Issues

Survey not loading

  • Check API token validity
  • Verify survey ID exists
  • Ensure user is properly identified

Styling issues

  • Check CSS specificity
  • Verify container dimensions
  • Test in different browsers

Performance problems

  • Monitor network requests
  • Check browser console for errors
  • Verify API endpoint availability

Debug Mode

Enable debug logging:

const sdk = new RISurveySDK({
  apiUrl: 'https://api.yoursurvey.com/backend/v1',
  token: 'your-token',
  debug: true  // Enable debug logging
});

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

License

MIT License - see LICENSE file for details.