TypeScript icon, indicating that this package has built-in type declarations

    1.1.5 • Public • Published

    WaiverForever Waiver Widget

    Adding a waiver widget to your website to allow participants to sign without leaving the page.



    1. Choose the preferred waiver templates from your templates.
    2. Go to Template Settings page -> Waiver Widget tab.
    3. Enable the widgets and configure them.
    4. Keep the templateIds for the next steps.
    5. There are multiple ways of embedding our waiver widget into your website:

    Want to add it to your WordPress website? Click here to see our tutorial.

    Easy route: reference the widget script from CDN:

    We can load the widget automatically or manually.

    For automatically loading, append the following HTML snippet into the body tag of your website:

    <script src="https://cdn.waiverforever.com/qs3/ew.js?templateId=${templateId1,templateId2}"></script>
    1. Widget with its trigger button will be mounted as soon as the script is loaded. It exposes the widget instance as a global JavaScript variable named waiverWidget (note: its initial letter is lowercase) and WF_EMBED_WAIVER (for backward compatibility).
    2. If you need multiple waivers be signed one by one, you can set multiple template IDs by join them with comma.
    3. The widget instance has a hook method .onReady, which you can use to perform extra operations if needed.
    4. If you don't like the default triggering button and want to create your own way to trigger the waiver modal, simply adding a query sdkMode=yes to disable it:
      <script src="https://cdn.waiverforever.com/qs3/ew.js?templateId=${templateId1,templateId2}&sdkMode=yes"></script>

    For manually loading, append the following HTML snippet into the body tag of your website:

    <script src="https://cdn.waiverforever.com/qs3/ew.js"></script>
    1. If the script's src doesn't contain a specified templateId, the script exposes the widget constructor as a global JavaScript variable named WaiverWidget (note: its initial letter is uppercase).
    2. You could manually initialize the widget instance on demand. Please make sure performing any extra operations after the .onReady hook is triggered.

    You could also load the widget script dynamically, e.g. The AMD way:

    require(['https://cdn.waiverforever.com/qs3/ew.js'], function (WaiverWidget) {
            const widget = new WaiverWidget({
                templateId: `${templateId}`, // You can also pass multiple template ids as an array, they will be displayed one after signing one.
                sdkMode: true
                myCustomButton.addEventListener('click', function () {

    Importing the widget into the module system

    Install the widget by npm or yarn:

    # npm
    npm i --save @waiverforever/waiver-widget
    # yarn
    yarn add @waiverforever/waiver-widget
    // app.js
    const WaiverWidget = require('@waiverforever/waiver-widget')
    const widget = new WaiverWidget()
    1. TypeScript is fully supported.
    2. Definitions bring TS/JS users the better developing experience.
    3. Could be used in ES modules or CommonJS standards systems.
    4. Could be dynamically loaded by third-party bundler's code splitting feature.



    • widget constructor: In manually loading or dynamically loading scenarios, the script exposes a constructor named WaiverWidget as a global variable. In a module system, we could require or import it directly.
    • widget instance: Instance of widget constructor. We could register events to its hooks and manipulate the instance through its methods.
    • SDK mode: Widget without the default triggering button, you need to programmatically trigger the waiver modal.
    • window mode: When enabled, instead of showing waiver modal, a new waiver page will be opened. If you passed multiple waiver template ID the window mode will be turn off.


    WaiverWidget constructor

    interface WidgetOption {
        templateId: string | string[];  // required, template id, or pass multiple ids
        sdkMode?: boolean;  // by default is false
        windowMode?: boolean; // by default it depends on the useragent (true for mobile devices, false for desktops)
        stylesheetURL?: string; // specify the stylesheet URL of the embedded waiver
    type WaiverWidgetConstructor = new (option?: WidgetOption): IWidget;


    const widget = new WaiverWidget({
        templateId: `${templateId}`,

    WaiverWidget instance

    interface IWidget {
        closeEmbedWaiverModal: () => void;  // Legacy API, for backward compatibility
        show: () => void; // Show widget modal and hide trigger button(in non-sdk mode)
        close: () => void; // Opposite operation of show()
        toggle: () => void; // Toggle between show and close methods
        destroy: () => void; // Destroy the current widget instance. After ensuring previous widget instance is destroyed, we can re-initialize another widget instance.
        onShowed: (callback: () => void) => void; // Event registry for modal showed hook
        onReady: (callback: (widget: IWidget) => void) => void; // Event registry for widget instance ready hook, an interactive widget instance will be passed to the registered hook
        onLoad: (callback: (signedCount: number) => void) => void; // Event registry for waiver page loading in the SDK mode
        onSigned: (callback: (signedCount: number) => void) => void; // Event registry for waiver signing success hook
        onClosed: (callback: (signedCount: number) => void) => void; // Event registry for modal close hook, the registered callback will receives a boolean type argument presents whether the user signed or not
        onDestroyed: (callback: () => void) => void; // Event registry for widget destroyed hook


    If you get bored of using the callback style .onReady hook and others, and the async/await syntax is available in your runtime, here are some tips for you.

    All of the widget APIs are thenable/awaitable! It means you can use the widget instance, instance methods and event hooks in a synchronous-like way.

    Thenable/awaitable instance

    Awaiting the response of the widget instance, we get a ready state (fully-interactive) instance.

    // note: use in async function, or some `top-level await` syntax implemented environment
    async function appDidMount () {
        const widget = await new WaiverWidget({
            templateId: `${templateId}`, // You can also pass multiple template ids  as an array, they will be displayed one after signing one.
        widget.show() // widget is in ready state

    Thenable/awaitable instance methods

    Awaiting a response of a widget method, we receive the callback payload of the method's corresponding event hook.

    async function appShowWaiverInstruction () {
        // `.onShowed` event has no return value
        await widget.show()
        sendLog('waiver showed')
    async function appCloseWaiverInstruction () {
        // We get the signed count, which is the `.onClosed` event's callback payload
        const signedCount = await widget.close()
        sendLog('waiver closed, with signed count: ' + signedCount)

    Thenable/awaitable event hooks

    A registered event handler will be triggered whenever the event occurs. An awaited event hook will only respond to the event payload for once.

    async function appDidMount () {
        // ... initialize widget instance ...
        widget.onSigned(async function () {
            // signedCount presents the number you signed successfully
            const signedCount = await widget.onClosed
            // Log will be sent under the condition that waiver is signed and then the modal is closed
            sendLog('waiver closed, with signed count: ' + signedCount)

    Actually, awaiting a response of a event hook is rarely used.


    npm i @waiverforever/waiver-widget

    DownloadsWeekly Downloads






    Unpacked Size

    214 kB

    Total Files


    Last publish


    • ll0jj0xx0
    • zheeeng