Skip to content

User authentication

The widget needs to know who is submitting a suggestion or opening a ticket. There are two ways to identify that person: login mode (SSO), when you already know who the logged-in user is on your site, and visitor mode, when there’s no login and the person identifies themself with their own email.

Both modes can coexist: sites with a logged-in area use SSO; visitors on public pages (landing page, blog, docs) use visitor mode. A site with no login system at all can rely solely on visitor mode.

If your site already authenticates the user, you can pass that identity to the widget to enable personalized features like voting and ticket history without asking the person for anything.

You generate a JWT on your server, signed with your app’s secret key (HMAC-SHA256). This token is passed to the widget via the data-user-token attribute on the script tag.

On the widget’s first initialization call, a user record is automatically created from the token claims.

ClaimTypeRequiredDescription
idstringYesUnique user identifier in your system.
namestringNoUser display name.
emailstringNoUser email.
avatar_urlstringNoURL to user avatar.

The secret key (sk_live_...) is found on the app details page. Never expose the secret key in the frontend — always generate the token on the server.

use Firebase\JWT\JWT;
$token = JWT::encode([
'id' => (string) $user->id,
'name' => $user->name,
'email' => $user->email,
], $secretKey, 'HS256');
const jwt = require('jsonwebtoken');
const token = jwt.sign({
id: String(user.id),
name: user.name,
email: user.email,
}, secretKey, { algorithm: 'HS256' });
import jwt
token = jwt.encode({
"id": str(user.id),
"name": user.name,
"email": user.email,
}, secret_key, algorithm="HS256")

Pass the generated token in the data-user-token attribute:

<script
src="https://pliic.com/widget/v1.js"
data-app-key="pk_live_xxx"
data-user-token="eyJhbGciOiJIUzI1NiJ9..."
async
></script>

Whenever data-user-token is present, the widget always uses login mode — even if visitor mode is enabled for the app.

If the site doesn’t send data-user-token, the widget opens in visitor mode. This happens automatically on any site without a login system, or on the public pages of a site that also has logged-in areas.

  1. A home screen with a short subtitle and three entries: See suggestions and vote (opens the public board, visible even without any identification), Suggest an improvement (opens the new suggestion form), and Talk to support (opens a new ticket or, if the person already has tickets, their list). Entries appear based on the modules enabled on the app.
  2. The person fills in the suggestion or ticket as usual. The email is only requested at submit time — the draft isn’t lost in the meantime, and this is the step where the notice that the email is only used to follow up on replies appears.
  3. A 6-digit code is sent to that email, valid for 15 minutes. The person types the code into the widget to confirm. Both the email and code screens have a back button, in case they need to fix the address.
  4. After verifying, the record is saved automatically — no need to click submit again.

Anyone who has submitted something before but doesn’t have an active session (a different browser or device, for example) can find the discreet “Already submitted something? Access your records” link in the footer of the home screen.

The suggestion, ticket, or vote is only actually recorded after verification. Until then, voting, commenting, submitting suggestions, and opening tickets are blocked for anyone who hasn’t verified their email.

After verifying their email once, the person doesn’t need to repeat the code on every visit: the browser keeps a session valid for 30 days, automatically renewed with each use. The home screen is always the same, whether the session is active or not — what changes is that the person already sees their own records when entering Suggestions or Support, without needing to verify their email again.

If the same person accesses from a different browser or device, they verify their email again — and land on the same records, because identity is tied to the email, not the device.

If you generate a new secret key for the app (rotate the key), all existing visitor sessions are ended, and people need to verify their email again on their next action.

Visitor mode is on by default. To change it, go to Apps → your app → Widget tab → “Visitor identity” section and use the “Allow visitors by email (OTP code)” field.

When turned off, the widget becomes a read-only suggestion board for anyone without a data-user-token: they can see existing suggestions, but can’t vote, comment, suggest, or open a ticket — only login mode can write.

While a ticket is open or pending, the conversation shows a Mark as resolved button. Use it when you’ve already solved the problem on your own and no longer need the team to keep tracking it.

Once you confirm, the ticket moves to resolved, and the team sees in the conversation history that you were the one who marked it that way, not an agent.

A resolved ticket still accepts replies: if you write in the conversation again, it reopens automatically and shows up as pending for the team again. There’s no reopen button, because replying already does that job.

A closed ticket, on the other hand, is final. It no longer accepts replies and doesn’t reopen, even if you write again.

The same behavior applies to tickets opened through the Need help? button inside the Pliic dashboard itself.

  • Site with login: use login mode (SSO). It’s a faster experience (no email/code prompt) and every action is already tied to the right account.
  • Site without login, or public pages: keep visitor mode on (default). Anyone can contribute without creating an account in your product.
  • Only want feedback from logged-in users: turn visitor mode off. The widget becomes a read-only board for anonymous visitors.