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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Textarea,
} from '@/components/emcn'
import { Check } from '@/components/emcn/icons'
import { captureClientEvent } from '@/lib/posthog/client'
import {
DEMO_REQUEST_COMPANY_SIZE_OPTIONS,
type DemoRequestPayload,
Expand Down Expand Up @@ -163,6 +164,9 @@ export function DemoRequestModal({ children, theme = 'dark' }: DemoRequestModalP
}

setSubmitSuccess(true)
captureClientEvent('landing_demo_request_submitted', {
company_size: parsed.data.companySize,
})
} catch (error) {
setSubmitError(
error instanceof Error
Expand Down
13 changes: 13 additions & 0 deletions apps/sim/app/(landing)/components/footer/footer-cta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import { useCallback, useRef, useState } from 'react'
import { ArrowUp } from 'lucide-react'
import Link from 'next/link'
import { captureClientEvent } from '@/lib/posthog/client'
import { useLandingSubmit } from '@/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel'
import { trackLandingCta } from '@/app/(landing)/landing-analytics'
import { useAnimatedPlaceholder } from '@/hooks/use-animated-placeholder'

const MAX_HEIGHT = 120
Expand All @@ -21,6 +23,7 @@ export function FooterCTA() {

const handleSubmit = useCallback(() => {
if (isEmpty) return
captureClientEvent('landing_prompt_submitted', {})
landingSubmit(inputValue)
}, [isEmpty, inputValue, landingSubmit])

Expand Down Expand Up @@ -94,12 +97,22 @@ export function FooterCTA() {
target='_blank'
rel='noopener noreferrer'
className={`${CTA_BUTTON} border-[var(--landing-border-strong)] text-[var(--landing-text)] transition-colors hover:bg-[var(--landing-bg-elevated)]`}
onClick={() =>
trackLandingCta({
label: 'Docs',
section: 'footer_cta',
destination: 'https://docs.sim.ai',
})
}
>
Docs
</a>
<Link
href='/signup'
className={`${CTA_BUTTON} gap-2 border-white bg-white text-black transition-colors hover:border-[#E0E0E0] hover:bg-[#E0E0E0]`}
onClick={() =>
trackLandingCta({ label: 'Get started', section: 'footer_cta', destination: '/signup' })
}
>
Get started
</Link>
Expand Down
7 changes: 7 additions & 0 deletions apps/sim/app/(landing)/components/hero/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dynamic from 'next/dynamic'
import Link from 'next/link'
import { DemoRequestModal } from '@/app/(landing)/components/demo-request/demo-request-modal'
import { trackLandingCta } from '@/app/(landing)/landing-analytics'

const LandingPreview = dynamic(
() =>
Expand Down Expand Up @@ -57,6 +58,9 @@ export default function Hero() {
type='button'
className={`${CTA_BASE} border-[var(--landing-border-strong)] bg-transparent text-[var(--landing-text)] transition-colors hover:bg-[var(--landing-bg-elevated)]`}
aria-label='Get a demo'
onClick={() =>
trackLandingCta({ label: 'Get a demo', section: 'hero', destination: 'demo_modal' })
}
>
Get a demo
</button>
Expand All @@ -65,6 +69,9 @@ export default function Hero() {
href='/signup'
className={`${CTA_BASE} gap-2 border-white bg-white text-black transition-colors hover:border-[#E0E0E0] hover:bg-[#E0E0E0]`}
aria-label='Get started with Sim'
onClick={() =>
trackLandingCta({ label: 'Get started', section: 'hero', destination: '/signup' })
}
>
Get started
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AnimatePresence, motion } from 'framer-motion'
import { ArrowUp, Table } from 'lucide-react'
import { Blimp, Checkbox, ChevronDown } from '@/components/emcn'
import { TypeBoolean, TypeNumber, TypeText } from '@/components/emcn/icons'
import { captureClientEvent } from '@/lib/posthog/client'
import { useLandingSubmit } from '@/app/(landing)/components/landing-preview/components/landing-preview-panel/landing-preview-panel'
import { EASE_OUT } from '@/app/(landing)/components/landing-preview/components/landing-preview-workflow/workflow-data'
import { useAnimatedPlaceholder } from '@/hooks/use-animated-placeholder'
Expand Down Expand Up @@ -151,6 +152,7 @@ export const LandingPreviewHome = memo(function LandingPreviewHome({

const handleSubmit = useCallback(() => {
if (isEmpty) return
captureClientEvent('landing_prompt_submitted', {})
landingSubmit(inputValue)
}, [isEmpty, inputValue, landingSubmit])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createPortal } from 'react-dom'
import { Blimp, BubbleChatPreview, ChevronDown, MoreHorizontal, Play } from '@/components/emcn'
import { AgentIcon, HubspotIcon, OpenAIIcon, SalesforceIcon } from '@/components/icons'
import { LandingPromptStorage } from '@/lib/core/utils/browser-storage'
import { captureClientEvent } from '@/lib/posthog/client'
import {
EASE_OUT,
type EditorPromptData,
Expand Down Expand Up @@ -147,6 +148,7 @@ export const LandingPreviewPanel = memo(function LandingPreviewPanel({

const handleSubmit = useCallback(() => {
if (isEmpty) return
captureClientEvent('landing_prompt_submitted', {})
landingSubmit(inputValue)
}, [isEmpty, inputValue, landingSubmit])

Expand Down
41 changes: 38 additions & 3 deletions apps/sim/app/(landing)/components/navbar/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@/app/(landing)/components/navbar/components/blog-dropdown'
import { DocsDropdown } from '@/app/(landing)/components/navbar/components/docs-dropdown'
import { GitHubStars } from '@/app/(landing)/components/navbar/components/github-stars'
import { trackLandingCta } from '@/app/(landing)/landing-analytics'
import { getBrandConfig } from '@/ee/whitelabeling'

type DropdownId = 'docs' | 'blog' | null
Expand Down Expand Up @@ -212,6 +213,13 @@ export default function Navbar({ logoOnly = false, blogPosts = [] }: NavbarProps
href='/workspace'
className='inline-flex h-[30px] items-center gap-[7px] rounded-[5px] border border-[var(--white)] bg-[var(--white)] px-[9px] text-[13.5px] text-black transition-colors hover:border-[#E0E0E0] hover:bg-[#E0E0E0]'
aria-label='Go to app'
onClick={() =>
trackLandingCta({
label: 'Go to App',
section: 'navbar',
destination: '/workspace',
})
}
>
Go to App
</Link>
Expand All @@ -221,13 +229,23 @@ export default function Navbar({ logoOnly = false, blogPosts = [] }: NavbarProps
href='/login'
className='inline-flex h-[30px] items-center rounded-[5px] border border-[var(--landing-border-strong)] px-[9px] text-[13.5px] text-[var(--landing-text)] transition-colors hover:bg-[var(--landing-bg-elevated)]'
aria-label='Log in'
onClick={() =>
trackLandingCta({ label: 'Log in', section: 'navbar', destination: '/login' })
}
>
Log in
</Link>
<Link
href='/signup'
className='inline-flex h-[30px] items-center gap-[7px] rounded-[5px] border border-[var(--white)] bg-[var(--white)] px-2.5 text-[13.5px] text-black transition-colors hover:border-[#E0E0E0] hover:bg-[#E0E0E0]'
aria-label='Get started with Sim'
onClick={() =>
trackLandingCta({
label: 'Get started',
section: 'navbar',
destination: '/signup',
})
}
>
Get started
</Link>
Expand Down Expand Up @@ -303,7 +321,14 @@ export default function Navbar({ logoOnly = false, blogPosts = [] }: NavbarProps
<Link
href='/workspace'
className='flex h-[32px] items-center justify-center rounded-[5px] border border-[var(--white)] bg-[var(--white)] text-[14px] text-black transition-colors active:bg-[#E0E0E0]'
onClick={() => setMobileMenuOpen(false)}
onClick={() => {
trackLandingCta({
label: 'Go to App',
section: 'navbar',
destination: '/workspace',
})
setMobileMenuOpen(false)
}}
aria-label='Go to app'
>
Go to App
Expand All @@ -313,15 +338,25 @@ export default function Navbar({ logoOnly = false, blogPosts = [] }: NavbarProps
<Link
href='/login'
className='flex h-[32px] items-center justify-center rounded-[5px] border border-[var(--landing-border-strong)] text-[14px] text-[var(--landing-text)] transition-colors active:bg-[var(--landing-bg-elevated)]'
onClick={() => setMobileMenuOpen(false)}
onClick={() => {
trackLandingCta({ label: 'Log in', section: 'navbar', destination: '/login' })
setMobileMenuOpen(false)
}}
aria-label='Log in'
>
Log in
</Link>
<Link
href='/signup'
className='flex h-[32px] items-center justify-center rounded-[5px] border border-[var(--white)] bg-[var(--white)] text-[14px] text-black transition-colors active:bg-[#E0E0E0]'
onClick={() => setMobileMenuOpen(false)}
onClick={() => {
trackLandingCta({
label: 'Get started',
section: 'navbar',
destination: '/signup',
})
setMobileMenuOpen(false)
}}
aria-label='Get started with Sim'
>
Get started
Expand Down
22 changes: 22 additions & 0 deletions apps/sim/app/(landing)/components/pricing/pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import Link from 'next/link'
import { Badge } from '@/components/emcn'
import { DemoRequestModal } from '@/app/(landing)/components/demo-request/demo-request-modal'
import { trackLandingCta } from '@/app/(landing)/landing-analytics'

interface PricingTier {
id: string
Expand Down Expand Up @@ -150,6 +151,13 @@ function PricingCard({ tier }: PricingCardProps) {
<button
type='button'
className='flex h-[32px] w-full items-center justify-center rounded-[5px] border border-[var(--landing-border-light)] bg-transparent px-2.5 font-[430] font-season text-[14px] text-[var(--landing-text-dark)] transition-colors hover:bg-[var(--landing-bg-hover)]'
onClick={() =>
trackLandingCta({
label: tier.cta.label,
section: 'pricing',
destination: 'demo_modal',
})
}
>
{tier.cta.label}
</button>
Expand All @@ -158,13 +166,27 @@ function PricingCard({ tier }: PricingCardProps) {
<Link
href={tier.cta.href || '/signup'}
className='flex h-[32px] w-full items-center justify-center rounded-[5px] border border-[#1D1D1D] bg-[#1D1D1D] px-2.5 font-[430] font-season text-[14px] text-white transition-colors hover:border-[var(--landing-border)] hover:bg-[var(--landing-bg-elevated)]'
onClick={() =>
trackLandingCta({
label: tier.cta.label,
section: 'pricing',
destination: tier.cta.href || '/signup',
})
}
>
{tier.cta.label}
</Link>
) : (
<Link
href={tier.cta.href || '/signup'}
className='flex h-[32px] w-full items-center justify-center rounded-[5px] border border-[var(--landing-border-light)] px-2.5 font-[430] font-season text-[14px] text-[var(--landing-text-dark)] transition-colors hover:bg-[var(--landing-bg-hover)]'
onClick={() =>
trackLandingCta({
label: tier.cta.label,
section: 'pricing',
destination: tier.cta.href || '/signup',
})
}
>
{tier.cta.label}
</Link>
Expand Down
11 changes: 10 additions & 1 deletion apps/sim/app/(landing)/landing-analytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import { useEffect } from 'react'
import { usePostHog } from 'posthog-js/react'
import { captureEvent } from '@/lib/posthog/client'
import { captureClientEvent, captureEvent } from '@/lib/posthog/client'
import type { PostHogEventMap } from '@/lib/posthog/events'

export function LandingAnalytics() {
const posthog = usePostHog()
Expand All @@ -13,3 +14,11 @@ export function LandingAnalytics() {

return null
}

/**
* Fire-and-forget tracker for landing page CTA clicks.
* Uses the non-hook client so it works in any click handler without requiring a PostHog provider ref.
*/
export function trackLandingCta(props: PostHogEventMap['landing_cta_clicked']): void {
captureClientEvent('landing_cta_clicked', props)
}
12 changes: 12 additions & 0 deletions apps/sim/lib/posthog/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ export interface PostHogEventMap {

landing_page_viewed: Record<string, never>

landing_cta_clicked: {
label: string
section: 'hero' | 'navbar' | 'footer_cta' | 'pricing'
destination: string
}

landing_demo_request_submitted: {
company_size: string
}

landing_prompt_submitted: Record<string, never>

signup_page_viewed: Record<string, never>

subscription_created: {
Expand Down
Loading