Skip to main content
The widget is one script with no dependencies. Loading it defines a global Feddy object with four methods and one callback, and this page is the complete list.
The script can be loaded from any site; it’s served with a one-hour cache and open CORS. The widget draws itself inside a shadow root attached to div#feddy-widget, which means it keeps its own styles: your page’s CSS never affects it and its CSS never affects your page. Keyboard events inside the widget don’t reach your page either.

Feddy.init(options)

Sets the widget up on the page. It only takes effect once per page load; later calls do nothing. If the page is still loading when you call it, the widget waits and appears once the page is ready. Without a project ID it logs [Feddy] init requires a projectId and does nothing.

Feddy.identify(options)

Tells Feddy which of your users is on this browser. You can call it before init; the call is held and sent once the widget is ready. Does nothing without userId. If something goes wrong, it logs a warning with console.warn and never throws. What happens on the server, including how records from different devices merge, is in Identify users.

Feddy.open() and Feddy.close()

Open or close the panel from your own element. open() shows the user’s conversations and a button to start a new one. Both do nothing until init has set the widget up.

Feddy.onUnreadCountChanged

A function the widget calls whenever the unread count changes. The widget checks every 45 seconds and again each time the tab becomes visible. Use it to drive your own badge when the floating button is off.

What happens on its own

  • Identity: the first time the widget runs, it creates an anonymous ID and stores it in localStorage under feddy_anon_id. Clearing site data resets it, which is why the widget offers to collect an email after a first message when your project has a verified email domain.
  • Language: the widget ships in English, Simplified Chinese, Traditional Chinese, Japanese, Korean, German, French, Spanish, Brazilian Portuguese, and Russian, and follows the browser language. zh-TW, zh-HK, and zh-MO resolve to Traditional Chinese; pt resolves to Brazilian Portuguese. Other languages fall back to English. Text you write in the dashboard, such as topics, is translated on the server according to your project settings.
  • Attachments: up to 5 images per message, 10 MB each before resizing. The browser resizes them so the longest edge is 2000 px and converts them to WebP before upload.
  • Screenshots: a camera button in the message box attaches a picture of the page as the visitor sees it, with the widget itself left out. It’s made in the browser with no permission prompt. Images from other sites, videos, and embedded frames show as grey boxes, and web fonts fall back to system fonts, which is enough to show which screen and what state. The button is hidden when attachments aren’t available on your plan.
  • Branding: the name, accent color, and logo users see come from the dashboard. The accent color is applied as --fd-accent inside the shadow root, and the widget picks a readable text color to go with it.
  • Reply popups: when a reply the visitor hasn’t seen is waiting, a card appears above the floating button saying who replied, with the first two lines of the latest reply. Clicking it opens that conversation; the close button dismisses it. If several replies are waiting, only the newest shows. Each reply shows at most once per browser, only replies from the last 14 days, and never while the panel is open. It checks shortly after the page loads, when the tab becomes visible again, and when a new reply arrives.
  • Floating button: fixed bottom-right, 56 px, with an unread count badge. Its z-index is 2147483000, so it sits above everything on the page.