How to Configure the SoluCX Widget

Introduction

What is the SoluCX Widget

The SoluCX Widget is a feedback collection tool that allows you to integrate satisfaction surveys directly into websites, applications, and digital platforms. Through it, you can capture customer ratings in real time using metrics such as NPS (Net Promoter Score), CSAT (Customer Satisfaction Score), and CES (Customer Effort Score).

The widget is compatible with two types of surveys:

  • Flex Survey: Flexible and customizable forms
  • Survey (Smart Survey): System-generated intelligent surveys

Overview: Platform vs Code

SoluCX Widget configurations are divided into two domains:

DomainExamplesWho configures
PlatformLogo, colors, input types, thank you screen, IP/CPF quarantineBusiness team or administrators
CodeWidget type, customer data, callbacks, dimensions, retryDevelopment team
BothCustom CSS, quarantine (platform + code)Collaboration between teams

Styling Configurations

Visual Identity (Platform)

Visual identity configurations are managed exclusively through the SoluCX administrative platform:

ConfigurationDescriptionWhere to configure
Logo and brandLogo upload displayed in the widget headerPlatform > Settings > Visual Identity
Main colorsPrimary and secondary widget colorsPlatform > Settings > Colors
Dynamic colorsColors that change based on customer score (e.g., red for detractors, green for promoters)Platform > Settings > Dynamic Colors
Form Builder themesPre-defined visual themes for flexible formsPlatform > Form Builder > Themes

Rating Input Types (Platform)

The widget supports various rating input types, all configurable through the platform. You can edit them the same way you edit the Smart Survey or Flex Survey:

NPS (Net Promoter Score)

Scale from 0 to 10 measuring likelihood of recommendation.

Input TypeDescription
ArrowSliding arrow input on 0-10 scale
ButtonsIndividual numeric buttons from 0 to 10
SliderContinuous sliding bar from 0 to 10
Colored ButtonsButtons with color gradient (red to green)
GradientVisual scale with color gradient

CSAT (Customer Satisfaction Score)

Measures direct customer satisfaction with a product or service.

Input TypeScaleDescription
Emoticons1-5Expressive faces from dissatisfied to very satisfied
Stars1-5Classic star rating
Buttons 1-51-5Numeric buttons from 1 to 5
Buttons 1-101-10Numeric buttons from 1 to 10

CES (Customer Effort Score)

Measures the customer's effort to solve a problem or complete an action.

Input TypeDescription
EmoticonExpressive faces representing effort level
ButtonsButtons with effort scale
StarsStar rating of ease level

Custom CSS

Advanced styling can be done in two ways:

Via Platform (customStyle)

The platform allows inserting custom CSS that will be applied internally to the widget iframe:

  • Go to Platform > Settings > Journeys
  • Insert CSS rules that will be injected inside the widget
  • Useful for fine-tuning fonts, spacing, and internal colors

Via Code (options)

To style the widget's external container (position, dimensions, borders), use the code parameters:

const options = {
    width: 600,
    height: 400
};

Positioning and Dimensions (Code)

Widget positioning is controlled by the type parameter during initialization:

Widget Types

Embedded in page content

The widget integrates into the natural layout flow, without overlapping other elements.

createSoluCXWidget(apiKey, "inline", data, {
    target: "my-container",
    width: 600,
    height: 400
});
<div id="my-container"></div>
  • Respects DOM position
  • Ideal for dedicated feedback pages
  • Requires a target element for rendering

Dimension Parameters

widthnumber
Widget width in pixels. Default: 100%
heightnumber
Widget height in pixels. Default: auto
targetstring
DOM element ID for inline widgets. Default: null

Behavior Configurations

Thank You Screen (Platform)

After the customer responds to the survey, a thank you screen is displayed. The following configurations are managed through the platform:

showThanksScreenboolean
Show or hide the thank you screen
successTitlestring
Success screen title
successMessagestring
Main thank you message
thanksMessagestring
Complementary thank you message
dateTimeMessagestring
Message with rating date/time
showInHouseAdsboolean
Show internal ads on the thank you screen
customAcknowledgmentHTMLstring
Custom HTML for the thank you screen

Redirection and Automation (Platform)

ConfigurationDescription
completedUrlRedirectionURL for redirection after survey completion
autoSendTimeoutTime (in seconds) for automatic partial survey submission

