Install the browser SDK
Install the SDK once through your framework's supported global script mechanism. The tag below is for plain HTML.
<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.
import 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.
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.
<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.
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.
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.
const attribution = window.splendorize.stripeMetadata();
await fetch("/api/checkout", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ attribution }),
});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.
setConsent(allowed)- Allows or withdraws durable tracking when your site uses gated consent. Passing false clears durable attribution.
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.