Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions apps/sim/app/(auth)/signup/signup-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Turnstile, type TurnstileInstance } from '@marsidev/react-turnstile'
import { createLogger } from '@sim/logger'
import { useRouter, useSearchParams } from 'next/navigation'
import { usePostHog } from 'posthog-js/react'
import { trackFreebuffConversion } from '@/lib/analytics/freebuff'
import { trackGoogleEvent } from '@/lib/analytics/google'
import { client, useSession } from '@/lib/auth/client'
import { DISPOSABLE_EMAIL_ERROR_CODE, DISPOSABLE_EMAIL_MESSAGE } from '@/lib/auth/constants'
Expand Down Expand Up @@ -112,7 +111,7 @@ function SignupFormContent({
const searchParams = useSearchParams()
const { refetch: refetchSession } = useSession()
const posthog = usePostHog()
const { measurement, marketing } = useTrackingConsent()
const { measurement } = useTrackingConsent()
useCaptureWhenReady('signup_page_viewed', {})
const [isLoading, setIsLoading] = useState(false)

Expand Down Expand Up @@ -352,7 +351,6 @@ function SignupFormContent({
}

if (measurement) trackGoogleEvent('sign_up', { method: 'email' })
if (marketing) trackFreebuffConversion('signup_completed', response.data.user.id)

try {
await refetchSession()
Expand Down
12 changes: 2 additions & 10 deletions apps/sim/app/(landing)/cookie-policy/cookie-policy-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const COOKIE_POLICY_CONFIG: LegalPageConfig = {
title: 'Cookie Policy',
description:
'What cookies Sim sets, why, how long they last, and how to change your choice at any time.',
lastUpdated: 'October 13, 2026',
lastUpdated: 'November 12, 2026',
intro: [
{
kind: 'paragraph',
Expand Down Expand Up @@ -238,12 +238,6 @@ export const COOKIE_POLICY_CONFIG: LegalPageConfig = {
],
['personalization_id', 'X (Twitter)', 'Personalizes the ads shown on X.', '13 months'],
['muc_ads', 'X (Twitter)', 'Measures ad conversions across X domains.', '13 months'],
[
'bfcid',
'Freebuff',
'Stores the click identifier from a Freebuff ad that brought you to sim.ai, so a sign-up can be credited to that ad. Deleted if you withdraw Marketing consent.',
'30 days',
],
]),
],
},
Expand Down Expand Up @@ -280,8 +274,7 @@ export const COOKIE_POLICY_CONFIG: LegalPageConfig = {
</ProseLink>
, <ProseLink href='https://adssettings.google.com'>Google Ads</ProseLink>,{' '}
<ProseLink href='https://x.com/settings/privacy_and_safety'>X (Twitter)</ProseLink>,
and <ProseLink href='https://posthog.com/privacy'>PostHog</ProseLink>. For Freebuff,{' '}
{CHANGE_CHOICES} to withdraw Marketing consent.
and <ProseLink href='https://posthog.com/privacy'>PostHog</ProseLink>.
</>
),
},
Expand All @@ -303,7 +296,6 @@ export const COOKIE_POLICY_CONFIG: LegalPageConfig = {
<ProseLink href='https://policies.google.com/technologies/cookies'>Google</ProseLink>{' '}
(Analytics and Ads),{' '}
<ProseLink href='https://x.com/en/privacy'>X (Twitter)</ProseLink>,{' '}
<ProseLink href='https://freebuff.com/privacy-policy'>Freebuff</ProseLink>,{' '}
<ProseLink href='https://ahrefs.com/legal/privacy-policy'>Ahrefs</ProseLink>,{' '}
<ProseLink href='https://posthog.com/privacy'>PostHog</ProseLink>, and{' '}
<ProseLink href='https://www.cloudflare.com/privacypolicy/'>Cloudflare</ProseLink>.
Expand Down
17 changes: 4 additions & 13 deletions apps/sim/app/(landing)/privacy/privacy-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function richText(content: string): ReactNode {
export const PRIVACY_CONFIG: LegalPageConfig = {
title: 'Privacy Policy',
description: 'Sim Studio, Inc. · Operating the Sim platform (sim.ai)',
lastUpdated: 'November 4, 2026',
lastUpdated: 'November 12, 2026',
intro: [
{
kind: 'paragraph',
Expand Down Expand Up @@ -263,7 +263,7 @@ export const PRIVACY_CONFIG: LegalPageConfig = {
],
[
'Behavioral remarketing',
'Cookie and pixel identifiers, ad click identifiers, browser and Device data, campaign attribution, website interaction data, and, for Freebuff sign-up conversions, a pseudonymous Sim Account identifier and the sign-up time',
'Cookie and pixel identifiers, ad click identifiers, browser and Device data, campaign attribution, and website interaction data',
'Consent — Article 6(1)(a)',
'Marketing cookies and ad personalization require Marketing consent. Google Ads may load earlier with ad storage denied and send limited cookieless consent signals. Consent may be changed or withdrawn through the cookie preferences link.',
],
Expand Down Expand Up @@ -577,7 +577,7 @@ export const PRIVACY_CONFIG: LegalPageConfig = {
{
kind: 'paragraph',
content: richText(
'Sim advertises through Google Ads, X, and Freebuff, and measures which ads lead to sign-ups and demo bookings. These services use non-essential Cookies, pixels, and similar technologies. Marketing Cookies and ad personalization are enabled only after You consent to the Marketing category in the cookie banner.'
'Sim advertises through Google Ads and X, and measures which ads lead to sign-ups and demo bookings. These services use non-essential Cookies, pixels, and similar technologies. Marketing Cookies and ad personalization are enabled only after You consent to the Marketing category in the cookie banner.'
),
},
{
Expand All @@ -592,12 +592,6 @@ export const PRIVACY_CONFIG: LegalPageConfig = {
"**X.** The X pixel loads on Sim's marketing pages only after Marketing consent. It reports page views and demo bookings."
),
},
{
kind: 'paragraph',
content: richText(
'**Freebuff.** After Marketing consent, the Freebuff tag stores the click identifier from a Freebuff ad. When You sign up, Sim sends Freebuff that click identifier, the event type, a pseudonymous Sim Account identifier, and the sign-up time so the sign-up can be credited to the ad. Sim does not send Your name or email address.'
),
},
{
kind: 'paragraph',
content: richText(
Expand All @@ -621,9 +615,6 @@ export const PRIVACY_CONFIG: LegalPageConfig = {
richText(
'X: [Personalization and data settings](https://x.com/settings/privacy_and_safety)'
),
richText(
'Freebuff: withdraw Marketing consent through the cookie preferences link; Sim then deletes the Freebuff click identifier cookie'
),
],
},
],
Expand Down Expand Up @@ -987,7 +978,7 @@ export const PRIVACY_CONFIG: LegalPageConfig = {
{
kind: 'paragraph',
content: richText(
'We do not sell Personal Information for money. When Marketing Cookies are enabled, Sim makes identifiers and internet activity on sim.ai available to Google, X, and Freebuff for advertising and ad measurement. This includes cookie and click identifiers, pages visited, and conversion events. California law may treat this as a "sale" or "sharing" of Personal Information. You may opt out at any time through the cookie preferences link, by sending a Global Privacy Control signal, or by emailing privacy@sim.ai. Sim does not knowingly sell or share the Personal Information of consumers under 16.'
'We do not sell Personal Information for money. When Marketing Cookies are enabled, Sim makes identifiers and internet activity on sim.ai available to Google and X for advertising and ad measurement. This includes cookie and click identifiers, pages visited, and conversion events. California law may treat this as a "sale" or "sharing" of Personal Information. You may opt out at any time through the cookie preferences link, by sending a Global Privacy Control signal, or by emailing privacy@sim.ai. Sim does not knowingly sell or share the Personal Information of consumers under 16.'
),
},
{ kind: 'subheading', text: 'Global Privacy Control' },
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/_shell/consent/consent-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { TrackingConsentProvider } from '@/lib/consent/tracking-consent'
import { AttributionCookieGuard } from '@/app/_shell/consent/attribution-cookie-guard'
import { ConsentBanner } from '@/app/_shell/consent/consent-banner'
import { ConsentStoreProvider } from '@/app/_shell/consent/consent-store-provider'
import { FreebuffClickIdGuard } from '@/app/_shell/consent/freebuff-click-id-guard'
import { GoogleAnalyticsPageViewTracker } from '@/app/_shell/consent/google-analytics-page-view-tracker'
import { RetiredCookieCleanup } from '@/app/_shell/consent/retired-cookie-cleanup'

interface ConsentProviderProps {
children: ReactNode
Expand All @@ -24,8 +24,8 @@ export function ConsentProvider({ children }: ConsentProviderProps) {
<TrackingConsentProvider>
{children}
<GoogleAnalyticsPageViewTracker />
<FreebuffClickIdGuard />
<AttributionCookieGuard />
Comment thread
waleedlatif1 marked this conversation as resolved.
Resolved
<RetiredCookieCleanup />
<ConsentBanner />
</TrackingConsentProvider>
</ConsentStoreProvider>
Expand Down
21 changes: 0 additions & 21 deletions apps/sim/app/_shell/consent/freebuff-click-id-guard.tsx

This file was deleted.

24 changes: 24 additions & 0 deletions apps/sim/app/_shell/consent/retired-cookie-cleanup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client'

import { useEffect } from 'react'

/**
* Cookies a removed integration may have left in returning browsers. Nothing
* reads them any more, so they are deleted whatever the visitor's consent:
* keeping an unused advertising identifier serves no one. `bfcid` lives at most
* 30 days, so this list can be emptied once that window has passed.
*/
const RETIRED_COOKIES = ['bfcid'] as const

/** Deletes every retired cookie present in this browser, once per page load. */
export function RetiredCookieCleanup() {
Comment thread
waleedlatif1 marked this conversation as resolved.
Resolved
useEffect(() => {
for (const name of RETIRED_COOKIES) {
if (document.cookie.includes(`${name}=`)) {
document.cookie = `${name}=; Max-Age=0; Path=/; SameSite=Lax`
}
}
}, [])

return null
}
1 change: 0 additions & 1 deletion apps/sim/lib/analytics/attribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const CLICK_ID_PARAMETERS = [
'ttclid',
'twclid',
'rdt_cid',
'bfcid',
] as const

/**
Expand Down
67 changes: 0 additions & 67 deletions apps/sim/lib/analytics/freebuff.server.ts

This file was deleted.

49 changes: 0 additions & 49 deletions apps/sim/lib/analytics/freebuff.ts

This file was deleted.

19 changes: 0 additions & 19 deletions apps/sim/lib/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ import {
renderWelcomeEmail,
} from '@/components/emails'
import { readAttributionProperties } from '@/lib/analytics/attribution'
import { FREEBUFF_CLICK_ID_COOKIE } from '@/lib/analytics/freebuff'
import { reportFreebuffConversion } from '@/lib/analytics/freebuff.server'
import { getAccessControlConfig, isEmailBlockedByAccessControl } from '@/lib/auth/access-control'
import { enqueueAdminRemovedChatCleanup } from '@/lib/auth/admin-removal-chat-cleanup'
import { holdAdminRemovalStops, stopAdminRemovedRuns } from '@/lib/auth/admin-removal-stops'
Expand Down Expand Up @@ -373,23 +371,6 @@ export const auth = betterAuth({
userId: user.id,
})

/**
* Only the marketing-consent-gated Freebuff tag writes the `bfcid`
* cookie, and `FreebuffClickIdGuard` deletes it once marketing consent
* is withdrawn or expires. Not awaited: the postback
* retries on its own and must never delay signup. The browser tag
* reports the same `eventId` on email signup and Freebuff dedupes.
*/
const freebuffClickId = context?.getCookie(FREEBUFF_CLICK_ID_COOKIE)
if (freebuffClickId) {
void reportFreebuffConversion({
clickId: freebuffClickId,
eventType: 'signup_completed',
eventId: user.id,
occurredAt: user.createdAt,
})
}

try {
PlatformEvents.userSignedUp({
userId: user.id,
Expand Down
14 changes: 0 additions & 14 deletions apps/sim/lib/consent/scripts.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ahrefsAnalytics } from '@c15t/scripts/ahrefs-analytics'
import { gtag } from '@c15t/scripts/google-tag'
import { xPixel } from '@c15t/scripts/x-pixel'
import { FREEBUFF_TAG_SRC, installFreebuffStub } from '@/lib/analytics/freebuff'
import { getGooglePageLocation, updateGooglePageContext } from '@/lib/consent/google-context'
import { isPathOrDescendant } from '@/lib/navigation/paths'

Expand Down Expand Up @@ -53,19 +52,6 @@ const GLOBAL_CONSENT_SCRIPTS = [
},
},
ahrefsAnalytics({ key: AHREFS_ANALYTICS_KEY }),
/**
* Global rather than landing-only: the ad lands on a marketing page but the
* conversion fires from `/signup`. The tag recovers `?bfcid=` from the
* original navigation entry, so a client-side route change before consent
* resolves does not lose the click id.
*/
{
id: 'freebuff-tag',
src: FREEBUFF_TAG_SRC,
category: 'marketing',
async: true,
onBeforeLoad: installFreebuffStub,
},
] as const

/** Excludes embedded extension pages and restricts Google's loader to production origins. */
Expand Down
1 change: 0 additions & 1 deletion apps/sim/lib/core/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ export const env = createEnv({

// Monitoring & Analytics
TELEMETRY_ENDPOINT: z.string().url().optional(), // Custom telemetry/analytics endpoint
FREEBUFF_API_KEY: z.string().min(1).optional(), // Freebuff Ads key for server-side conversion postbacks (unset disables them)
COST_MULTIPLIER: z.number().optional(), // Multiplier for cost calculations
LOG_LEVEL: z.enum(['DEBUG', 'INFO', 'WARN', 'ERROR']).optional(), // Minimum log level to display (defaults to ERROR in production, DEBUG in development)
GRAFANA_OTLP_ENDPOINT: z.string().url().optional(), // Grafana Cloud OTLP HTTP gateway base URL (e.g., https://otlp-gateway-prod-us-east-0.grafana.net/otlp). Trigger.dev exporters append /v1/traces, /v1/logs, /v1/metrics.
Expand Down
Loading
Loading