Practical use cases:

  • E-commerce: Redirect to a discount coupon page after a positive rating
  • Customer service: Redirect to FAQ page after feedback collection
  • Auto-send: Ensure partial collection if the customer abandons the survey

Configurations related to GDPR/LGPD and user consent:

ConfigurationDescription
Custom contact consent textCustom acceptance terms text
Consent pre-checked by defaultWhether the consent checkbox comes pre-checked
Acceptance strategyAcceptance strategy (e.g., opt-in, opt-out)

Contact Channels (Platform)

Configurations to enable contact channel requests based on respondent classification:

ConfigurationDescription
Contact consent by channel if detractorRequest contact if the customer is a detractor (NPS 0-6)
Contact consent by channel if neutralRequest contact if the customer is neutral (NPS 7-8)
Contact consent by channel if promoterRequest contact if the customer is a promoter (NPS 9-10)

Quarantine System

The quarantine system controls how frequently the same customer is asked to respond to surveys, avoiding survey fatigue.

Platform Quarantine

Configurations managed through the administrative platform:

ConfigurationDescription
Cookie quarantineEnables cookie-based browser quarantine
IP quarantineIP-based quarantine period (in days)
CPF quarantineCPF-based quarantine period (in days)
Fingerprint antifraudDevice fingerprint-based quarantine period (in days)
Fingerprint API keyFingerprint API key
Enable fingerprint collectionEnables device fingerprint collection

Code Quarantine

Configurations defined in the options parameters during widget initialization:

ConfigurationTypeDefaultDescription
retry.attemptsnumber3Number of widget display attempts before giving up
retry.intervalnumber1Interval (in days) between collection attempts
waitDelayAfterRatingnumber60Time (in days) for the widget to reappear after a rating

Quarantine Flow

The quarantine system follows this logic:

  1. First display: Widget appears normally
  2. Customer doesn't respond: After the interval configured in retry.interval, the widget tries again
  3. Attempts exhausted: After retry.attempts without response, the widget stops appearing
  4. Customer responds: After the rating, the widget enters quarantine for waitDelayAfterRating days
  5. End of quarantine: After the period, the widget can be displayed again
const options = {
    retry: {
        attempts: 5,
        interval: 2
    },
    waitDelayAfterRating: 30
};

Code Integration

Required Parameters

The createSoluCXWidget function requires two mandatory parameters:

apiKey (string)

API key provided by SoluCX that identifies your instance. Obtained in the administrative platform at Settings > API.

const apiKey = "YOUR_API_KEY";

type (string)

Defines the widget display mode:

ValueDescription
inlineEmbedded in page content
bottomBarFixed bar at the bottom
bottomBoxFixed box in the bottom right corner
bottomBoxLeftFixed box in the bottom left corner
modalCentered modal on the page
createSoluCXWidget(apiKey, type, data, options);

Customer Data (data)

The data object contains customer and transaction information:

Identification Fields

transaction_idstring
External transaction ID provided by the client.
customer_idstring
Customer ID. Required if not providing transaction_id OR name AND (email OR phone)
form_idstring
Form ID. Required only for Flex Survey Forms

Personal Data

namestring
Customer name. Required if not providing transaction_id OR customer_id
emailstring
Customer email. Required if not providing transaction_id OR customer_id AND phone
phonestring
Customer phone. Required if not providing transaction_id OR customer_id AND email
phone2string
Customer secondary phone.
documentstring
Customer document (CPF, CNPJ, etc).
birth_datestring
Customer birth date. Format: YYYY-MM-DD

Contextual Data

store_idstring
Store/unit ID. Required if not providing transaction_id
store_namestring
Store/unit name.
employee_idstring
Employee ID.
employee_namestring
Employee name.
amountnumber
Transaction amount.
scorenumber
Customer score.
journeystring
Customer journey. Required if more than one journey is registered for the instance.

Custom Parameters

Any field prefixed with param_ is considered an extra transaction parameter for traceability.
const data = {
    name: "John Smith",
    email: "[email protected]",
    store_id: "store-001",
    param_channel: "website",
    param_campaign: "black-friday",
    param_region: "southeast"
};

Configuration Options (options)

Options Parameter

