[{"data":1,"prerenderedAt":407},["ShallowReactive",2],{"blog-how-to\u002Ftrack-hacker-news-reddit-signups":3},{"id":4,"title":5,"body":6,"category":376,"date":377,"dateModified":378,"description":379,"draft":380,"extension":381,"faq":382,"featured":380,"keywords":393,"meta":394,"navigation":395,"ogDescription":396,"ogTitle":397,"path":398,"readTime":399,"schemaType":400,"seo":401,"sitemap":402,"stem":403,"tags":404,"twitterCard":405,"__hash__":406},"blog\u002Fblog\u002Fhow-to\u002Ftrack-hacker-news-reddit-signups.md","Track Hacker News and Reddit Signups on Launch Day",{"type":7,"value":8,"toc":367},"minimark",[9,13,16,39,44,117,120,145,149,152,162,168,172,179,187,198,202,209,217,226,230,245,262,272,276,285,344],[10,11,12],"p",{},"You post a Show HN at 9am, a Reddit thread at noon, and by evening you have 214 visits and 31 signups. Your analytics says 140 of those visits were direct. You know that is wrong, because you were refreshing the thread all day.",[10,14,15],{},"Both channels are bad at handing you attribution. Hacker News sends the referrer without a path, so you cannot tell which thread. Reddit traffic arrives with a referrer from the website but often with none from the mobile apps. This guide builds a small classifier so launch-day signups are credited to a channel and a thread.",[17,18,19],"tldr",{},[10,20,21,22,26,27,30,31,34,35,38],{},"Tag the link you submit with ",[23,24,25],"code",{},"utm_source"," and ",[23,28,29],{},"utm_campaign",". On landing, classify the visit from the UTM source first and ",[23,32,33],{},"document.referrer"," second, then send it with ",[23,36,37],{},"OperatorStack.trackEvent(\"channel_landing\", { channel, campaign })",". On signup, send a second event with the same channel, so you can compare visits to signups per channel.",[40,41,43],"h2",{"id":42},"what-each-channel-actually-sends","What Each Channel Actually Sends",[45,46,47,63],"table",{},[48,49,50],"thead",{},[51,52,53,57,60],"tr",{},[54,55,56],"th",{},"Signal",[54,58,59],{},"Hacker News",[54,61,62],{},"Reddit",[64,65,66,80,92,103],"tbody",{},[51,67,68,74,77],{},[69,70,71,73],"td",{},[23,72,33],{}," on desktop web",[69,75,76],{},"Site origin only, no thread path",[69,78,79],{},"Site origin, sometimes a subreddit path",[51,81,82,87,90],{},[69,83,84,86],{},[23,85,33],{}," from native apps",[69,88,89],{},"Often empty",[69,91,89],{},[51,93,94,97,100],{},[69,95,96],{},"Your UTM tags",[69,98,99],{},"Verify they survive submission",[69,101,102],{},"Survive in posts you control",[51,104,105,108,111],{},[69,106,107],{},"Click ID",[69,109,110],{},"None",[69,112,113,116],{},[23,114,115],{},"rdt_cid"," only on Reddit ads",[10,118,119],{},"Treat the referrer as a fallback, never the primary signal. It tells you the platform when it is present and tells you nothing when it is empty, and the empty case is common exactly where launch traffic is heaviest: phones.",[10,121,122,123,126,127,129,130,129,133,135,136,138,139,144],{},"OperatorStack's script tag already stores a first-touch ",[23,124,125],{},"os_attribution"," cookie with ",[23,128,25],{},", ",[23,131,132],{},"utm_medium",[23,134,29],{},", and ",[23,137,115],{},". The full mechanics are in ",[140,141,143],"a",{"href":142},"\u002Fblog\u002Fhow-to\u002Ftrack-utm-without-google-analytics","Track UTM Parameters Without Google Analytics",". What it does not do is look at the referrer when there is no tag, which is the gap below.",[40,146,148],{"id":147},"step-1-tag-each-link-per-thread","Step 1: Tag Each Link Per Thread",[10,150,151],{},"Make one tagged URL per place you post. The campaign names the thread, not the channel.",[153,154,160],"pre",{"className":155,"code":157,"language":158,"meta":159},[156],"language-text","https:\u002F\u002Fyoursite.com\u002F?utm_source=hackernews&utm_medium=social&utm_campaign=show-hn\nhttps:\u002F\u002Fyoursite.com\u002F?utm_source=reddit&utm_medium=social&utm_campaign=r-saas\nhttps:\u002F\u002Fyoursite.com\u002F?utm_source=reddit&utm_medium=social&utm_campaign=r-indiehackers\n","text","",[23,161,157],{"__ignoreMap":159},[163,164,165],"warning-box",{},[10,166,167],{},"After you submit to Hacker News, click your own title link from the listing and read the address bar. If the query string is gone, your tags did not survive and every HN visitor falls back to the referrer path in step 2. Do this in the first minute, while changing the submission is still possible.",[40,169,171],{"id":170},"step-2-classify-the-landing","Step 2: Classify the Landing",[10,173,174,175,178],{},"Add this after the OperatorStack script tag. It reads the UTM source first, falls back to the referrer hostname, and only reports ",[23,176,177],{},"direct"," when both are missing.",[153,180,185],{"className":181,"code":183,"language":184,"meta":159},[182],"language-html","\u003Cscript src=\"https:\u002F\u002Foperatorstack.dev\u002Fos.js\" data-project=\"pk_your_project_key\">\u003C\u002Fscript>\n\u003Cscript>\n  function classifyChannel() {\n    const p = new URLSearchParams(location.search);\n    const utm = (p.get(\"utm_source\") || \"\").toLowerCase();\n    if (utm) return { channel: utm, campaign: p.get(\"utm_campaign\") || \"none\", via: \"utm\" };\n\n    let host = \"\";\n    try {\n      host = new URL(document.referrer).hostname.replace(\u002F^www\\.\u002F, \"\");\n    } catch (e) {}\n\n    if (host === \"news.ycombinator.com\")\n      return { channel: \"hackernews\", campaign: \"none\", via: \"referrer\" };\n    if (host.endsWith(\"reddit.com\") || host === \"redd.it\")\n      return { channel: \"reddit\", campaign: \"none\", via: \"referrer\" };\n    return { channel: host || \"direct\", campaign: \"none\", via: host ? \"referrer\" : \"none\" };\n  }\n\n  const landing = classifyChannel();\n  sessionStorage.setItem(\"os_channel\", JSON.stringify(landing));\n  OperatorStack.trackEvent(\"channel_landing\", landing);\n\u003C\u002Fscript>\n","html",[23,186,183],{"__ignoreMap":159},[10,188,189,190,193,194,197],{},"The ",[23,191,192],{},"via"," property is the useful debugging field. If most of your Reddit visits report ",[23,195,196],{},"via: \"referrer\"",", your tagged links are not being clicked, and people are finding the thread another way.",[40,199,201],{"id":200},"step-3-carry-the-channel-onto-the-signup","Step 3: Carry the Channel Onto the Signup",[10,203,204,205,208],{},"A landing event tells you who visited. A signup event tells you who converted. Send the stored channel when ",[23,206,207],{},"joinWaitlist()"," resolves:",[153,210,215],{"className":211,"code":213,"language":214,"meta":159},[212],"language-javascript","async function signUp(email) {\n  const result = await OperatorStack.joinWaitlist({ email });\n  const landing = JSON.parse(sessionStorage.getItem(\"os_channel\") || \"{}\");\n  OperatorStack.trackEvent(\"signup_attributed\", {\n    channel: landing.channel || \"direct\",\n    campaign: landing.campaign || \"none\",\n  });\n  return result;\n}\n","javascript",[23,216,213],{"__ignoreMap":159},[10,218,219,222,223,225],{},[23,220,221],{},"sessionStorage"," is enough on launch day because most signups happen in the same visit. For visitors who return later, read the ",[23,224,125],{}," cookie instead; it is first-touch and lasts 30 days.",[40,227,229],{"id":228},"step-4-read-the-two-events-side-by-side","Step 4: Read the Two Events Side by Side",[10,231,232,233,236,237,240,241,244],{},"Open Analytics, then Events. Pick ",[23,234,235],{},"channel_landing"," and read the ",[23,238,239],{},"channel"," card, then ",[23,242,243],{},"signup_attributed"," and read the same card. Each card lists top values with counts.",[10,246,247,248,250,251,254,255,258,259,261],{},"A worked example. Say ",[23,249,235],{}," shows ",[23,252,253],{},"hackernews"," at 120 and ",[23,256,257],{},"reddit"," at 70, while ",[23,260,243],{}," shows 9 and 14. HN converts at 7.5 percent and Reddit at 20 percent. The thread with more traffic was not the one that produced more signups, and you would have missed that with a single \"direct\" bucket.",[263,264,265],"tip-box",{},[10,266,267,268,271],{},"Compare by ",[23,269,270],{},"campaign"," too. Two subreddits can differ by an order of magnitude, and the answer decides where you post your second launch.",[40,273,275],{"id":274},"mistakes-that-skew-the-numbers","Mistakes That Skew the Numbers",[10,277,278,279,281,282,284],{},"Do not tag links inside the thread comments that point to other pages on your own site. They create a second landing event for a visitor you already counted. Do not reuse one campaign name across threads, or you lose the per-thread breakdown. And do not trust a spike labeled ",[23,280,177],{}," on launch day without checking the ",[23,283,192],{}," property first.",[286,287,288,298,308,321,338],"faq-section",{},[289,290,292],"faq-item",{"question":291},"Why does my analytics show Hacker News traffic as direct?",[10,293,294,295,297],{},"Some visitors arrive with an empty ",[23,296,33],{},": native mobile apps, privacy browsers, or tabs opened with a no-referrer policy. With no referrer and no UTM tag, the visit has no source. A tagged link fixes it.",[289,299,301],{"question":300},"Can I put UTM parameters on a Show HN link?",[10,302,303,304,307],{},"Yes, but test it. After you submit, click the title link from the HN listing and read the address bar. If your tags survived, keep them. If not, use a path-based tag such as ",[23,305,306],{},"\u002Fhn"," that redirects to your landing page.",[289,309,311],{"question":310},"How do I tell Hacker News traffic from Reddit traffic in one report?",[10,312,313,314,316,317,320],{},"Classify each landing from the UTM source first and the referrer hostname second, then send the result as a ",[23,315,239],{}," property with ",[23,318,319],{},"trackEvent()",". The Events tab totals each channel across every page.",[289,322,324],{"question":323},"Which subreddit sent a signup?",[10,325,326,327,329,330,333,334,337],{},"The referrer rarely names the subreddit reliably. Give each post its own ",[23,328,29],{},", such as ",[23,331,332],{},"r-saas"," or ",[23,335,336],{},"r-indiehackers",", and read the breakdown by campaign.",[289,339,341],{"question":340},"How long should I keep watching after launch day?",[10,342,343],{},"Both channels spike for hours, then trickle for weeks as the thread is found through search. The 30-day first-touch cookie keeps credit with the original channel for late converters.",[345,346,347,348],"content-related-articles",{},"\n  ",[349,350,347,352],"contentrelatedcard",{"href":142,"title":143,"description":351},"The os_attribution cookie, first-touch rules, and the per-campaign breakdown this post builds on.",[349,353,347,357],{"href":354,"title":355,"description":356},"\u002Fblog\u002Fhow-to\u002Ftrack-referral-sources","Track Referral Sources on Your Landing Page","What the script tag records on its own and how ?ref= differs from a channel tag.",[349,358,362],{"href":359,"title":360,"description":361},"\u002Fblog\u002Fhow-to\u002Fwarm-up-waitlist-product-hunt","How to Warm Up Your Waitlist Before Product Hunt","The 30-day plan for the launch you are attributing, from list building to launch morning.",[363,364],"cta-box",{"href":365,"label":366},"\u002F","Get Started Free",{"title":159,"searchDepth":368,"depth":368,"links":369},2,[370,371,372,373,374,375],{"id":42,"depth":368,"text":43},{"id":147,"depth":368,"text":148},{"id":170,"depth":368,"text":171},{"id":200,"depth":368,"text":201},{"id":228,"depth":368,"text":229},{"id":274,"depth":368,"text":275},"how-to","2026-11-04",null,"Attribute launch-day signups to Hacker News and Reddit when referrers are truncated or empty. A channel classifier, a trackEvent bridge, and a per-thread tag.",false,"md",[383,385,387,389,391],{"question":291,"answer":384},"Some visitors arrive with an empty document.referrer: links opened from native mobile apps, from privacy browsers, or from a tab opened with a no-referrer policy. With no referrer and no UTM tag, the visit has no source and gets filed as direct. A tagged link fixes it.",{"question":300,"answer":386},"Yes, but test it. After you submit, open the title link from the HN listing and read the address bar. If your tags survived, keep them. If not, rely on the referrer host and a path-based tag such as \u002Fhn that redirects to your landing page.",{"question":310,"answer":388},"Classify each landing in JavaScript from the UTM source first and the referrer hostname second, then send the result as a channel property on a trackEvent() call. The Events tab then totals each channel across every page.",{"question":323,"answer":390},"Reddit's referrer rarely names the subreddit reliably. Give each post its own utm_campaign, such as r-saas or r-indiehackers, and read the breakdown by campaign.",{"question":340,"answer":392},"Both channels spike for hours, then trickle for weeks as the thread is found via search. The 30-day first-touch cookie keeps credit with the original channel for late converters.","track hacker news reddit signups,show hn signup tracking,reddit referrer missing,launch day attribution,document.referrer hacker news,operatorstack trackevent",{},true,"Hacker News sends an origin-only referrer and Reddit apps often send none. Here is how to still know which thread produced each signup.","Track Hacker News and Reddit Signups","\u002Fblog\u002Fhow-to\u002Ftrack-hacker-news-reddit-signups","7 min","HowTo",{"title":5,"description":379},{"loc":398},"blog\u002Fhow-to\u002Ftrack-hacker-news-reddit-signups",[],"summary_large_image","oyvefSPRWi1nbQ1YsOvcVdFJARjc8u1-hjHZ75RS4WA",1793791550905]