The Frill Script

Controlling widgets programmatically

Once a Frill widget is loaded, you can control it programmatically—open or close it, navigate to specific sections, trigger idea creation, and respond to user actions like login or badge count updates.

Before you begin: You need the Frill Script installed and a widget instance loaded. See Installing the Frill Script for setup.

Getting a widget instance

To control a widget, you need a reference to it. The Frill('widget', {...}) method returns a widget instance:

const widget = await window.Frill('widget', {
  key: 'YOUR_WIDGET_KEY',
  callbacks: {
    onReady: (widgetInstance) => {
      console.log('Widget ready:', widgetInstance);
    }
  }
});

This loads a widget manually, ignoring targeting rules. Use this when you want to trigger widgets based on custom logic (like a button click).

Widget control methods

Once you have a widget instance, you can call these methods:

Open and close

  • widget.open() — Opens the widget

  • widget.close() — Closes the widget

  • widget.toggle() — Opens if closed, closes if open

Navigate to sections

  • widget.viewSection('ideas') — Show the ideas/feedback section

  • widget.viewSection('roadmap') — Show the roadmap section

  • widget.viewSection('announcements') — Show announcements

View specific content

  • widget.viewIdea('idea-slug') — Open a specific idea by its slug

  • widget.viewAnnouncement('announcement-slug') — Open a specific announcement

Create ideas

  • widget.createIdea({ name: 'Feature request', topics: ['mobile'] }) — Pre-fill the idea creation form

Badge count

  • widget.setBadgeCount(5) — Manually set the unread announcement badge count

Cleanup

  • widget.destroy() — Remove the widget from the page completely

Widget events

Listen to widget events to react to user actions or state changes. Pass callbacks when initializing the widget:

const widget = await window.Frill('widget', {
  key: 'YOUR_WIDGET_KEY',
  callbacks: {
    onReady: (widget) => {
      console.log('Widget loaded');
    },
    onOpen: () => {
      console.log('User opened widget');
    },
    onClose: () => {
      console.log('User closed widget');
    },
    onLogin: ({ user }) => {
      console.log('User logged in:', user.email);
    },
    onLogout: () => {
      console.log('User logged out');
    },
    onBadgeCount: ({ count, announcements }) => {
      console.log(`${count} unread announcements`);
    },
    onNotificationOpen: () => {
      console.log('Notification opened');
    },
    onNotificationClose: () => {
      console.log('Notification closed');
    },
    onDestroy: () => {
      console.log('Widget destroyed');
    }
  }
});

You can also subscribe to events after initialization:

widget.events.on('open', () => {
  console.log('Widget opened');
});

// Later, unsubscribe:
widget.events.unsubscribe('open');

Example: Custom launcher button

Load a widget manually and trigger it with your own button:

// Initialize with autoLoad: false to prevent auto-loading
window.Frill('container', {
  key: 'YOUR_CONTAINER_KEY',
  autoLoad: false
});

// Load widget on button click
document.querySelector('#feedback-button').addEventListener('click', async () => {
  const widget = await window.Frill('widget', {
    key: 'YOUR_WIDGET_KEY'
  });
  widget.open();
});

For complete technical reference including all methods and callbacks, see the official Frill Script documentation.

Was this helpful?