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
2 changes: 2 additions & 0 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ LEMON_SQUEEZY_SIGNING_SECRET=

NEXT_PUBLIC_PRO_PAYMENT_LINK=
NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK=

NEXT_PUBLIC_POSTHOG_KEY=
18 changes: 2 additions & 16 deletions apps/web/app/(landing)/home/CTA.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import Link from "next/link";
import { Button } from "@/components/Button";
import { GithubIcon } from "lucide-react";
import { CTAButtons } from "@/app/(landing)/home/CTAButtons";

export function CTA() {
return (
Expand Down Expand Up @@ -28,19 +26,7 @@ export function CTA() {
took hours, now takes minutes. Inbox Zero is your virtual assistant
for emails.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<Button size="2xl" link={{ href: "/waitlist" }}>
Join Waitlist
</Button>
<Button
size="2xl"
color="white"
link={{ href: "/github", target: "_blank" }}
>
<GithubIcon className="mr-2 h-4 w-4" />
Star on GitHub
</Button>
</div>
<CTAButtons />
</div>
{/* <div
className="absolute left-1/2 right-0 top-full -z-10 hidden -translate-y-1/2 transform-gpu overflow-hidden blur-3xl sm:block"
Expand Down
34 changes: 34 additions & 0 deletions apps/web/app/(landing)/home/CTAButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { GithubIcon } from "lucide-react";
import { Button } from "@/components/Button";
import { usePostHog } from "posthog-js/react";

export function CTAButtons() {
const posthog = usePostHog();

return (
<div className="mt-10 flex items-center justify-center gap-x-6">
<Button
size="2xl"
link={{ href: "/waitlist" }}
onClick={() => {
posthog.capture("Clicked Join Waitlist");
}}
>
Join Waitlist
</Button>
<Button
size="2xl"
color="white"
link={{ href: "/github", target: "_blank" }}
onClick={() => {
posthog.capture("Clicked Star on Github", {});
}}
>
<GithubIcon className="mr-2 h-4 w-4" />
Star on GitHub
</Button>
</div>
);
}
20 changes: 4 additions & 16 deletions apps/web/app/(landing)/home/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GithubIcon } from "lucide-react";
import Image from "next/image";
import { Button } from "@/components/Button";
import { HeroHeadingAB } from "@/app/(landing)/home/HeroHeadingAB";
import { CTAButtons } from "@/app/(landing)/home/CTAButtons";

export function Hero() {
return (
Expand Down Expand Up @@ -52,26 +52,14 @@ export function Hero() {
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl text-center">
<h1 className="font-cal text-4xl font-bold text-gray-900 sm:text-6xl">
Automate your emails with the power of AI
<HeroHeadingAB />
</h1>
<p className="mt-6 text-lg leading-8 text-gray-600">
Inbox Zero helps you handle emails faster with AI assistance.
Automate replies and answer your users in seconds. Understand what
{"'"}s filling up your inbox with our detailed analytics.
</p>
<div className="mt-10 flex items-center justify-center gap-x-6">
<Button size="2xl" link={{ href: "/waitlist" }}>
Join Waitlist
</Button>
<Button
size="2xl"
color="white"
link={{ href: "/github", target: "_blank" }}
>
<GithubIcon className="mr-2 h-4 w-4" />
Star on GitHub
</Button>
</div>
<CTAButtons />
</div>
<div className="mt-16 flow-root sm:mt-24">
<div className="-m-2 rounded-xl bg-gray-900/5 p-2 ring-1 ring-inset ring-gray-900/10 lg:-m-4 lg:rounded-2xl lg:p-4">
Expand Down
17 changes: 17 additions & 0 deletions apps/web/app/(landing)/home/HeroHeadingAB.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

import { Skeleton } from "@/components/ui/skeleton";
import { useFeatureFlagVariantKey } from "posthog-js/react";

export function HeroHeadingAB() {
const variant = useFeatureFlagVariantKey("experiment-hero-heading");

if (variant === "control")
return <>Automate your emails with the power of AI</>;
// if (variant === "test") return <>Automate your email support with AI</>;
if (variant === "test")
return <>Open source tools to reach inbox zero fast</>;

// return <div className="h-28"></div>;
return <Skeleton className="h-28 w-full rounded" />;
}
17 changes: 17 additions & 0 deletions apps/web/app/(landing)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { Suspense } from "react";
import { PostHogPageview, PostHogProvider } from "@/providers/PostHogProvider";

export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<Suspense>
<PostHogPageview />
</Suspense>
<PostHogProvider>{children}</PostHogProvider>
</>
);
}
2 changes: 2 additions & 0 deletions apps/web/env.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ export const env = createEnv({
client: {
NEXT_PUBLIC_PRO_PAYMENT_LINK: z.string().min(1),
NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK: z.string().min(1),
NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
},
// For Next.js >= 13.4.4, you only need to destructure client variables:
experimental__runtimeEnv: {
NEXT_PUBLIC_PRO_PAYMENT_LINK: process.env.NEXT_PUBLIC_PRO_PAYMENT_LINK,
NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK:
process.env.NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK,
NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
},
});
4 changes: 3 additions & 1 deletion apps/web/legal/privacy.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Privacy Policy
updatedAt: 2023-08-15
updatedAt: 2023-09-14
---

## Introduction
Expand Down Expand Up @@ -32,6 +32,8 @@ We may share the information collected with the following parties:
**OpenAI:** We send email data to OpenAI for AI processing of each email. As per the [OpenAI data usage policies](https://openai.com/policies/api-data-usage-policies), OpenAI will not use data submitted by customers via their API to train or improve their models.
Any data sent through the API will be retained for abuse and misuse monitoring purposes for a maximum of 30 days, after which it will be deleted (unless otherwise required by law).

**PostHog:** The landing page and pages you see when not logged in use PostHog for analytic purposes. PostHog is not used for log in gated pages and no email data is sent to PostHog.

## Data Security

We implement appropriate security measures to protect your information. However, no method of transmission or storage is 100% secure, and we cannot guarantee absolute security.
Expand Down
8 changes: 8 additions & 0 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ const nextConfig = {
},
];
},
async rewrites() {
return [
{
source: "/ingest/:path*",
destination: "https://app.posthog.com/:path*",
},
];
},
};

export default withContentlayer(nextConfig);
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"node-email-reply-parser": "^0.1.4",
"nodemailer": "^6.9.4",
"openai-edge": "^1.2.2",
"posthog-js": "^1.78.4",
"prettier": "2.8.8",
"prettier-plugin-tailwindcss": "^0.4.1",
"react": "18.2.0",
Expand Down
39 changes: 39 additions & 0 deletions apps/web/providers/PostHogProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client";
import posthog from "posthog-js";
import { PostHogProvider as PHProvider } from "posthog-js/react";
import { usePathname, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { env } from "@/env.mjs";

// based on: https://posthog.com/docs/libraries/next-js

if (typeof window !== "undefined" && env.NEXT_PUBLIC_POSTHOG_KEY) {
posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY, {
// https://posthog.com/docs/advanced/proxy/nextjs
api_host: `${window.location.origin}/ingest`,
capture_pageview: false, // Disable automatic pageview capture, as we capture manually
});
}

export function PostHogPageview(): JSX.Element {
const pathname = usePathname();
const searchParams = useSearchParams();

useEffect(() => {
if (pathname) {
let url = window.origin + pathname;
if (searchParams && searchParams.toString()) {
url = url + `?${searchParams.toString()}`;
}
posthog.capture("$pageview", {
$current_url: url,
});
}
}, [pathname, searchParams]);

return <></>;
}

export function PostHogProvider({ children }: { children: React.ReactNode }) {
return <PHProvider client={posthog}>{children}</PHProvider>;
}
19 changes: 19 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"LEMON_SQUEEZY_API_SECRET",
"LEMON_SQUEEZY_SIGNING_SECRET",
"NEXT_PUBLIC_PRO_PAYMENT_LINK",
"NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK"
"NEXT_PUBLIC_ENTERPRISE_PAYMENT_LINK",
"NEXT_PUBLIC_POSTHOG_KEY"
],
"outputs": [".next/**", "!.next/cache/**"]
},
Expand Down