Additional options for widget configuration.
targetstring|null
For inline widgets, defines the DOM element ID where the widget will be inserted.
widthnumber
Widget width in pixels. Default: 100%.
heightnumber
Widget height in pixels. Default: automatic.
retryobject
Retry configuration. attempts: number of attempts. interval: interval in days between attempts.
waitDelayAfterRatingnumber
Time (in days) for the widget to reappear after response. Default: 60.
callbacksobject
Object with callback functions for widget events.
interface WidgetOptions {
    target?: string | null;
    width?: number;
    height?: number;
    retry?: {
        attempts?: number;
        interval?: number;
    };
    waitDelayAfterRating?: number;
    callbacks?: WidgetCallbacks;
}

Callback System

The widget supports callbacks for survey lifecycle events:

CallbackParameterDescription
onOpeneduserId: stringWidget was opened/displayed
onClosedWidget was closed by the user
onCompleteduserId: stringSurvey completed successfully
onPartialCompleteduserId: stringSurvey partially completed
onErrormessage: stringAn error occurred in the widget
onPageChangedpage: stringUser navigated to another page within the widget
onQuestionAnsweredUser answered a question. Works only for Flex Survey
onResizeheight: numberWidget was resized
const options = {
    callbacks: {
        onOpened: (userId) => {
            console.log("Widget opened for:", userId);
            analytics.track("widget_opened", { userId });
        },
        onCompleted: (userId) => {
            console.log("Survey completed:", userId);
            analytics.track("survey_completed", { userId });
        },
        onPartialCompleted: (userId) => {
            console.log("Partial survey:", userId);
        },
        onError: (message) => {
            console.error("Widget error:", message);
            errorTracker.capture(message);
        },
        onClosed: () => {
            console.log("Widget closed");
        },
        onPageChanged: (page) => {
            console.log("Page changed:", page);
        },
        onQuestionAnswered: () => {
            console.log("Question answered");
        },
        onResize: (height) => {
            console.log("New height:", height);
        }
    }
};

Response Handling

The createSoluCXWidget function returns a Promise:

createSoluCXWidget(apiKey, type, data, options)
    .then(response => {
        console.log(response); // { status: "success" }
    })
    .catch(error => {
        console.log(error); // WidgetError { status: "error", message: "Error message" }
    });

Complete Comparison Table

Styling

FeaturePlatformCodeDescription
Logo and brandLogo upload and configuration
Main colorsPrimary and secondary colors
Dynamic colorsColors based on customer score
Form Builder themesPre-defined visual themes
Input type (NPS/CSAT/CES)Visual style of the rating scale
Internal CSS (customStyle)CSS inside the widget iframe
Widget typeinline, bottomBar, bottomBox, modal
Dimensions (width/height)Container width and height
Target elementDOM element ID for inline

Behavior

FeaturePlatformCodeDescription
Thank you screenPost-survey messages and HTML
RedirectionRedirect URL after completion
Auto-send (timeout)Automatic submission after time
Acceptance textConsent terms customization
Acceptance strategyOpt-in vs opt-out
Contact channelsRequest contact by classification
Hide creditsRemove "Powered by SoluCX"
Lock scrollBlock scrolling during display
Allow HTMLHTML in questions and descriptions
LanguageWidget language
CallbacksFunctions for widget events

Quarantine

FeaturePlatformCodeDescription
Cookie quarantineBased on browser cookies
IP quarantineBased on IP address
CPF quarantineBased on CPF document
Fingerprint quarantineBased on device fingerprint
RetriesNumber of attempts and interval
Post-rating delayWait time after response

Data and Integration

FeaturePlatformCodeDescription
API KeyAuthentication key
Widget typeDisplay mode
Customer dataName, email, phone, etc
Transaction dataID, amount, store, employee
Custom parameters (param_*)Extra fields for traceability
JourneyCustomer journey identifier

Practical Guides

Common Scenarios

Post-Purchase E-commerce

Ideal for collecting feedback after order completion:

const apiKey = "YOUR_API_KEY";
const type = "bottomBox";
const data = {
    transaction_id: "order-12345",
    name: "Maria Smith",
    email: "[email protected]",
    store_id: "main-ecommerce",
    amount: 299.90,
    journey: "post-purchase",
    param_product: "Smartphone XYZ",
    param_category: "Electronics"
};
const options = {
    width: 400,
    retry: { attempts: 3, interval: 2 },
    waitDelayAfterRating: 30,
    callbacks: {
        onCompleted: (userId) => {
            dataLayer.push({
                event: "survey_completed",
                userId: userId
            });
        }
    }
};

createSoluCXWidget(apiKey, type, data, options);

