[{"data":1,"prerenderedAt":411},["ShallowReactive",2],{"blog-how-to/waitlist-squarespace":3},{"id":4,"title":5,"body":6,"category":382,"date":383,"dateModified":384,"description":385,"draft":386,"extension":387,"faq":388,"featured":386,"keywords":397,"meta":398,"navigation":399,"ogDescription":400,"ogTitle":5,"path":401,"readTime":402,"schemaOrg":403,"schemaType":404,"seo":405,"sitemap":406,"stem":407,"tags":408,"twitterCard":409,"__hash__":410},"blog/blog/how-to/waitlist-squarespace.md","Squarespace Waitlist: Add Signups With Code Injection",{"type":7,"value":8,"toc":373},"minimark",[9,18,21,35,40,67,71,95,114,127,131,152,158,165,169,172,183,186,195,204,208,211,214,220,239,264,272,286,290,293,296,304,348],[10,11,12,13,17],"p",{},"Squarespace hosts a lot of pre-launch landing pages, and the first thing founders discover when they try to add a waitlist is that the Personal plan cannot run any third-party code at all. Code Injection and Code Blocks are both premium features. If ",[14,15,16],"code",{},"Settings > Advanced"," on your site has no Code Injection entry, that is not a bug and no workaround exists at that tier.",[10,19,20],{},"On a Business plan or higher, the install is one script tag and one div. The two things that waste an afternoon are the editor preview, which never runs your script, and Ajax loading on 7.0 templates, which silently breaks the widget on every page after the first.",[22,23,24],"tldr",{},[10,25,26,27,30,31,34],{},"Paste the OperatorStack script tag into ",[14,28,29],{},"Settings > Advanced > Code Injection > Footer",", then drop a Code Block containing ",[14,32,33],{},"\u003Cdiv data-os-widget=\"waitlist\">\u003C/div>"," wherever you want the form. Requires a Squarespace Business plan or higher. The widget will not render inside the editor, only on the saved page.",[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 Squarespace Business plan or higher."," Code Injection and Code Blocks are premium features. The Personal plan has neither, so there is no way to add a waitlist, analytics, or any other script to a Personal site.",[44,52,53,56,57,60],{},[47,54,55],{},"An OperatorStack account."," Free to start. You need the ",[14,58,59],{},"pk_"," project key from your embed snippet.",[44,62,63,66],{},[47,64,65],{},"Which Squarespace version you are on."," Design > Site Styles will tell you. 7.1 sites are the common case now. 7.0 sites need one extra step covered below.",[36,68,70],{"id":69},"step-1-add-the-script-tag-site-wide","Step 1: Add the Script Tag Site-Wide",[72,73,75,85],"step",{"number":74},"1",[10,76,77,80,81,84],{},[47,78,79],{},"Create an OperatorStack project"," and enter your Squarespace domain (including the ",[14,82,83],{},".squarespace.com"," staging domain if you are still testing on it) so CORS is configured for both. Copy your snippet:",[86,87,93],"pre",{"className":88,"code":90,"language":91,"meta":92},[89],"language-html","\u003Cscript src=\"https://operatorstack.dev/os.js\" data-project=\"pk_abc123\">\u003C/script>\n","html","",[14,94,90],{"__ignoreMap":92},[72,96,98,111],{"number":97},"2",[10,99,100,106,107,110],{},[47,101,102,103],{},"Go to ",[14,104,105],{},"Settings > Advanced > Code Injection"," and paste the script tag into the ",[47,108,109],{},"Footer"," box, not the Header box. Save.",[10,112,113],{},"Footer is the better default here. The script fetches your widget config asynchronously and does not need to run before your content paints, so putting it at the end of the body keeps it off the critical rendering path that Squarespace's own speed reporting measures.",[10,115,116,117,120,121,126],{},"This is site-wide. Every page on your Squarespace site now loads ",[14,118,119],{},"os.js"," once, which is also enough to start collecting ",[122,123,125],"a",{"href":124},"/blog/how-to/analytics-without-cookie-banners","cookie-free analytics"," with no consent banner.",[36,128,130],{"id":129},"step-2-place-the-widget-where-you-want-the-form","Step 2: Place the Widget Where You Want the Form",[72,132,134,140,146],{"number":133},"3",[10,135,136,139],{},[47,137,138],{},"Edit the page, add a Code Block"," where the form should appear, and paste only the div:",[86,141,144],{"className":142,"code":143,"language":91,"meta":92},[89],"\u003Cdiv data-os-widget=\"waitlist\">\u003C/div>\n",[14,145,143],{"__ignoreMap":92},[10,147,148,149,151],{},"No script tag here. It is already loading site-wide from Step 1, and adding it a second time makes the page fetch and run ",[14,150,119],{}," twice.",[153,154,155],"warning-box",{},[10,156,157],{},"The Code Block will look empty or show a placeholder message while you are editing. Squarespace does not execute Code Block scripts in the editor, so the widget genuinely cannot render there. Save and open the live page (or the preview link) in a normal tab before concluding anything is broken. This costs people more debugging time on Squarespace than any other step.",[10,159,160,161,164],{},"Only the first ",[14,162,163],{},"data-os-widget=\"waitlist\""," div on a page renders. If you paste the Code Block into two sections of the same page, the second one stays empty by design.",[36,166,168],{"id":167},"step-3-turn-off-ajax-loading-squarespace-70-only","Step 3: Turn Off Ajax Loading (Squarespace 7.0 Only)",[10,170,171],{},"Skip this if you are on 7.1. It has no Ajax loading.",[10,173,174,175,178,179,182],{},"On 7.0 templates in the Brine family, ",[14,176,177],{},"Design > Site Styles"," has a ",[47,180,181],{},"Site: Ajax Loading Enabled"," toggle that is on by default. With it on, clicking an internal link swaps the page content in place instead of doing a real browser navigation.",[10,184,185],{},"That breaks the widget on every page after the first, and the reason is worth understanding because it explains a whole class of \"it worked on the homepage\" reports:",[10,187,188,190,191,194],{},[14,189,119],{}," runs its initialization once per real page load. When it initializes and finds no widget container on the page, it starts a ",[14,192,193],{},"MutationObserver"," to catch containers added late by a framework or a popup, and that observer disconnects after 10 seconds to avoid leaking. Under Ajax loading there is no second page load, so nothing re-runs initialization, and by the time you click through to your signup page the observer that would have caught the new div is long gone.",[72,196,198],{"number":197},"4",[10,199,200,203],{},[47,201,202],{},"Set Ajax Loading to off"," in Design > Site Styles, then save and click between pages again. Each navigation is now a real page load, and the widget renders everywhere you placed a Code Block.",[36,205,207],{"id":206},"matching-your-squarespace-template-styling","Matching Your Squarespace Template Styling",[10,209,210],{},"The default widget renders in a Shadow DOM, so your Squarespace template's CSS cannot reach inside it. That is deliberate, and it means the form looks the same everywhere instead of inheriting whatever your template does to inputs.",[10,212,213],{},"If you want the form to match your template exactly, build the markup yourself in a Code Block and call the SDK on submit:",[86,215,218],{"className":216,"code":217,"language":91,"meta":92},[89],"\u003Cform id=\"join\">\n  \u003Cinput type=\"email\" name=\"email\" placeholder=\"you@example.com\" required />\n  \u003Cbutton type=\"submit\">Request access\u003C/button>\n\u003C/form>\n\u003Cp id=\"joined\" hidden>You are in. Share your link: \u003Ca id=\"ref\">\u003C/a>\u003C/p>\n\n\u003Cscript>\n  document.getElementById(\"join\").addEventListener(\"submit\", async (e) => {\n    e.preventDefault();\n    const email = e.target.email.value;\n    const result = await OperatorStack.joinWaitlist({ email });\n    const link = document.getElementById(\"ref\");\n    link.href = result.referral_link;\n    link.textContent = result.referral_link;\n    document.getElementById(\"join\").hidden = true;\n    document.getElementById(\"joined\").hidden = false;\n  });\n\u003C/script>\n",[14,219,217],{"__ignoreMap":92},[10,221,222,225,226,229,230,233,234,238],{},[14,223,224],{},"joinWaitlist"," waits internally for the SDK to finish initializing, so you do not need to guard the call or wait on ",[14,227,228],{},"OperatorStack.ready"," yourself. It returns ",[14,231,232],{},"{ success, referral_code, referral_link }",", and the referral code is what turns a signup into a ",[122,235,237],{"href":236},"/blog/guides/viral-referral-loop","referral loop"," instead of a flat list of emails.",[10,240,241,242,245,246,249,250,249,253,249,256,259,260,263],{},"To add share buttons, pass that code to ",[14,243,244],{},"getShareLinks",", which returns ready-to-use URLs for ",[14,247,248],{},"twitter",", ",[14,251,252],{},"linkedin",[14,254,255],{},"whatsapp",[14,257,258],{},"email",", and ",[14,261,262],{},"copy",":",[86,265,270],{"className":266,"code":268,"language":269,"meta":92},[267],"language-js","const links = OperatorStack.getShareLinks(result.referral_code);\ndocument.getElementById(\"tweet\").href = links.twitter;\n","js",[14,271,268],{"__ignoreMap":92},[273,274,275],"tip-box",{},[10,276,277,278,281,282,285],{},"Since a Code Block is per-page, this custom form only exists where you paste it. Two calls worth knowing if you reuse it across several Squarespace pages: ",[14,279,280],{},"OperatorStack.isSignedUp()"," returns whether this visitor already joined, and ",[14,283,284],{},"OperatorStack.getReferralLink()"," returns their existing link, so a returning visitor can see their share link again instead of a form they already filled in.",[36,287,289],{"id":288},"why-not-the-squarespace-form-block","Why Not the Squarespace Form Block",[10,291,292],{},"Squarespace has a native Form Block, and for a plain \"email me at launch\" list it is fine. It stops being fine the moment you want referrals.",[10,294,295],{},"A Form Block delivers submissions to Squarespace storage, Google Drive, or a connected Mailchimp list. None of those assign a referral code to a signup or count how many people that signup brought in, so there is no way to build a position-based or reward-based launch list on top of it. You also cannot see which page or campaign produced a submission without wiring up separate analytics.",[10,297,298,299,303],{},"The Code Block route keeps signups, ",[122,300,302],{"href":301},"/blog/guides/why-referral-tracking","referral counts",", page analytics, and form submissions on the same contact record, which is the part that matters when you are deciding who to let into a beta first.",[305,306,307,317,323,329,338],"faq-section",{},[308,309,311],"faq-item",{"question":310},"What Squarespace plan do I need to add a waitlist?",[10,312,313,314,316],{},"Business or higher. Code Injection and Code Blocks are both premium features on Squarespace, and the Personal plan has neither. If ",[14,315,16],{}," has no Code Injection entry, you are on Personal and cannot add any third-party script until you upgrade. This is a Squarespace restriction, not an OperatorStack one.",[308,318,320],{"question":319},"Why is my waitlist widget blank in the Squarespace editor?",[10,321,322],{},"Squarespace does not execute scripts inside Code Blocks while you are editing. The editor shows a placeholder instead, which is expected. Save, then view the live or preview site in a normal browser tab. If the form renders there, nothing is broken.",[308,324,326],{"question":325},"Do I put the script tag in the Header or the Footer injection?",[10,327,328],{},"Either works, but Footer is the better default. The script does not block rendering and does not need to run before your page content paints, so loading it at the end of the body keeps your Squarespace page speed scores unaffected.",[308,330,332],{"question":331},"My waitlist stops working when I click between pages. Why?",[10,333,334,335,337],{},"You are on a Squarespace 7.0 template with Ajax loading enabled. Ajax loading swaps page content without a full browser navigation, so ",[14,336,119],{}," never re-initializes and never sees the widget div on the newly loaded page. Turn Ajax loading off in Design > Site Styles, or upgrade to 7.1, which does not use it.",[308,339,341],{"question":340},"Can I use Squarespace's own Form Block for the waitlist instead?",[10,342,343,344,347],{},"Not for referral tracking. A Squarespace Form Block posts to Squarespace storage, Google Drive, or Mailchimp, and none of those issue a referral code or count referrals per signup. If you want the Squarespace-native look with OperatorStack behind it, build a plain HTML form in a Code Block and call ",[14,345,346],{},"OperatorStack.joinWaitlist()"," on submit.",[349,350,351,352],"content-related-articles",{},"\n  ",[353,354,351,358],"contentrelatedcard",{"href":355,"title":356,"description":357},"/blog/how-to/waitlist-carrd","Carrd Waitlist: Add Email Signup to Your Carrd Site","Another plan-gated builder with its own quirk: Carrd's iframe sandboxing changes where the script tag goes.",[353,359,351,363],{"href":360,"title":361,"description":362},"/blog/how-to/waitlist-wordpress","WordPress Waitlist: Add a Signup Form Without a Plugin","The other CMS install, where the script gets stripped on save unless you use the functions.php method.",[353,364,368],{"href":365,"title":366,"description":367},"/blog/guides/javascript-sdk","OperatorStack JavaScript SDK: All Methods with Examples","Full reference for joinWaitlist, getShareLinks, isSignedUp, and the rest of the calls used in the custom form above.",[369,370],"cta-box",{"href":371,"label":372},"/","Get Started Free",{"title":92,"searchDepth":374,"depth":374,"links":375},2,[376,377,378,379,380,381],{"id":38,"depth":374,"text":39},{"id":69,"depth":374,"text":70},{"id":129,"depth":374,"text":130},{"id":167,"depth":374,"text":168},{"id":206,"depth":374,"text":207},{"id":288,"depth":374,"text":289},"how-to","2026-09-10",null,"Add a waitlist with referral tracking to Squarespace using Code Injection. Requires a Business plan, and the widget will not render in the editor.",false,"md",[389,391,392,393,395],{"question":310,"answer":390},"Business or higher. Code Injection and Code Blocks are both premium features on Squarespace, and the Personal plan has neither. If Settings > Advanced has no Code Injection entry, you are on Personal and cannot add any third-party script until you upgrade. This is a Squarespace restriction, not an OperatorStack one.",{"question":319,"answer":322},{"question":325,"answer":328},{"question":331,"answer":394},"You are on a Squarespace 7.0 template with Ajax loading enabled. Ajax loading swaps page content without a full browser navigation, so os.js never re-initializes and never sees the widget div on the newly loaded page. Turn Ajax loading off in Design > Site Styles, or upgrade to 7.1, which does not use it.",{"question":340,"answer":396},"Not for referral tracking. A Squarespace Form Block posts to Squarespace storage, Google Drive, or Mailchimp, and none of those issue a referral code or count referrals per signup. If you want the Squarespace-native look with OperatorStack behind it, build a plain HTML form in a Code Block and call OperatorStack.joinWaitlist() on submit.","squarespace waitlist,add waitlist to squarespace,squarespace code injection,squarespace email signup,squarespace code block,squarespace custom code",{},true,"Add a waitlist to Squarespace with one script tag in Code Injection. Covers the Business plan requirement and why the widget looks broken in the editor.","/blog/how-to/waitlist-squarespace","6 min","[object Object]","HowTo",{"title":5,"description":385},{"loc":401},"blog/how-to/waitlist-squarespace",[],"summary_large_image","7I2CsB6QDoJld736bEn1gT6MwI7ZEiAbRZIyGcFoj5k",1789175127235]