
Company News
Meet the Socket Team at RSAC and BSidesSF 2026
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.
solucx-survey-widget
Advanced tools
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 ha
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.
npm install solucx-survey-widget
The widget requires the following props:
| Prop | Type | Required | Description |
|---|---|---|---|
soluCxKey | string | ✅ | Your SoluCX survey key |
widgetType | WidgetType | ✅ | Display mode: 'inline', 'modal', 'bottomBar', 'bottomBox', 'bottomBoxLeft' |
widgetData | WidgetData | string | ✅ | Survey data (object or JSON string) |
widgetOptions | WidgetOptions | string | ❌ | Configuration options |
interface WidgetData {
customer_id?: string
email?: string
name?: string
phone?: string
document?: string
transaction_id?: string
// ... other custom fields
}
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)
}
// 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": "user@example.com"}'
/>
// main.js
import { createApp } from 'vue'
import SoluCXSurveyWidget from 'solucx-survey-widget'
import App from './App.vue'
const app = createApp(App)
// Register globally
app.component('SoluCXSurveyWidget', SoluCXSurveyWidget)
app.mount('#app')
<!-- Now you can use it anywhere without importing -->
<template>
<div>
<SoluCXSurveyWidget
:solu-cx-key="surveyKey"
widget-type="modal"
:widget-data="customerData"
/>
</div>
</template>
<script setup>
// No need to import when registered globally
const surveyKey = 'your-survey-key'
const customerData = {
customer_id: '12345',
email: 'customer@example.com'
}
</script>
<!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": "user@example.com"}'
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!')
// Handle completion
})
widget.addEventListener('widgetError', (event) => {
console.error('Widget error:', event.detail)
})
</script>
</body>
</html>
<!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>
// Create widget programmatically
function createSurveyWidget(containerId, config) {
const container = document.getElementById(containerId)
if (!container) {
console.error('Container not found')
return
}
// Create the web component
const widget = document.createElement('solucx-survey-widget')
// Set properties
widget.setAttribute('solu-cx-key', config.surveyKey)
widget.setAttribute('widget-type', config.type || 'inline')
widget.setAttribute('widget-data', JSON.stringify(config.data))
if (config.options) {
widget.setAttribute('widget-options', JSON.stringify(config.options))
}
// Add event listeners
widget.addEventListener('widgetCompleted', config.onComplete || (() => {}))
widget.addEventListener('widgetClosed', config.onClose || (() => {}))
widget.addEventListener('widgetError', config.onError || (() => {}))
// Append to container
container.appendChild(widget)
return widget
}
// Usage
createSurveyWidget('survey-container', {
surveyKey: 'your-survey-key',
type: 'modal',
data: {
customer_id: '12345',
email: 'user@example.com'
},
options: {
width: 600,
height: 400
},
onComplete: (userId) => {
console.log('Survey completed by:', userId)
// Redirect or show thank you message
},
onError: (error) => {
console.error('Survey error:', error)
}
})
// Load widget only when needed
async function loadSurveyWidget() {
try {
// Dynamic import
await import('solucx-survey-widget')
// Create and configure widget
const widget = document.createElement('solucx-survey-widget')
widget.setAttribute('solu-cx-key', 'your-survey-key')
widget.setAttribute('widget-type', 'bottomBar')
widget.setAttribute('widget-data', JSON.stringify({
customer_id: '12345',
email: 'user@example.com'
}))
document.body.appendChild(widget)
} catch (error) {
console.error('Failed to load survey widget:', error)
}
}
// Load on user interaction
document.getElementById('show-survey').addEventListener('click', loadSurveyWidget)
// Or load after page load
window.addEventListener('load', () => {
setTimeout(loadSurveyWidget, 3000) // Show survey after 3 seconds
})
<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: 'user@example.com',
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>
1. Create a plugin (plugins/solucx-widget.client.js):
import SoluCXSurveyWidget from 'solucx-survey-widget'
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.component('SoluCXSurveyWidget', SoluCXSurveyWidget)
})
2. Use in your component:
<template>
<div>
<ClientOnly>
<SoluCXSurveyWidget
:solu-cx-key="surveyKey"
widget-type="modal"
:widget-data="surveyData"
@widget-completed="handleCompletion"
/>
</ClientOnly>
</div>
</template>
<script setup>
const surveyKey = 'your-survey-key'
const surveyData = {
customer_id: '12345',
email: 'user@example.com'
}
const handleCompletion = (userId) => {
console.log('Survey completed!', userId)
// Navigate to thank you page
await navigateTo('/thank-you')
}
</script>
1. Create a wrapper component (SoluCXWidget.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) {
// Set properties
widget.soluCxKey = soluCxKey
widget.widgetType = widgetType
widget.widgetData = JSON.stringify(widgetData)
widget.widgetOptions = JSON.stringify(widgetOptions)
// Add event listeners
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)
// Cleanup
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
2. Use in your React component:
import React, { useState } from 'react'
import SoluCXWidget from './SoluCXWidget'
const SurveyPage = () => {
const [surveyData] = useState({
customer_id: '12345',
email: 'user@example.com',
name: 'John Doe'
})
const handleSurveyCompleted = (userId) => {
console.log('Survey completed by:', userId)
// Redirect or show success message
}
return (
<div className="survey-container">
<h2>Customer Feedback</h2>
<SoluCXWidget
soluCxKey="your-survey-key"
widgetType="inline"
widgetData={surveyData}
widgetOptions={{ width: 600, height: 400 }}
onWidgetCompleted={handleSurveyCompleted}
/>
</div>
)
}
export default SurveyPage
1. Create a dynamic component (components/SoluCXWidget.js):
import dynamic from 'next/dynamic'
import { useEffect, useRef } from 'react'
const SoluCXWidget = ({ soluCxKey, widgetType, widgetData, widgetOptions, onComplete }) => {
const widgetRef = useRef(null)
useEffect(() => {
// Import the web component dynamically
import('solucx-survey-widget')
}, [])
useEffect(() => {
const widget = widgetRef.current
if (widget) {
widget.soluCxKey = soluCxKey
widget.widgetType = widgetType
widget.widgetData = JSON.stringify(widgetData)
widget.widgetOptions = JSON.stringify(widgetOptions || {})
const handleComplete = () => onComplete?.(widgetData.customer_id)
widget.addEventListener('widgetCompleted', handleComplete)
return () => widget.removeEventListener('widgetCompleted', handleComplete)
}
}, [soluCxKey, widgetType, widgetData, widgetOptions, onComplete])
return <solucx-survey-widget ref={widgetRef} />
}
// Export as dynamic component to avoid SSR issues
export default dynamic(() => Promise.resolve(SoluCXWidget), { ssr: false })
2. Use in your page (pages/survey.js):
import SoluCXWidget from '../components/SoluCXWidget'
import { useRouter } from 'next/router'
export default function SurveyPage() {
const router = useRouter()
const surveyData = {
customer_id: '12345',
email: 'user@example.com',
transaction_id: 'tx_' + Date.now()
}
const handleSurveyComplete = (userId) => {
console.log('Survey completed!', userId)
router.push('/thank-you')
}
return (
<div style={{ padding: '20px' }}>
<h1>Customer Satisfaction Survey</h1>
<SoluCXWidget
soluCxKey="your-survey-key"
widgetType="inline"
widgetData={surveyData}
widgetOptions={{ width: 700, height: 500 }}
onComplete={handleSurveyComplete}
/>
</div>
)
}
1. Create a wrapper component (survey-widget.component.ts):
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() {
// Import the web component
await import('solucx-survey-widget')
// Add event listeners
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)
})
}
}
2. Use in your component (survey.component.ts):
import { Component } from '@angular/core'
import { Router } from '@angular/router'
@Component({
selector: 'app-survey',
template: `
<div class="survey-container">
<h2>Customer Feedback</h2>
<app-survey-widget
[soluCxKey]="surveyKey"
widgetType="inline"
[widgetData]="surveyData"
[widgetOptions]="surveyOptions"
(widgetCompleted)="onSurveyCompleted($event)"
(widgetError)="onSurveyError($event)"
></app-survey-widget>
</div>
`,
styles: [`
.survey-container {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
`]
})
export class SurveyComponent {
surveyKey = 'your-survey-key'
surveyData = {
customer_id: '12345',
email: 'user@example.com',
name: 'John Doe'
}
surveyOptions = {
width: 600,
height: 400
}
constructor(private router: Router) {}
onSurveyCompleted(userId: string) {
console.log('Survey completed by:', userId)
this.router.navigate(['/thank-you'])
}
onSurveyError(error: string) {
console.error('Survey error:', error)
// Handle error
}
}
3. Update your module (app.module.ts):
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { SurveyWidgetComponent } from './survey-widget.component'
@NgModule({
declarations: [
SurveyWidgetComponent
],
imports: [BrowserModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
The widget emits the following events:
| Event | Description | Payload |
|---|---|---|
widgetOpened | Widget is displayed | userId: string |
widgetClosed | Widget is closed | - |
widgetCompleted | Survey completed | userId: string |
widgetError | Error occurred | error: string |
widgetResized | Widget height changed | height: number |
widgetPageChanged | Survey page changed | page: string |
inline: Embedded directly in page contentmodal: Overlay modal with backdropbottomBar: Fixed bottom bar across full widthbottomBox: Fixed bottom-right corner boxbottomBoxLeft: Fixed bottom-left corner box# Install dependencies
npm install
# Run tests
npm test
# Build for production
npm run build
For support and questions, please contact the SoluCX team or refer to the official documentation.
FAQs
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 ha
The npm package solucx-survey-widget receives a total of 56 weekly downloads. As such, solucx-survey-widget popularity was classified as not popular.
We found that solucx-survey-widget demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Company News
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.

Research
/Security News
Malicious Packagist packages disguised as Laravel utilities install an encrypted PHP RAT via Composer dependencies, enabling remote access and C2 callbacks.

Research
/Security News
OpenVSX releases of Aqua Trivy 1.8.12 and 1.8.13 contained injected natural-language prompts that abuse local AI coding agents for system inspection and potential data exfiltration.