[{"data":1,"prerenderedAt":398},["ShallowReactive",2],{"blog-how-to\u002Fwaitlist-bubble":3},{"id":4,"title":5,"body":6,"category":369,"date":370,"dateModified":370,"description":371,"draft":372,"extension":373,"faq":374,"featured":372,"keywords":382,"meta":383,"navigation":384,"ogDescription":385,"ogTitle":5,"path":386,"readTime":387,"schemaType":388,"seo":389,"sitemap":390,"stem":391,"tags":392,"twitterCard":396,"__hash__":397},"blog\u002Fblog\u002Fhow-to\u002Fwaitlist-bubble.md","Bubble Waitlist: Add Signups With Referral Tracking",{"type":7,"value":8,"toc":361},"minimark",[9,13,16,35,40,67,71,91,107,120,129,133,153,164,170,174,193,201,220,237,254,258,291,336],[10,11,12],"p",{},"A Bubble app can collect emails in minutes, but the default route is a Bubble database thing created by a button workflow. That gives you a list of addresses and nothing else: no referral code per signup, no record of which link brought each person, no ranking of who is bringing friends.",[10,14,15],{},"The fix is two small pieces: one script in Bubble's SEO settings and one HTML element where the form should sit. For a form built from native Bubble inputs, a third piece is the Toolbox plugin, which lets a workflow run one line of JavaScript.",[17,18,19],"tldr",{},[10,20,21,22,26,27,30,31,34],{},"Paste the OperatorStack script tag into ",[23,24,25],"code",{},"Settings > SEO \u002F metatags > Script\u002Fmeta tags in header",", then drop an HTML element containing ",[23,28,29],{},"\u003Cdiv data-os-widget=\"waitlist\">\u003C\u002Fdiv>"," on the page. For a form that uses Bubble inputs, install the Toolbox plugin and call ",[23,32,33],{},"OperatorStack.joinWaitlist()"," from a Run javascript action.",[36,37,39],"h2",{"id":38},"what-you-need-before-you-start","What You Need Before You Start",[41,42,43,51,61],"ul",{},[44,45,46,50],"li",{},[47,48,49],"strong",{},"A Bubble app"," you can edit.",[44,52,53,56,57,60],{},[47,54,55],{},"An OperatorStack account."," Free to start. You need the ",[23,58,59],{},"pk_"," project key from your embed snippet.",[44,62,63,66],{},[47,64,65],{},"The Toolbox plugin",", only for the custom form route below.",[36,68,70],{"id":69},"step-1-add-the-script-to-the-header","Step 1: Add the Script to the Header",[72,73,75,81],"step",{"number":74},"1",[10,76,77,80],{},[47,78,79],{},"Create an OperatorStack project"," and copy your snippet:",[82,83,89],"pre",{"className":84,"code":86,"language":87,"meta":88},[85],"language-html","\u003Cscript src=\"https:\u002F\u002Foperatorstack.dev\u002Fos.js\" data-project=\"pk_abc123\">\u003C\u002Fscript>\n","html","",[23,90,86],{"__ignoreMap":88},[72,92,94],{"number":93},"2",[10,95,96,103,104,102],{},[47,97,98,99,102],{},"In the Bubble editor, open ",[23,100,101],{},"Settings > SEO \u002F metatags","."," Paste the snippet into ",[47,105,106],{},"Script\u002Fmeta tags in header",[72,108,110],{"number":109},"3",[10,111,112,115,116,119],{},[47,113,114],{},"Open the app with Preview",", load any page, and check the Network tab for a request to ",[23,117,118],{},"os.js",". Seeing it on a page that has no form confirms the tag is app-wide.",[10,121,122,123,128],{},"Because the tag loads on every page, you also get ",[124,125,127],"a",{"href":126},"\u002Fblog\u002Fhow-to\u002Fanalytics-without-cookie-banners","cookie-free analytics"," across the whole app, with no consent banner.",[36,130,132],{"id":131},"step-2-place-the-form-with-an-html-element","Step 2: Place the Form With an HTML Element",[72,134,136,142,148],{"number":135},"4",[10,137,138,141],{},[47,139,140],{},"Add a Visual element > HTML"," where the form belongs and paste:",[82,143,146],{"className":144,"code":145,"language":87,"meta":88},[85],"\u003Cdiv data-os-widget=\"waitlist\">\u003C\u002Fdiv>\n",[23,147,145],{"__ignoreMap":88},[10,149,150,151,102],{},"Do not paste the script tag here. The header field already loads ",[23,152,118],{},[10,154,155,156,159,160,163],{},"Only the ",[47,157,158],{},"first"," ",[23,161,162],{},"data-os-widget=\"waitlist\""," div on a page renders. A second one on the same page stays empty by design, so pick one placement.",[165,166,167],"tip-box",{},[10,168,169],{},"The design canvas often shows the HTML element as empty. Use Preview and look at the running page before you assume the install failed.",[36,171,173],{"id":172},"a-form-built-from-bubble-inputs","A Form Built From Bubble Inputs",[10,175,176,177,180,181,184,185,188,189,192],{},"If the widget style does not fit your app, build the form with a Bubble ",[47,178,179],{},"Input"," and a ",[47,182,183],{},"Button",", then install the ",[47,186,187],{},"Toolbox"," plugin. In the button's workflow, add the Toolbox action ",[47,190,191],{},"Run javascript"," and paste:",[82,194,199],{"className":195,"code":197,"language":198,"meta":88},[196],"language-javascript","OperatorStack.joinWaitlist({ email: properties.param1 }).then((res) => {\n  bubble_fn_referral(res.referral_code);\n});\n","javascript",[23,200,197],{"__ignoreMap":88},[10,202,203,204,207,208,211,212,215,216,219],{},"Set the action's first property field to the Input's value, which Toolbox exposes to the script as ",[23,205,206],{},"properties.param1",". To get the referral code back into Bubble, add a Toolbox ",[47,209,210],{},"JavaScript to Bubble"," element named ",[23,213,214],{},"referral",": its ",[23,217,218],{},"bubble_fn_referral"," function publishes the value for use in a workflow or custom state.",[10,221,222,225,226,229,230,233,234,102],{},[23,223,224],{},"joinWaitlist()"," resolves with ",[23,227,228],{},"{ success, referral_code, referral_link }",". To turn the code into share URLs for a thank-you group, call ",[23,231,232],{},"OperatorStack.getShareLinks(referral_code, { text: \"I just joined the waitlist\" })",", which returns ",[23,235,236],{},"{ twitter, linkedin, email, whatsapp, copy }",[10,238,239,242,243,246,247,250,251,102],{},[23,240,241],{},"getShareLinks()"," builds the URL from the current origin and path, so a form on ",[23,244,245],{},"yourapp.bubbleapps.io\u002Flaunch"," produces links ending ",[23,248,249],{},"\u002Flaunch?ref=CODE",". To point somewhere else, build the URL yourself from ",[23,252,253],{},"referral_code",[36,255,257],{"id":256},"common-mistakes","Common Mistakes",[41,259,260,269,275,281],{},[44,261,262,265,266,268],{},[47,263,264],{},"Pasting the script into both the header and the HTML element."," The page loads ",[23,267,118],{}," twice. Script in settings, div in the element.",[44,270,271,274],{},[47,272,273],{},"Judging the install from the design canvas."," Check Preview or the live URL.",[44,276,277,280],{},[47,278,279],{},"Two widget divs on one page."," Only the first renders.",[44,282,283,286,287,290],{},[47,284,285],{},"Running the JavaScript action before the email is validated."," Add an ",[23,288,289],{},"Input's value is not empty"," condition on the workflow so blank submissions never reach the SDK.",[292,293,294,304,310,316,322],"faq-section",{},[295,296,298],"faq-item",{"question":297},"Where do I paste a script tag in Bubble?",[10,299,300,301,303],{},"In the editor, open ",[23,302,101],{}," and use the Script\u002Fmeta tags in header field. Anything there loads on every page of the app. Use the Body field only if a script needs to run after the page markup exists.",[295,305,307],{"question":306},"Do I need a plugin to add a waitlist to Bubble?",[10,308,309],{},"No, not for the standard widget. A script tag in the settings plus an HTML element containing the widget div is enough. You only need a plugin, such as Toolbox, when you want to build the form from native Bubble inputs and call the SDK from a workflow.",[295,311,313],{"question":312},"Why is the form empty inside the Bubble editor?",[10,314,315],{},"Third-party scripts often do not render in the design canvas. Open the app with Preview, or the live URL, and check the form there before debugging.",[295,317,319],{"question":318},"Can I store signups in the Bubble database too?",[10,320,321],{},"Yes, but you do not need to. OperatorStack keeps the contact, source and referral count in its own contact list. If you also want a Bubble record, add a Create a new thing step before the JavaScript action in the same workflow.",[295,323,325],{"question":324},"Does the referral code survive moving between Bubble pages?",[10,326,327,328,331,332,335],{},"A visitor who arrives with ",[23,329,330],{},"?ref=CODE"," has it stored in sessionStorage under ",[23,333,334],{},"os_ref"," for that browser tab, so it survives page changes within the visit. It does not survive a closed tab.",[337,338,339,340],"content-related-articles",{},"\n  ",[341,342,339,346],"contentrelatedcard",{"href":343,"title":344,"description":345},"\u002Fblog\u002Fhow-to\u002Fwaitlist-wix","Wix Waitlist: Add Signups With Custom Code","The same site-wide script plus embed element pattern on a hosted builder, including the scope setting that drops tracking.",[341,347,339,351],{"href":348,"title":349,"description":350},"\u002Fblog\u002Fhow-to\u002Foperatorstack-webflow","Webflow Waitlist: Add Signups With Custom Code, No Zapier","Add the script tag and widget to a Webflow project through custom code.",[341,352,356],{"href":353,"title":354,"description":355},"\u002Fblog\u002Fhow-to\u002Fsocial-share-links-waitlist","Waitlist Share Links: Add Social Sharing to Your Thank-You Page","What to do with the referral code after signup, using the same getShareLinks() call shown above.",[357,358],"cta-box",{"href":359,"label":360},"\u002F","Get Started Free",{"title":88,"searchDepth":362,"depth":362,"links":363},2,[364,365,366,367,368],{"id":38,"depth":362,"text":39},{"id":69,"depth":362,"text":70},{"id":131,"depth":362,"text":132},{"id":172,"depth":362,"text":173},{"id":256,"depth":362,"text":257},"how-to","2026-11-05","Add a waitlist with referral tracking to a Bubble app using the header script field and an HTML element. Covers the Toolbox plugin for custom forms.",false,"md",[375,377,378,379,380],{"question":297,"answer":376},"In the editor, open Settings > SEO \u002F metatags and use the Script\u002Fmeta tags in header field. Anything there loads on every page of the app. Use the Body field only if a script needs to run after the page markup exists.",{"question":306,"answer":309},{"question":312,"answer":315},{"question":318,"answer":321},{"question":324,"answer":381},"A visitor who arrives with ?ref=CODE has it stored in sessionStorage under os_ref for that browser tab, so it survives page changes within the visit. It does not survive a closed tab.","bubble waitlist,add waitlist to bubble,bubble.io email signup,bubble referral program,bubble html element,bubble toolbox plugin",{},true,"One script in Bubble's SEO settings, one HTML element for the form. Plus the Toolbox route for a form that matches your Bubble design.","\u002Fblog\u002Fhow-to\u002Fwaitlist-bubble","7 min","HowTo",{"title":5,"description":371},{"loc":386},"blog\u002Fhow-to\u002Fwaitlist-bubble",[393,394,395],"bubble","waitlist","no-code","summary_large_image","wUe0gNJ-PYvAe6sRScqBBa5HCmQRWdF78P2-SMd_gFM",1793938121898]