@getspot/spot-widget
v3.2.2
Published
Core JavaScript/TypeScript library for integrating Spot's refund guarantee widget into your applications.
Keywords
Readme
@getspot/spot-widget
Core JavaScript/TypeScript library for integrating Spot's refund guarantee widget into your applications.
Installation
npm install @getspot/spot-widgetQuick Start
import SpotWidget from '@getspot/spot-widget';
// Create widget instance
const widget = new SpotWidget({
location: '#spot-widget-container', // CSS selector or DOM element
apiConfig: {
environment: 'production', // 'sandbox' for testing
partnerId: 'your-partner-id'
},
quoteRequestData: {
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-01-07T23:59:59Z',
currencyCode: 'USD',
eventType: 'Ski Trip',
productType: 'Trip',
productDuration: 'Trip',
productPrice: 500,
productId: 'ski-trip-2024',
cartId: 'cart-123',
productName: 'Aspen Ski Trip 2024'
},
callbacks: {
onOptIn: (data) => {
console.log('User opted in:', data);
// Handle opt-in logic
},
onOptOut: (data) => {
console.log('User opted out:', data);
// Handle opt-out logic
},
onQuoteRetrieved: (quote) => {
console.log('Quote retrieved:', quote);
},
onError: (error) => {
console.error('Widget error:', error);
}
}
});TypeScript Support
This package is written in TypeScript and includes full type definitions.
import SpotWidget, { SpotWidgetOptions, SelectionData, Quote } from '@getspot/spot-widget';
const options: SpotWidgetOptions = {
// ... your configuration
};
const widget = new SpotWidget(options);Configuration
SpotWidgetOptions
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| location | string \| HTMLElement | No | "body" | Target element for the widget |
| apiConfig | ApiConfig | Yes | - | API configuration |
| quoteRequestData | QuoteRequestData | Yes | - | Quote request information |
| showTable | boolean | No | true | Whether to show payout table |
| optInSelected | boolean | No | false | Pre-select opt-in option |
| theme | Theme | No | - | Custom styling |
| callbacks | Callbacks | No | {} | Event callbacks |
ApiConfig
{
environment: 'production' | 'sandbox' | 'local';
partnerId: string;
customEndpoint?: string; // Optional custom API endpoint
}QuoteRequestData
Single Product Quote
{
startDate: string; // ISO 8601 date
endDate: string; // ISO 8601 date
currencyCode: 'USD' | 'CAD' | 'AUD';
eventType: string; // Event description
productType: 'Pass' | 'Trip' | 'Registration';
productDuration: 'Daily' | 'Seasonal' | 'Trip' | 'Event';
productPrice: number; // Price in specified currency
productId: string; // Unique product identifier
cartId: string; // Shopping cart identifier
productName: string; // Human-readable product name
participantDescription?: string; // Optional participant info
}Batch Quote (Multiple Products)
{
cartInfo: {
cartId: string;
cartName: string;
currencyCode: 'USD' | 'CAD' | 'AUD';
};
items: Array<{
// All single product fields except cartId and currencyCode
cartItemId?: string; // Optional item identifier
}>;
}Widget Methods
updateQuote(newQuoteRequestData)
Update the widget with new quote data.
const success = await widget.updateQuote({
// new quote request data
});
console.log('Update successful:', success);Returns: Promise<boolean>
getSelection()
Get the current user selection.
const selection = widget.getSelection();
console.log('User selection:', selection);Returns: SelectionData | null
validateSelection()
Check if the user has made a selection.
const isValid = widget.validateSelection();
if (!isValid) {
console.log('Please make a selection');
}Returns: boolean
destroy()
Clean up the widget instance.
widget.destroy();Callbacks
onOptIn(data: SelectionData)
Called when user opts into the refund guarantee.
{
onOptIn: (data) => {
console.log('Opt-in data:', data);
// data.status === 'QUOTE_ACCEPTED'
// data.quoteId - unique quote identifier
// data.spotPrice - refund guarantee price
}
}onOptOut(data: SelectionData)
Called when user opts out of the refund guarantee.
{
onOptOut: (data) => {
console.log('Opt-out data:', data);
// data.status === 'QUOTE_DECLINED'
// data.quoteId - unique quote identifier
}
}onQuoteRetrieved(quote: Quote)
Called when a quote is successfully retrieved.
{
onQuoteRetrieved: (quote) => {
console.log('Quote:', quote);
// quote.id - quote identifier
// quote.spotPrice - refund guarantee price
// quote.communication - display text and labels
}
}onError(error: ErrorData)
Called when an error occurs.
{
onError: (error) => {
console.error('Error:', error);
// error.message - error description
// error.status - HTTP status code (if applicable)
// error.responseBody - API response (if applicable)
}
}noMatchingQuote(data)
Called when no quote is available for the request.
{
noMatchingQuote: (data) => {
console.log('No quote available:', data);
// Handle case where product isn't eligible
}
}Styling
Customize the widget appearance using the theme option:
const widget = new SpotWidget({
// ... other options
theme: {
primaryColor: '#007bff',
secondaryColor: '#6c757d',
borderRadius: '8px',
fontFamily: 'Arial, sans-serif',
fontSize: '14px'
// Any CSS custom properties (without -- prefix)
}
});Error Handling
Always implement comprehensive error handling:
const widget = new SpotWidget({
// ... configuration
callbacks: {
onError: (error) => {
// Log for debugging
console.error('Spot Widget Error:', error);
// Handle different error types
if (error.status === 404) {
console.log('Product not eligible for refund guarantee');
} else if (error.status >= 500) {
console.log('Service temporarily unavailable');
}
// Track in analytics
if (window.analytics) {
window.analytics.track('spot_widget_error', {
message: error.message,
status: error.status
});
}
},
noMatchingQuote: (data) => {
console.log('No refund guarantee available');
// Hide widget or show alternative messaging
}
}
});Environments
Sandbox (Development)
Use the sandbox environment for testing:
{
apiConfig: {
environment: 'sandbox',
partnerId: 'your-sandbox-partner-id'
}
}Production
Use the production environment for live applications:
{
apiConfig: {
environment: 'production',
partnerId: 'your-production-partner-id'
}
}API Reference
This package exports the following types and interfaces:
Interfaces
ApiConfig
export interface ApiConfig {
environment: "sandbox" | "production" | "local";
partnerId: string;
customEndpoint?: string;
}QuoteMetadata
export interface QuoteMetadata {
segment?: string;
operator?: string;
channel?: string;
consumerId?: string;
}CartInfo
export interface CartInfo {
cartId: string;
cartName: string;
currencyCode: "USD" | "CAD" | "AUD";
metadata?: QuoteMetadata;
isPartialPayment?: boolean;
}QuoteItem
export interface QuoteItem {
productPrice: number;
productType: "Pass" | "Trip" | "Registration";
productDuration: "Daily" | "Seasonal" | "Trip" | "Event";
productId: string;
cartId: string;
cartName: string;
productName: string;
participantDescription?: string;
eventType: string;
eventId?: string;
currencyCode: "USD" | "CAD" | "AUD";
startDate: string;
endDate: string;
partnerRiskEnd?: Date;
metadata?: QuoteMetadata;
isPartialPayment?: boolean;
hostCountry?: string;
hostCountryState?: string;
destinations?: string[];
dob?: string;
}BatchQuoteRequest
export interface BatchQuoteRequest {
cartInfo: CartInfo;
items: BatchQuoteItem[];
}QualifyingReason
export interface QualifyingReason {
rank: number;
name?: string;
benefitType?: {
name: string;
};
}PayoutScheduleItem
export interface PayoutScheduleItem {
text: string;
percent: string | number;
amount: number;
}Communication
export interface Communication {
name: string;
description: string;
bulletPoints: string[];
yesOptionText: string;
noOptionText: string;
legalDisclaimer: string;
termsAndConditionsUrl: string;
paymentTerms?: string;
}Quote
export interface Quote {
id: string;
cartItemId?: string;
spotPrice: number;
currencyCode: string;
communication: Communication;
payoutSchedule: PayoutScheduleItem[];
qualifyingReasons?: QualifyingReason[];
coveredItems?: string[];
originalQuotes?: Quote[];
}QuoteUpdates
export interface QuoteUpdates {
spotPriceWithFees?: number;
}ApiResponse
export interface ApiResponse {
status: "QUOTE_AVAILABLE" | "QUOTES_AVAILABLE" | "NO_MATCHING_QUOTE";
data?: Quote;
quotes?: Quote[];
totalSpotPrice?: number;
spotPrice?: number;
currencyCode?: string;
communication?: Communication;
payoutSchedule?: PayoutScheduleItem[];
coveredItems?: string[];
}SelectionData
export interface SelectionData {
status: "QUOTE_ACCEPTED" | "QUOTE_DECLINED";
spotPrice?: number;
quoteId?: string;
selection?: string;
batchQuoteDetails?: Array<{
quoteId: string;
productPrice: number;
cartItemId: string;
}>;
}Callbacks
export interface Callbacks {
onOptIn?: (data: SelectionData) => void;
onOptOut?: (data: SelectionData) => void;
onQuoteRetrieved?: (quote: Quote) => QuoteUpdates | void;
onError?: (error: { message: string; status?: number; responseBody?: any }) => void;
noMatchingQuote?: (data: { status: string; data: QuoteRequestData }) => void;
}Theme
export interface Theme {
[key: string]: string;
}SpotWidgetOptions
export interface SpotWidgetOptions {
location?: string | HTMLElement;
showTable?: boolean;
optInSelected?: boolean;
logoPosition?: "bottom-right" | "top-right";
apiConfig: ApiConfig;
quoteRequestData: QuoteRequestData;
callbacks?: Callbacks;
theme?: Theme;
isPartialPayment?: boolean;
useMockData?: boolean;
mockData?: ApiResponse;
}ElementOptions
export interface ElementOptions {
text?: string;
className?: string;
parent?: HTMLElement;
innerHTML?: string;
href?: string;
target?: string;
}Type Aliases
QuoteRequestData
export type QuoteRequestData = QuoteItem | BatchQuoteRequest;Framework Integration
This is the core library. For framework-specific wrappers:
- React: @getspot/spot-widget-react
- Vue 3: @getspot/spot-widget-vue
- Vue 2: @getspot/spot-widget-vue2
Browser Support
- Modern browsers (ES2020+)
- Chrome 80+
- Firefox 74+
- Safari 13+
- Edge 80+
License
See the main package for license information.
Support
For support, please contact [email protected].
