Skip to content

Feedback widget: install and identify users

Last updated October 24, 2026

The Camelus widget is a small feedback button for your site or app. Visitors write a message, optionally tag it as a bug, idea or question, and leave their email if they want to hear back. It shows up in your Inbox right away.

Install

Open Settings → Products → your product → Feedback widget and copy the snippet. It looks like this:

<script src="https://camelus.si/w/v1.js" data-key="pk_live_…" async></script>
<script>
  window.camelus = window.camelus || function(){(camelus.q=camelus.q||[]).push(arguments)};
</script>

Paste it before the closing </body> tag. The script loads asynchronously and never blocks your page. It's under 15 KB gzipped.

Then add your site to Allowed origins, for example https://habits.app. The widget only accepts feedback from these exact origins: scheme, host and port must match, so add https://www.habits.app separately if you use it. For local testing, turn on Allow localhost.

The pk_live_ key is public by design. It can only send feedback and read the widget's look, and only from your allowed origins.

Identify signed-in users

If your visitors are signed in, tell the widget who they are. Their feedback is then linked to the same person across messages, and the email field is hidden:

camelus('identify', { id: 'u_123', email: 'ana@example.com', name: 'Ana', hash: 'HASH_FROM_YOUR_SERVER' });

Anyone can call identify from the browser console, so Camelus only trusts an identity it can verify. Create an identity secret in the widget settings (it's shown once) and compute the hash on your server:

// Node.js
import crypto from "node:crypto";
const hash = crypto.createHmac("sha256", process.env.CAMELUS_IDENTITY_SECRET).update(user.id).digest("hex");
# Python
import hmac, hashlib, os
hash = hmac.new(os.environ["CAMELUS_IDENTITY_SECRET"].encode(), user_id.encode(), hashlib.sha256).hexdigest()
// PHP
$hash = hash_hmac('sha256', $user->id, getenv('CAMELUS_IDENTITY_SECRET'));

Verified identities weigh more when themes are ranked. Without a valid hash, the identity is kept as an unverified claim: it never attaches feedback to a person someone else verified.

Open it from your own button

Add data-headless="true" to the script tag to hide the floating button, then open the form yourself:

document.querySelector('#feedback').addEventListener('click', () => camelus('open'));
// Preselect a type: bug, idea, question or other
camelus('open', { type: 'bug' });

Add context

Send flat key/value details with each message (at most 2 KB, strings and numbers only):

camelus('meta', { plan: 'pro', app_version: '2.3.1' });

The widget also records the page URL (without query string or fragment), page title, viewport, browser and OS family, and language.

Customize

In the widget settings you can change the accent color, the position (bottom right or left), the language and every text. Data attributes on the script tag override the settings for one page: data-accent="#2563EB", data-position="left", data-locale="fr".

The widget speaks English, French, German, Spanish and Slovenian, and follows the visitor's browser language unless you pick one. It follows the visitor's light or dark preference, respects reduced motion, traps focus while open and closes with Escape.

Privacy

The widget sets no cookies, stores no identifiers and doesn't fingerprint visitors. The only thing it keeps is the unsent draft, in the tab's session storage. It renders in a Shadow DOM, so its styles never touch your page and yours never touch it.