Custom metadata
Custom metadata lets you attach extra context to a visitor session — pricing tier, A/B test variant, account type, a checkout attribution ID, and so on. That context shows up alongside pageviews and payments in the dashboard, and is how you share a unique value with a payment provider for reliable attribution.
Metadata is scoped per session. Setting a key again overwrites the earlier value for that key in the same session; keys you do not touch keep their previous values. Setting a key to an empty string removes it from the session.
Static config object
Pass a config object as the fourth argument to the required stub. Set
metadata to a plain object; those keys are merged into the
session on each pageview:
<script>(function(w,n,u,c){
if(u&&typeof u==="object"){c=u;u=null}c=c||{};u=u||"https://in.revscope.co/";c.url=u;u+=n+".js";c.project=n;n=typeof c.name==="string"&&c.name||"dispatch";if(typeof w[n]==="function")return;var q=[];function f(){q.push([].slice.call(arguments));}f.q=f.a=q;f.c=c;w[n]=f;var s=document.createElement("script");s.src=u;s.defer=true;document.head.appendChild(s);
})(window, "REPLACE_WITH_PROJECT_NAME", {
metadata: {
plan: "growth",
experiment: "pricing-v2",
},
});
</script> Dynamic config function
metadata can be a function when the value depends on the
current page. It
receives an eventContext with type (e.g.
pageview) and path, and should return a plain
object:
<script>(function(w,n,u,c){
if(u&&typeof u==="object"){c=u;u=null}c=c||{};u=u||"https://in.revscope.co/";c.url=u;u+=n+".js";c.project=n;n=typeof c.name==="string"&&c.name||"dispatch";if(typeof w[n]==="function")return;var q=[];function f(){q.push([].slice.call(arguments));}f.q=f.a=q;f.c=c;w[n]=f;var s=document.createElement("script");s.src=u;s.defer=true;document.head.appendChild(s);
})(window, "REPLACE_WITH_PROJECT_NAME", {
metadata: function (eventContext) {
return {
plan: "growth",
path: eventContext.path,
};
},
});
</script> JavaScript API
Dispatch a metadata command anytime after a page is tracked
— for example when the visitor picks a plan, logs in, or you generate
an ID to share with Stripe:
dispatch(
"metadata",
{
plan: "pro",
client_reference_id: crypto.randomUUID(),
}
); Only changed keys are sent. Calling again with the same key replaces the previous value for the session. Pass an empty string to remove a key.
The required queue stub safely replays metadata commands dispatched before the tracker initializes:
<script>(function(w,n,u,c){
if(u&&typeof u==="object"){c=u;u=null}c=c||{};u=u||"https://in.revscope.co/";c.url=u;u+=n+".js";c.project=n;n=typeof c.name==="string"&&c.name||"dispatch";if(typeof w[n]==="function")return;var q=[];function f(){q.push([].slice.call(arguments));}f.q=f.a=q;f.c=c;w[n]=f;var s=document.createElement("script");s.src=u;s.defer=true;document.head.appendChild(s);
})(window, "REPLACE_WITH_PROJECT_NAME");
</script> dispatch("metadata", { plan: "pro" }); Declarative HTML attribute
Mark any element with data-revscope-metadata and space-separated
key=value pairs (quote values that contain spaces). The tracker
scans these on each pageview — including SPA navigations — and
again whenever the markup changes, so elements added or updated later are
picked up. Values are applied the same way as the metadata command
(only changed keys are sent), and a key you set through the command is not
overwritten by a later scan unless its attribute value changed:
<div data-revscope-metadata="plan=growth experiment=pricing-v2">
...
</div>
<!-- Quoted values for spaces -->
<body data-revscope-metadata="plan='pro annual' variant=b">
...
</body> URL query parameters
Any rr_* query parameter is recorded as session metadata (the
rr_ prefix is stripped). For example
/pricing?rr_plan=growth&rr_variant=b sets
plan and variant. Campaign parameters
(utm_*, click IDs, and a small allowlist like
ref / user_id) are captured the same way. Use
data-include-params on the script tag (or
includeParams in the stub config) to keep additional
query keys — see the
tracking script reference.
Limits and event metadata
Metadata must be a plain object and serializes to at most 4kb of JSON. Nested objects and arrays are fine; non-objects are ignored.
Custom events can also take a per-event
metadata option. That payload is attached to the event only
— it does not update the session metadata described on this page.