Customer Service

For collecting feedback after support interactions:

const apiKey = "YOUR_API_KEY";
const type = "modal";
const data = {
    name: "Carlos Oliveira",
    email: "[email protected]",
    store_id: "support-center",
    employee_id: "agent-42",
    employee_name: "Ana Souza",
    journey: "post-service",
    param_ticket: "2024-ABC-789",
    param_channel: "chat"
};
const options = {
    callbacks: {
        onCompleted: () => {
            window.location.href = "/feedback-thanks";
        },
        onClosed: () => {
            console.log("Customer closed service survey");
        }
    }
};

createSoluCXWidget(apiKey, type, data, options);

Physical Store Survey (Kiosk/Tablet)

For in-person feedback collection on dedicated devices:

const apiKey = "YOUR_API_KEY";
const type = "inline";
const data = {
    store_id: "store-downtown",
    store_name: "Downtown Store",
    journey: "store-experience",
    param_kiosk: "kiosk-entrance-01"
};
const options = {
    target: "survey-container",
    width: 800,
    height: 600,
    waitDelayAfterRating: 0,
    retry: { attempts: 1, interval: 0 },
    callbacks: {
        onCompleted: () => {
            setTimeout(() => {
                location.reload();
            }, 5000);
        }
    }
};

createSoluCXWidget(apiKey, type, data, options);

Web Application Feedback

For integration in web panels/dashboards:

const apiKey = "YOUR_API_KEY";
const type = "inline";
const data = {
    customer_id: "usr-98765",
    name: "Pedro Santos",
    email: "[email protected]",
    journey: "platform-usage",
    param_plan: "enterprise",
    param_feature: "reports"
};
const options = {
    target: "feedback-section",
    width: 600,
    callbacks: {
        onOpened: (userId) => {
            console.log("Survey displayed for:", userId);
        },
        onCompleted: (userId) => {
            showNotification("Thank you for your feedback!");
        },
        onResize: (height) => {
            document.getElementById("feedback-section").style.height = height + "px";
        }
    }
};

createSoluCXWidget(apiKey, type, data, options);

Best Practices

When to use each widget type

TypeBest forAvoid when
inlineDedicated pages, kiosks, iframesYou don't want to take up layout space
bottomBarPassive collection, content sitesMany fixed elements in the footer
bottomBoxE-commerce, post-transactionSite has chat in the same corner
bottomBoxLeftAlternative to bottomBoxSite has left sidebar menu
modalMandatory surveys, post-serviceExperiences that cannot be interrupted

Combining Platform and Code Configurations

  1. Set up visual identity on the platform before implementing the code
  2. Configure quarantine on the platform for robust control (IP, CPF, fingerprint)
  3. Supplement with code quarantine for additional cookie-based control
  4. Use code callbacks to integrate with analytics and internal systems
  5. Customize CSS on the platform for fine visual adjustments

Quarantine Optimization

  • Testing environment: Use waitDelayAfterRating: 0 and retry.attempts: 1 for easier testing
  • Production: Recommended waitDelayAfterRating: 30-60 days to avoid fatigue
  • Kiosks/Tablets: Use waitDelayAfterRating: 0 to allow consecutive ratings from different customers
  • Combine methods: Use platform IP quarantine + code cookie quarantine for maximum coverage

Troubleshooting

Widget doesn't appear

ProblemCheckSolution
Invalid API KeyBrowser consoleVerify the key in the administrative platform
Missing required dataBrowser consoleFill in name or customer_id
Active quarantineBrowser cookiesClear cookies or reduce waitDelayAfterRating for testing
Target element doesn't existDOM inspectorVerify the target ID exists before calling the widget
Script not loadedNetwork tabConfirm widget.js loaded successfully

CSS and positioning issues

ProblemLikely causeSolution
Widget cut offContainer with overflow: hiddenRemove overflow: hidden from parent container
Widget behind other elementsLow z-indexAdjust z-index via custom CSS on the platform
Widget not responsiveFixed widthDon't set width or use percentage values
Scroll locked after closinglockScroll activeDisable lockScroll on the platform if needed

Debugging callbacks

