Quickstart

Add the chat widget to any site with one script tag. It works on localhost with no setup.

The chat widget lets visitors message you from your site or app. Messages arrive in your Ticketping inbox and your Slack channel, and you reply from either.

You handle two values in total:

ValueWhere it goesWhere to find it
Publishable key (pk_...)In your page. It’s publicSettings → Widgets
TICKETPING_IDENTITY_SECRETOn your server only. Needed only to identify signed-in usersSettings → API → Identity secret

Both are the same in local development, staging and production.

Add the script tag

Copy your publishable key from Settings → Widgets and add this before </body>:

html
<script src="https://widget.ticketping.com/v2/loader.js" data-key="pk_..." async></script>

The loader is under 2 KB. It loads the widget when the browser is idle, or right away if your page opens it.

Until 2.0.0 is released, /v2/loader.js isn’t published. To try a beta, use the pinned install with the beta version, or install @ticketping/chat-widget@next from npm.

Try it on localhost

Open your site on localhost, 127.0.0.1 or [::1], on any port. There’s nothing to configure.

  1. Click the launcher and send a message.
  2. It appears in your inbox and in the widget’s Slack channel, marked as a test conversation.
  3. Reply in the Slack thread. The reply shows up in the widget.

Conversations from localhost are tagged TEST in the dashboard and [TEST] in Slack, left out of reports, and deleted after 30 days. Your real users never see them.

Identify signed-in users

If your site has logins, tell the widget who the user is. They then see their past conversations on every device, and your team sees who they’re talking to.

html
<script>
  window.Ticketping ||= (...args) => (Ticketping.q ||= []).push(args)

  Ticketping('identify', {
    userId: 'u_123',
    email: 'ada@acme.com',
    name: 'Ada Lovelace',
    getToken: async () => {
      const res = await fetch('/api/ticketping-token', { method: 'POST' })
      if (!res.ok) throw new Error(`Ticketping token request failed (${res.status})`)
      return res.text()
    }
  })
</script>

Render the user’s values from your server template, and only for signed-in users. The first line lets you call Ticketping(...) before the loader has run. Calls wait in a queue until the widget loads.

getToken calls a small route on your server that signs a short-lived token for the signed-in user. Identity verification shows that route for your stack, in about 15 lines.

Before you go live

  • Lock allowed domains. While domains are unlocked, the widget works on any https:// site and records where it was seen. Allow the domains you expect, then lock them. See Security and CSP.
  • Require verified identity if you identify users, so nobody can claim to be someone else.
  • Match your brand in the widget editor: accent color, texts, launcher. You can also set them in code.

Neither value changes when you go live.

Install for your framework

Copy prompt for your AI coding agent

Paste this into Cursor, Claude Code or another coding agent. It does the steps above.

prompt
Add the Ticketping chat widget (v2) to this project.

Docs index: https://ticketping.com/llms.txt
This page as Markdown: https://ticketping.com/docs/install-chat-widget.md

1. Find the HTML layout every page shares and add this before </body>:
   <script src="https://widget.ticketping.com/v2/loader.js" data-key="pk_..." async></script>
   Ask me for the publishable key (it starts with pk_). It is public and the same in every environment.
2. If this project has signed-in users, follow the identity verification docs for this stack
   (https://ticketping.com/docs/authentication.md): add a POST /api/ticketping-token route that signs
   { sub, email, name, exp: now + 300 } with HS256 using the TICKETPING_IDENTITY_SECRET env var, and call
   Ticketping('identify', { userId, email, name, getToken }) for the signed-in user.
   Never put the secret in client code or commit it.
3. Tell me how to test: run the site on localhost, send a message from the widget, and check that it shows up in Ticketping marked as a test conversation.