SoluCX Survey Widget - SDK Web Component

A customizable survey widget component built with Vue.js that can be integrated into various web frameworks. This widget allows you to embed SoluCX surveys directly into your applications with support for different display modes and comprehensive event handling.

Features

  • 🎯 Multiple widget types: inline, modal, bottom bar, bottom box (left/right)
  • 📱 Responsive design with customizable dimensions
  • 🔒 Security-focused with domain validation and data sanitization
  • 📊 Built-in analytics and user behavior tracking
  • ⚡ Framework agnostic - works with Vue, React, Angular, and more
  • 🎨 Customizable styling and positioning
  • 📡 Real-time event handling and callbacks

Installation

npm install solucx-survey-widget

Configuration

The widget requires the following props:

PropTypeRequiredDescription
soluCxKeystringYour SoluCX survey key
widgetTypeWidgetTypeDisplay mode: 'inline', 'modal', 'bottomBar', 'bottomBox', 'bottomBoxLeft'
widgetDataWidgetData | stringSurvey data (object or JSON string)
widgetOptionsWidgetOptions | stringConfiguration options

Widget Data Structure

interface WidgetData {
  customer_id?: string
  email?: string
  name?: string
  phone?: string
  document?: string
  transaction_id?: string
  // ... other custom fields
}

Widget Options

interface WidgetOptions {
  width?: number        // Widget width in pixels
  height?: number       // Widget height in pixels
  retry?: {
    attempts?: number   // Max retry attempts (default: 5)
    interval?: number   // Retry interval in days (default: 1)
  }
  waitDelayAfterRating?: number // Days to wait after rating (default: 60)
}

Basic Usage Examples

Direct Import and Use

app.js
  // Import the component directly
  import SoluCXSurveyWidget from 'solucx-survey-widget'

  // Use in your template/JSX
  <SoluCXSurveyWidget
  solu-cx-key="your-survey-key"
  widget-type="inline"
  widget-data='{"customer_id": "12345", "email": "[email protected]"}'
  />
  ```

Web Component (Vanilla HTML/JS)

app.html
  <!DOCTYPE html>
  <html>
  <head>
  <title>SoluCX Survey</title>
  </head>
  <body>
  <!-- Include the widget -->
  <script type="module">
      import 'solucx-survey-widget'
  </script>
  
  <!-- Use the web component -->
  <solucx-survey-widget
      solu-cx-key="your-survey-key"
      widget-type="bottomBox"
      widget-data='{"customer_id": "12345", "email": "[email protected]"}'
      widget-options='{"width": 400, "height": 300}'
  ></solucx-survey-widget>

  <script>
      // Listen to events
      const widget = document.querySelector('solucx-survey-widget')
      
      widget.addEventListener('widgetCompleted', (event) => {
      console.log('Survey completed!')
      })
      
      widget.addEventListener('widgetError', (event) => {
      console.error('Widget error:', event.detail)
      })
  </script>
  </body>
  </html>
  ```

CDN Usage

<!DOCTYPE html>
<html>
<head>
  <title>SoluCX Survey - CDN</title>
</head>
<body>
  <!-- Load from CDN -->
  <script type="module" src="https://unpkg.com/solucx-survey-widget@latest/dist/index.js"></script>
  
  <!-- Use the component -->
  <solucx-survey-widget
    solu-cx-key="your-survey-key"
    widget-type="inline"
    widget-data='{"customer_id": "67890", "name": "John Doe"}'
  ></solucx-survey-widget>
</body>
</html>

Framework Integration Examples

Vue.js

