1import{_ as h,a as v}from"./De7ji8Y0.js";import{_ as w}from"./C5Bp6h9P.js";import{_}from"./Baf5cy0I.js";import{_ as k}from"./B02SoRjN.js";import{_ as S}from"./DLzX97yS.js";import{d as D,c,I as m,b as o,w as a,e as t,g as s,F as T,j as C,a as g,t as r}from"./BJ-fXIum.js";const F={class:"space-y-3 mb-4"},j={class:"flex items-center gap-2 mb-1"},A={class:"font-mono text-xs px-1.5 py-0.5 bg-gray-100 rounded text-gray-700"},P={class:"text-xs text-gray-400"},E={class:"text-sm text-gray-600"},N=`<script src="https://operatorstack.dev/os.js" 2 data-project="pk_xxxxx" 3 data-chat="false" 4 data-exclude="/admin,/internal" 5 data-dev="true"><\/script>`,I=`<!-- Waitlist signup form --> 6<div data-os-widget="waitlist"></div> 7 8<!-- Contact form --> 9<div data-os-widget="form" data-os-form="contact"></div> 10 11<!-- Custom form (by form key) --> 12<div data-os-widget="form" data-os-form="frm_abc123"></div>`,V=D({__name:"embed-script",setup(O){const u=[{name:"data-project",type:"string",required:!0,description:"Your project key (e.g., pk_xxxxx). Required."},{name:"data-api",type:"string",description:"Override the API base URL (for self-hosted deployments)"},{name:"data-chat",type:"string",description:'Set to "false" to suppress the chat bubble on this specific page. Useful for pages where chat is distracting.',default:'"true"'},{name:"data-exclude",type:"string",description:"Comma-separated path prefixes to exclude from analytics tracking. SPA navigations to these paths are silently skipped.",default:"none"},{name:"data-dev",type:"string",description:'Set to "true" for development mode: disables config caching, enables console logging.',default:'"false"'}],y=[{name:"page_view",type:"auto",description:"Fired on every page load"},{name:"widget_impression",type:"auto",description:"Fired when a widget is rendered on the page"},{name:"waitlist_signup",type:"auto",description:"Fired on successful waitlist submission"},{name:"form_submission",type:"auto",description:"Fired on form submission"},{name:"contact_message",type:"auto",description:"Fired on contact form submission"},{name:"referral_conversion",type:"auto",description:"Fired when a referred visitor signs up"},{name:"chat_opened",type:"auto",description:"Fired when chat bubble is opened"},{name:"chat_closed",type:"auto",description:"Fired when chat window is closed"},{name:"chat_message_sent",type:"auto",description:"Fired when visitor sends a chat message"},{name:"console_error",type:"auto",description:"JavaScript errors from the host page (max 1,000/day)"},{name:"performance",type:"auto",description:"Core Web Vitals (TTFB, FCP, LCP, CLS, INP) when performance monitoring is enabled"},{name:"custom",type:"SDK",description:"Custom events via trackEvent() (max 10,000/day)"}],f=[{name:"visitor_id",type:"localStorage UUID",description:"Most stable identifier. A random UUID generated on first visit and stored in localStorage. Persists across sessions on the same browser."},{name:"client_visitor_hash",type:"Browser fingerprint",description:"SHA-256 hash of User-Agent, screen resolution, language, timezone, and hardware info. Stable across sessions and survives localStorage clearing. Does not rotate."},{name:"visitor_hash",type:"Server-side hash",description:"SHA-256 hash of IP + User-Agent + Accept-Language + month.
12Computed server-side as final fallback. Rotates monthly."}];return(R,e)=>{const i=h,d=w,l=_,x=k,p=S,b=v;return g(),c("div",null,[e[12]||(e[12]=m('<div class="mb-10"><p class="text-xs font-mono uppercase tracking-widest text-gray-400 mb-2">Tools</p><h1 class="text-3xl font-bold tracking-tight mb-3">Embed Script</h1><p class="text-gray-500 text-lg leading-relaxed"> The <code class="font-mono text-sm bg-gray-100 px-1.5 py-0.5 rounded">os.js</code> script is the single entry point that powers analytics, widgets, and the SDK on your site. </p></div><hr class="border-gray-200 mb-10">',2)),o(i,{id:"installation"},{default:a(()=>[...e[0]||(e[0]=[s("Installation",-1)])]),_:1}),e[13]||(e[13]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," Add the script tag to every page where you want tracking and widgets. It loads asynchronously and wonât block page rendering. ",-1)),o(d,{filename:"index.html",code:N,"highlight-lines":[1,2,3]}),o(i,{id:"how-it-works"},{default:a(()=>[...e[1]||(e[1]=[s("How it works",-1)])]),_:1}),e[14]||(e[14]=m('<p class="text-sm text-gray-600 leading-relaxed mb-4"> When the script loads, it performs these steps in order: </p><ol class="text-sm text-gray-600 space-y-2 mb-4 list-decimal list-inside"><li> Reads the <code class="font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded">data-project</code> key from the script tag </li><li>Fetches your project configuration (cached for 5 minutes in localStorage)</li><li>Starts tracking page views and events automatically</li><li>Renders any widgets found on the page (Shadow DOM isolated)</li><li> Exposes the <code class="font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded">window.OperatorStack</code> SDK </li><li> Resolves the <code class="font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded">ready</code> promise </li></ol>',2)),o(i,{id:"config-caching"},{default:a(()=>[...e[2]||(e[2]=[s("Configuration caching",-1)])]),_:1}),e[15]||(e[15]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," Project configuration is cached in localStorage using a stale-while-revalidate strategy: ",-1)),e[16]||(e[16]=t("ul",{class:"text-sm text-gray-600 space-y-1 mb-4 list-disc list-inside"},[t("li",null,[t("strong",null,"Production:"),s(" 5-minute TTL. Serves cached config immediately, fetches fresh in background. ")]),t("li",null,[t("strong",null,"Dev mode:"),s(" No caching. Always fetches fresh config.")])],-1)),o(i,{id:"data-attributes",level:3},{default:a(()=>[...e[3]||(e[3]=[s("Data attributes",-1)])]),_:1}),o(l,{items:u}),o(x,{type:"info"},{default:a(()=>[...e[4]||(e[4]=[s(" Enable dev mode with ",-1),t("code",{class:"font-mono text-xs"},'data-dev="true"',-1),s(" to see configuration changes immediately without waiting for the cache to expire. ",-1)])]),_:1}),o(i,{id:"event-batching"},{default:a(()=>[...e[5]||(e[5]=[s("Event batching",-1)])]),_:1}),e[17]||(e[17]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," Events are queued and sent in batches for performance: ",-1)),e[18]||(e[18]=t("ul",{class:"text-sm text-gray-600 space-y-1 mb-4 list-disc list-inside"},[t("li",null,[s(" First batch sends immediately (via "),t("code",{class:"font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded"},"setTimeout(0)"),s(" to coalesce synchronous init events) ")]),t("li",null,[s("Subsequent events flush every "),t("strong",null,"5 seconds")]),t("li",null,[s(" On page unload or tab hide, remaining events are sent via "),t("code",{class:"font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded"},"sendBeacon")])],-1)),o(i,{id:"event-types"},{default:a(()=>[...e[6]||(e[6]=[s("Event types",-1)])]),_:1}),e[19]||(e[19]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," The following event types are tracked automatically or can be sent via the SDK: ",-1)),o(l,{items:y}),o(i,{id:"shadow-dom"},{default:a(()=>[...e[7]||(e[7]=[s("Shadow DOM isolation",-1)])]),_:1}),e[20]||(e[20]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," All widgets render inside Shadow DOM, which means: ",-1)),e[21]||(e[21]=t("ul",{class:"text-sm text-gray-600 space-y-1 mb-4 list-disc list-inside"}
12,[t("li",null,"Widget styles wonât leak into your page"),t("li",null,"Your page styles wonât affect widget appearance"),t("li",null,"Each widget is self-contained with its own scoped CSS")],-1)),o(i,{id:"widget-attributes"},{default:a(()=>[...e[8]||(e[8]=[s("Widget HTML attributes",-1)])]),_:1}),e[22]||(e[22]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," Place these elements anywhere on your page. The embed script finds and replaces them with rendered widgets. ",-1)),o(d,{code:I}),o(i,{id:"visitor-tracking"},{default:a(()=>[...e[9]||(e[9]=[s("Visitor identification",-1)])]),_:1}),e[23]||(e[23]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"}," OperatorStack uses a three-tier fallback strategy for visitor identification, with no cookies required: ",-1)),t("div",F,[(g(),c(T,null,C(f,n=>t("div",{key:n.name,class:"rounded-lg border border-gray-200 p-3"},[t("div",j,[t("span",A,r(n.name),1),t("span",P,r(n.type),1)]),t("p",E,r(n.description),1)])),64))]),o(i,{id:"do-not-track"},{default:a(()=>[...e[10]||(e[10]=[s("Do Not Track",-1)])]),_:1}),e[24]||(e[24]=t("p",{class:"text-sm text-gray-600 leading-relaxed mb-4"},[s(" When a visitorâs browser sends the "),t("code",{class:"font-mono text-xs bg-gray-100 px-1.5 py-0.5 rounded"},"DNT: 1"),s(" header and your project has âRespect Do Not Trackâ enabled, the script skips all analytics tracking. Widgets and the SDK still function normally. ")],-1)),o(i,{id:"api-endpoints"},{default:a(()=>[...e[11]||(e[11]=[s("API endpoints",-1)])]),_:1}),o(p,{method:"GET",path:"/v1/projects/{projectKey}/config",description:"Fetch project configuration including all enabled widgets and settings.",auth:"public"}),o(p,{method:"POST",path:"/v1/projects/{projectKey}/events/batch",description:"Submit a batch of analytics events. Returns 202 Accepted immediately.",auth:"public"}),o(b,{prev:{label:"Quickstart",to:"/docs/quickstart"},next:{label:"Waitlist",to:"/docs/waitlist"}})])}}});export{V as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.