Interactive Playground

Notification Playground

Test all Pinglet notification types in real-time. Configure, preview the payload, and send.

Try full demos:Payload Creator

Choose Notification Type

Content
Glassmorphism Options

Same tag replaces the active notification

Action Buttons(0/3)

No action buttons added

Click "Add" to attach buttons to your notification

Glassmorphism

Ready to send

Endpoint

POST /api/v1/notifications/send
Type: 0
Max 3 Buttons
Custom Events

Custom Event Button Action

Trigger real DOM CustomEvents on the user's browser when they click a notification button. Your frontend JS listens for the event and runs any logic — add to cart, open a modal, track conversions, and more.

How It Works

Flow:1. Backend sends notification with button → action: "event"
2. SDK renders notification (type 0, 1, or 2 — all supported)
3. User clicks the button
4. SDK fires: window.dispatchEvent(new CustomEvent("name", { detail: payload }))
5. SDK auto-dismisses the notification + tracks the click
6. Your JS listener catches the event and runs YOUR logic

Event Button Schema

textstringrequired

Button label shown to the user

action"event"required

Must be exactly "event"

eventstringrequired

Custom event name (e.g. "pinglet:addToCart")

dataany

Payload sent as event.detail — object, array, string, number

All Button Actions

ActionRequiredBehavior
redirectsrc (URL)Opens URL in new tab
linksrc (URL)Opens URL in same tab
alertsrc (string)Shows browser alert
reloadReloads the page
closeDismisses notification
eventevent (string)Fires CustomEvent on window
onClickonClick (fn)Evaluates inline function

Example: Send with Event Button

curlcurl -X POST https://your-api/api/v1/notifications/send \
  -H "Content-Type: application/json" \
  -d '{
    "type": "2",
    "projectId": "your-project-id",
    "body": {
      "title": "Flash Sale!",
      "description": "50% off — limited time only",
      "icon": "https://example.com/sale-icon.png",
      "buttons": [
        {
          "text": "Add to Cart",
          "action": "event",
          "event": "pinglet:addToCart",
          "data": {
            "productId": "SKU-123",
            "quantity": 1,
            "discount": 50,
            "source": "flash-sale-notification"
          }
        },
        { "text": "Maybe Later", "action": "close" }
      ]
    }
  }'

Step-by-Step Frontend Guide

1. Include Pinglet SDK (already done if notifications work)

2. Add your event listener AFTER the SDK script

html<script>
  window.addEventListener("pinglet:addToCart", function (e) {
    console.log("Payload received:", e.detail);
    addItemToCart(e.detail.productId, e.detail.quantity);
  });
</script>

3. Send notification with event button (API / curl / dashboard)

4. User clicks → your listener fires with e.detail

React / SPA Usage

Register in a lifecycle hook and clean up on unmount.

tsxuseEffect(() => {
  const handler = (e: CustomEvent) => {
    console.log("Event data:", e.detail);
    // Your logic here
  };
  window.addEventListener("pinglet:addToCart", handler);
  return () => window.removeEventListener("pinglet:addToCart", handler);
}, []);

Real-World Examples

Add to Cart

event: "shop:addToCart"data: { productId, variant, price }

Open Modal

event: "ui:openModal"data: { modalId, productSlug }

Track Conversion

event: "analytics:conversion"data: { campaign, value, currency }

SPA Navigation

event: "app:navigate"data: { path, tab }

Start Chat

event: "support:openChat"data: { department, priority }

Apply Coupon

event: "promo:applyCoupon"data: { code, discount, minOrder }

Theme Toggle

event: "theme:toggle"data: { theme: "dark" }

Important Notes

  • You must register your listener — the SDK only fires the event
  • Works with Type 0 (toast), Type 1 (template), and Type 2 (glassmorphism)
  • Notification auto-dismisses after the event is dispatched
  • Max 3 buttons per notification — any combo of actions allowed
  • Don't put sensitive data (passwords, tokens) in payload
  • Use namespaced names like "app:action" to avoid collisions
  • data accepts any JSON type: object, array, string, number
  • Backend validates: action = "event", event = string, data = optional
  • In DevTools Console, test manually: window.dispatchEvent(new CustomEvent("your:event", { detail: { test: true } }))

✓ Valid Payloads

// Minimal — just event name
{ "text": "Click Me", "action": "event", "event": "app:clicked" }

// With object data
{ "text": "Buy", "action": "event", "event": "shop:buy", "data": { "id": 1 } }

// With array data
{ "text": "Select", "action": "event", "event": "bulk:select", "data": [1, 2, 3] }

✗ Invalid (Rejected by Backend)

// Missing "event" field
{ "text": "Click", "action": "event" }

// "event" is not a string
{ "text": "Click", "action": "event", "event": 123 }

// Wrong action type
{ "text": "Click", "action": "customEvent", "event": "x" }