const options = {
    callbacks: {
        onOpened: (userId) => console.log("[DEBUG] Opened:", userId),
        onClosed: () => console.log("[DEBUG] Closed"),
        onCompleted: (userId) => console.log("[DEBUG] Completed:", userId),
        onPartialCompleted: (userId) => console.log("[DEBUG] Partial:", userId),
        onError: (msg) => console.error("[DEBUG] Error:", msg),
        onPageChanged: (page) => console.log("[DEBUG] Page:", page),
        onQuestionAnswered: () => console.log("[DEBUG] Question answered"),
        onResize: (h) => console.log("[DEBUG] Resize:", h)
    }
};

Complete Code Examples

Basic Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>SoluCX Widget - Basic</title>
    <script src="https://widget.solucx.com.br/widget.js"></script>
</head>
<body>
    <script>
        createSoluCXWidget("YOUR_API_KEY", "bottomBox", {
            name: "Customer Name",
            email: "[email protected]",
            store_id: "store-001"
        });
    </script>
</body>
</html>

Advanced Example with All Parameters

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>SoluCX Widget - Advanced</title>
    <script src="https://widget.solucx.com.br/widget.js"></script>
</head>
<body>
    <div id="widget-container"></div>

    <script>
        const apiKey = "YOUR_API_KEY";
        const type = "inline";

        const data = {
            transaction_id: "TXN-2024-001",
            form_id: "form-flex-001",
            customer_id: "CLI-12345",
            name: "Maria Smith",
            email: "[email protected]",
            phone: "11999887766",
            phone2: "1133445566",
            document: "123.456.789-00",
            birth_date: "1990-05-15",
            store_id: "downtown-store",
            store_name: "Downtown Store",
            employee_id: "emp-042",
            employee_name: "Ana Souza",
            amount: 1599.90,
            score: 8,
            journey: "post-purchase",
            param_channel: "website",
            param_campaign: "summer-2024",
            param_category: "electronics"
        };

        const options = {
            target: "widget-container",
            width: 700,
            height: 500,
            retry: {
                attempts: 5,
                interval: 2
            },
            waitDelayAfterRating: 30,
            callbacks: {
                onOpened: (userId) => {
                    console.log("Widget opened for:", userId);
                },
                onCompleted: (userId) => {
                    console.log("Survey completed by:", userId);
                },
                onPartialCompleted: (userId) => {
                    console.log("Partial survey from:", userId);
                },
                onError: (message) => {
                    console.error("Error:", message);
                },
                onClosed: () => {
                    console.log("Widget closed");
                },
                onPageChanged: (page) => {
                    console.log("Page:", page);
                },
                onQuestionAnswered: () => {
                    console.log("Question answered");
                },
                onResize: (height) => {
                    console.log("New height:", height);
                }
            }
        };

        createSoluCXWidget(apiKey, type, data, options)
            .then(response => console.log("Success:", response))
            .catch(error => console.error("Error:", error));
    </script>
</body>
</html>

Example with Callbacks and Analytics

function initSoluCXWidget(customerData) {
    const apiKey = "YOUR_API_KEY";
    const type = "bottomBox";

    const data = {
        ...customerData,
        journey: "post-purchase"
    };

    const options = {
        width: 400,
        retry: { attempts: 3, interval: 1 },
        waitDelayAfterRating: 60,
        callbacks: {
            onOpened: (userId) => {
                gtag("event", "widget_opened", {
                    event_category: "SoluCX",
                    event_label: userId
                });
            },
            onCompleted: (userId) => {
                gtag("event", "survey_completed", {
                    event_category: "SoluCX",
                    event_label: userId
                });
                showThankYouBanner();
            },
            onError: (message) => {
                Sentry.captureMessage("SoluCX Widget Error: " + message);
            },
            onClosed: () => {
                gtag("event", "widget_closed", {
                    event_category: "SoluCX"
                });
            }
        }
    };

    return createSoluCXWidget(apiKey, type, data, options);
}

initSoluCXWidget({
    name: "John Smith",
    email: "[email protected]",
    store_id: "store-01",
    amount: 150.00,
    param_order: "ORD-9876"
});

Technical References

Available SDKs

SDKTechnologyPackage
JavaScript WidgetVanilla JavaScriptwidget.js (CDN)
React Native SDKReact Native / Expo@solucx/react-native-solucx-widget
Web Component SDKVue.js / Web Componentssolucx-survey-widget
Flutter SDKFlutter / Dartsolucx_widget

Script URL

https://widget.solucx.com.br/widget.js

Support

For questions or issues with widget integration, contact SoluCX support through the administrative platform or via the support email.