Merge pull request #748 from elammertsma/dev

feat: Implemented hero A/B test, added Contact Sales button
This commit is contained in:
Rohan Verma 2026-01-27 16:03:02 -08:00 committed by GitHub
commit 114ac59c0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 16 deletions

View file

@ -1,4 +1,5 @@
"use client"; "use client";
import { useFeatureFlagVariantKey } from "@posthog/react";
import { AnimatePresence, motion } from "motion/react"; import { AnimatePresence, motion } from "motion/react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
@ -33,6 +34,8 @@ const GoogleLogo = ({ className }: { className?: string }) => (
export function HeroSection() { export function HeroSection() {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const parentRef = useRef<HTMLDivElement>(null); const parentRef = useRef<HTMLDivElement>(null);
const heroVariant = useFeatureFlagVariantKey("notebooklm_flag");
const isNotebookLMVariant = heroVariant === "notebooklm";
return ( return (
<div <div
@ -83,12 +86,22 @@ export function HeroSection() {
<h2 className="relative z-50 mx-auto mb-4 mt-4 max-w-4xl text-balance text-center text-3xl font-semibold tracking-tight text-gray-700 md:text-7xl dark:text-neutral-300"> <h2 className="relative z-50 mx-auto mb-4 mt-4 max-w-4xl text-balance text-center text-3xl font-semibold tracking-tight text-gray-700 md:text-7xl dark:text-neutral-300">
<Balancer> <Balancer>
The AI Workspace{" "} {isNotebookLMVariant ? (
<div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]"> <div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]">
<div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white"> <div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white">
<span className="">Built for Teams</span> <span className="">NotebookLM for Teams</span>
</div>
</div> </div>
</div> ) : (
<>
The AI Workspace{" "}
<div className="relative mx-auto inline-block w-max filter-[drop-shadow(0px_1px_3px_rgba(27,37,80,0.14))]">
<div className="text-black [text-shadow:0_0_rgba(0,0,0,0.1)] dark:text-white">
<span className="">Built for Teams</span>
</div>
</div>
</>
)}
</Balancer> </Balancer>
</h2> </h2>
{/* // TODO:aCTUAL DESCRITION */} {/* // TODO:aCTUAL DESCRITION */}
@ -96,15 +109,10 @@ export function HeroSection() {
Connect any LLM to your internal knowledge sources and chat with it in real time alongside Connect any LLM to your internal knowledge sources and chat with it in real time alongside
your team. your team.
</p> </p>
<div className="mb-10 mt-8 flex w-full flex-col items-center justify-center gap-4 px-8 sm:flex-row md:mb-20"> <div className="mb-10 mt-8 flex w-full flex-col items-center justify-center gap-4 px-8 sm:flex-row md:mb-20">
<GetStartedButton /> <GetStartedButton />
{/* <Link <ContactSalesButton />
href="/pricing" </div>
className="shadow-input group relative z-20 flex h-10 w-full cursor-pointer items-center justify-center space-x-2 rounded-lg bg-white p-px px-4 py-2 text-sm font-semibold leading-6 text-black no-underline transition duration-200 hover:-translate-y-0.5 sm:w-52 dark:bg-neutral-800 dark:text-white"
>
Start Free Trial
</Link> */}
</div>
<div <div
ref={containerRef} ref={containerRef}
className="relative mx-auto max-w-7xl rounded-[32px] border border-neutral-200/50 bg-neutral-100 p-2 backdrop-blur-lg md:p-4 dark:border-neutral-700 dark:bg-neutral-800/50" className="relative mx-auto max-w-7xl rounded-[32px] border border-neutral-200/50 bg-neutral-100 p-2 backdrop-blur-lg md:p-4 dark:border-neutral-700 dark:bg-neutral-800/50"
@ -193,6 +201,21 @@ function GetStartedButton() {
); );
} }
function ContactSalesButton() {
return (
<motion.div whileHover={{ scale: 1.02, y: -2 }} whileTap={{ scale: 0.98 }}>
<Link
href="https://calendly.com/eric-surfsense/surfsense-meeting"
target="_blank"
rel="noopener noreferrer"
className="group relative z-20 flex h-11 w-full cursor-pointer items-center justify-center gap-2 rounded-xl bg-white px-6 py-2.5 text-sm font-semibold text-neutral-700 shadow-lg ring-1 ring-neutral-200/50 transition-shadow duration-300 hover:shadow-xl sm:w-56 dark:bg-neutral-900 dark:text-neutral-200 dark:ring-neutral-700/50"
>
Contact Sales
</Link>
</motion.div>
);
}
const BackgroundGrids = () => { const BackgroundGrids = () => {
return ( return (
<div className="pointer-events-none absolute inset-0 z-0 grid h-full w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4"> <div className="pointer-events-none absolute inset-0 z-0 grid h-full w-full -rotate-45 transform select-none grid-cols-2 gap-10 md:grid-cols-4">

View file

@ -3,6 +3,7 @@
import { PostHogProvider as PHProvider } from "@posthog/react"; import { PostHogProvider as PHProvider } from "@posthog/react";
import posthog from "posthog-js"; import posthog from "posthog-js";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import "../../instrumentation-client";
import { PostHogIdentify } from "./PostHogIdentify"; import { PostHogIdentify } from "./PostHogIdentify";
interface PostHogProviderProps { interface PostHogProviderProps {
@ -10,8 +11,8 @@ interface PostHogProviderProps {
} }
export function PostHogProvider({ children }: PostHogProviderProps) { export function PostHogProvider({ children }: PostHogProviderProps) {
// posthog-js is already initialized in instrumentation-client.ts // posthog-js is initialized by importing instrumentation-client.ts above
// We just need to wrap the app with the PostHogProvider for hook access // We wrap the app with the PostHogProvider for hook access
return ( return (
<PHProvider client={posthog}> <PHProvider client={posthog}>
<PostHogIdentify /> <PostHogIdentify />

View file

@ -12,5 +12,17 @@ if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
capture_pageview: "history_change", capture_pageview: "history_change",
// Enable session recording // Enable session recording
capture_pageleave: true, capture_pageleave: true,
loaded: (posthog) => {
// Expose PostHog to window for console access and toolbar
if (typeof window !== "undefined") {
window.posthog = posthog;
}
},
}); });
} }
// Always expose posthog to window for debugging/toolbar access
// This allows testing feature flags even without POSTHOG_KEY configured
if (typeof window !== "undefined") {
window.posthog = posthog;
}

9
surfsense_web/types/window.d.ts vendored Normal file
View file

@ -0,0 +1,9 @@
import type { PostHog } from "posthog-js";
declare global {
interface Window {
posthog?: PostHog;
}
}
export {};