ri-survey-sdk
v1.1.1
Published
Universal JavaScript SDK for RI Survey integration
Maintainers
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-sdkQuick 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:
- Replace iframe calls with native SDK methods
- Update event listeners to use SDK callbacks
- Customize styling using SDK options
- 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
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details.
