Skip to content

Install the browser SDK

Install the SDK once through your framework's supported global script mechanism. The tag below is for plain HTML.

SDK script<script async src="https://cdn.splendorize.com/splendorize.js" data-site="pub_YOUR_SITE_KEY" ></script>

Frameworks manage the document head. In Next.js App Router, use next/script in the root layout. Never render a custom head or inject this tag into it with dangerouslySetInnerHTML.

Next.js App Routerimport Script from "next/script"; <Script id="splendorize-analytics" src="https://cdn.splendorize.com/splendorize.js" data-site="pub_YOUR_SITE_KEY" strategy="afterInteractive" />

If calls may run before the SDK loads, copy the personalized preload-safe loader from your project's Tracking section.

Open Splendorize

Call the two core methods

window.splendorize.action("start_trial");

Record a meaningful visitor action or decision.

window.splendorize.conversion("trial_started");

Record a completed outcome only after your app confirms success.

Track actions

Use JavaScript for meaningful behavior without a matching DOM activation. For links, buttons, controls, and forms, add HTML attributes instead.

JavaScript method

Call action()

Use action() for meaningful behavior that has no element to annotate.

JavaScript
window.splendorize.action(
  "change_billing_period",
  { placement: "pricing" },
);

HTML attributes

Annotate the element

Add the action to the owning element. Splendorize follows its existing click or form lifecycle.

HTML
<a
  href="/signup"
  data-splendorize-action="start_trial"
  data-splendorize-action-placement="hero"
>
  Start trial
</a>

<form data-splendorize-action="request_demo">
  <!-- Existing fields and submit button -->
</form>

HTML attributes are for actions, not conversions.

There is no conversion HTML attribute. Call conversion() at a confirmed success boundary, or use the authenticated server API.

Action rules

  • Use a lowercase purpose key that starts with a letter, contains letters, numbers, and single underscores, and is no more than 64 characters.
  • Reuse one key across placements. Annotate a form once on the form itself, and never add a programmatic call for the same gesture.
  • Never derive keys or placements from visible copy, locale, visitor data, account IDs, timestamps, or experiment arms.

Browser conversions

Call conversion only after the existing application flow proves success. For example, wait for a successful API response or a destination state that confirms the outcome.

Authority
Client-asserted. Correct placement makes the event meaningful, but browser code cannot provide authenticated server authority.
Use when
A signup, trial, waitlist join, or demo request is genuinely completed and the browser is the only available success boundary. Never call it on the initiating click or submit.
Confirmed browser outcome
const result = await startTrial();

if (result.trialStarted === true) {
  window.splendorize.conversion("trial_started");
}

Authenticated server API

When your backend owns the success transaction, POST the conversion to /v1/conversion with the private site key. Accepted requests return 202. url is required and must belong to an allowed project domain; name, occurredAt, referrer, and visitor, session, and page-view IDs are optional.

Authority
Authenticated project-level provenance. It is stronger than a browser assertion, but it does not prove a person's identity.
Use when
Your backend has confirmed a non-payment outcome. Keep the private key server-side and choose this path instead of emitting the same browser conversion.
Server-only conversion request
const response = await fetch("https://cdn.splendorize.com/v1/conversion", {
  method: "POST",
  headers: {
    authorization: "Bearer " + process.env.SPLENDORIZE_PRIVATE_SITE_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    name: "trial_started",
    url: "https://example.com/welcome",
    occurredAt: new Date().toISOString(),
  }),
});

if (response.status !== 202) {
  throw new Error("Splendorize rejected the conversion");
}

Stripe revenue

Connect Stripe and collect stripeMetadata() after the browser SDK loads. For subscription-mode Checkout, validate the supported attribution keys on your backend and attach them to both Checkout Session and subscription metadata. Signed invoice.payment_succeeded events supply gross amount, currency, and paid time. Refund and dispute webhooks adjust net value; subscription webhooks add cancellation and churn signals. Historical invoices are not imported.

Authority
Provider-backed for paid invoice status, gross amount, currency, and paid time. Splendorize metadata connects the visitor journey; it does not prove payment.
Use when
You need invoice-backed purchases or recurring subscription revenue. Do not report browser-supplied amounts or emit a second browser conversion merely to claim the same payment.
Browser attribution bridge
const attribution = window.splendorize.stripeMetadata();

await fetch("/api/checkout", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ attribution }),
});
Validated Checkout metadata
const attribution = Object.fromEntries(
  [
    "splendorize_site_id",
    "splendorize_visitor_id",
    "splendorize_session_id",
    "splendorize_page_view_id",
  ].flatMap((key) => {
    const value = requestBody.attribution?.[key];
    return typeof value === "string" && value.length <= 120
      ? [[key, value]]
      : [];
  }),
);

await stripe.checkout.sessions.create({
  mode: "subscription",
  line_items,
  success_url,
  cancel_url,
  metadata: attribution,
  subscription_data: { metadata: attribution },
});

SDK reference

Call these methods on window.splendorize. With the personalized loader, all except stripeMetadata() can queue before the SDK loads.

action(actionKey, { placement? })
Records a stable, purpose-based action with an optional placement. It does not declare a completed outcome.
conversion(name?, properties?)
Records a client-asserted conversion. Call it only after the application has confirmed success.
payment({ email })
Hashes a checkout email to bridge the current visitor journey. It never proves payment, amount, or revenue.
stripeMetadata()After SDK loads
Returns Splendorize attribution IDs to attach to Stripe metadata. It does not prove payment.

The generated loader also supports callable commands such as window.splendorize("action", "start_trial"). Prefer the named methods above in application code because they are easier to read.

Privacy and implementation checklist

Keep the implementation narrow and make every signal mean exactly one thing.

  • Install one global loader and preserve the site's consent and CSP behavior.
  • Keep the private site key on the server; the public site key may appear in browser code.
  • Never send form values, emails, names, phone numbers, customer IDs, or secrets in action or conversion metadata.
  • Emit one semantic action per gesture and choose one authoritative source for each outcome.
  • Treat payment attribution as an identity bridge, never as authorization or proof of payment.

Use the source closest to the truth.

Start with the personalized installation instructions in your project. Splendorize keeps actions, confirmed outcomes, and paid revenue separate so your agents can reason from evidence instead of guesses.