app.vue
  <template>
  <div>
      <SoluCXSurveyWidget
      :solu-cx-key="surveyKey"
      widget-type="inline"
      :widget-data="surveyData"
      :widget-options="options"
      @widget-opened="onWidgetOpened"
      @widget-closed="onWidgetClosed"
      @widget-completed="onWidgetCompleted"
      />
  </div>
  </template>

  <script setup>
  import { ref } from 'vue'
  import SoluCXSurveyWidget from 'solucx-survey-widget'

  const surveyKey = 'your-survey-key'
  const surveyData = ref({
  customer_id: '12345',
  email: '[email protected]',
  name: 'John Doe'
  })

  const options = ref({
  width: 600,
  height: 400
  })

  const onWidgetOpened = (userId) => {
  console.log('Widget opened for user:', userId)
  }

  const onWidgetClosed = () => {
  console.log('Widget closed')
  }

  const onWidgetCompleted = (userId) => {
  console.log('Survey completed by user:', userId)
  }
  </script>
  ```

React

app.jsx
  import React, { useEffect, useRef } from 'react'
  import 'solucx-survey-widget'

  const SoluCXWidget = ({ 
  soluCxKey, 
  widgetType = 'inline', 
  widgetData, 
  widgetOptions = {},
  onWidgetCompleted,
  onWidgetClosed,
  onWidgetError 
  }) => {
  const widgetRef = useRef(null)

  useEffect(() => {
      const widget = widgetRef.current

      if (widget) {
      widget.soluCxKey = soluCxKey
      widget.widgetType = widgetType
      widget.widgetData = JSON.stringify(widgetData)
      widget.widgetOptions = JSON.stringify(widgetOptions)

      const handleCompleted = () => onWidgetCompleted?.(widgetData.customer_id)
      const handleClosed = () => onWidgetClosed?.()
      const handleError = (event) => onWidgetError?.(event.detail)

      widget.addEventListener('widgetCompleted', handleCompleted)
      widget.addEventListener('widgetClosed', handleClosed)
      widget.addEventListener('widgetError', handleError)

      return () => {
          widget.removeEventListener('widgetCompleted', handleCompleted)
          widget.removeEventListener('widgetClosed', handleClosed)
          widget.removeEventListener('widgetError', handleError)
      }
      }
  }, [soluCxKey, widgetType, widgetData, widgetOptions])

  return <solucx-survey-widget ref={widgetRef} />
  }

  export default SoluCXWidget
  ```

Angular

app.jsx
  import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

  @Component({
  selector: 'app-survey-widget',
  template: `
      <solucx-survey-widget 
      #widget
      [attr.solu-cx-key]="soluCxKey"
      [attr.widget-type]="widgetType"
      [attr.widget-data]="widgetDataString"
      [attr.widget-options]="widgetOptionsString"
      ></solucx-survey-widget>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
  })
  export class SurveyWidgetComponent implements OnInit {
  @Input() soluCxKey!: string
  @Input() widgetType: string = 'inline'
  @Input() widgetData: any = {}
  @Input() widgetOptions: any = {}
  
  @Output() widgetCompleted = new EventEmitter<string>()
  @Output() widgetClosed = new EventEmitter<void>()
  @Output() widgetError = new EventEmitter<string>()

  @ViewChild('widget', { static: true }) widget!: ElementRef

  get widgetDataString(): string {
      return JSON.stringify(this.widgetData)
  }

  get widgetOptionsString(): string {
      return JSON.stringify(this.widgetOptions)
  }

  async ngOnInit() {
      await import('solucx-survey-widget')
      
      const widgetElement = this.widget.nativeElement
      
      widgetElement.addEventListener('widgetCompleted', () => {
      this.widgetCompleted.emit(this.widgetData.customer_id)
      })
      
      widgetElement.addEventListener('widgetClosed', () => {
      this.widgetClosed.emit()
      })
      
      widgetElement.addEventListener('widgetError', (event: any) => {
      this.widgetError.emit(event.detail)
      })
  }
  }
  ```

Events

The widget emits the following events:

EventDescriptionPayload
widgetOpenedWidget is displayeduserId: string
widgetClosedWidget is closed-
widgetCompletedSurvey completeduserId: string
widgetErrorError occurrederror: string
widgetResizedWidget height changedheight: number
widgetPageChangedSurvey page changedpage: string

Widget Types

  • inline: Embedded directly in page content
  • modal: Overlay modal with backdrop
  • bottomBar: Fixed bottom bar across full width
  • bottomBox: Fixed bottom-right corner box
  • bottomBoxLeft: Fixed bottom-left corner box

Development

# Install dependencies
npm install

# Run tests
npm test

# Build for production
npm run build

Support

For support and questions, please contact the SoluCX team or refer to the official documentation.