feat: new public website

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-12-02 09:17:49 +01:00
parent e2536774b0
commit ac4429d6d9
206 changed files with 18415 additions and 12433 deletions

View File

@@ -1,4 +1,4 @@
![hero](apps/public/public/ogimage.jpg) ![hero](apps/public/public/ogimage.png)
<p align="center"> <p align="center">
<h1 align="center"><b>Openpanel</b></h1> <h1 align="center"><b>Openpanel</b></h1>

View File

@@ -2,8 +2,6 @@
/node_modules /node_modules
# generated content # generated content
.contentlayer
.content-collections
.source .source
# test & build # test & build

View File

@@ -1,94 +0,0 @@
ARG NODE_VERSION=20.15.1
FROM --platform=linux/amd64 node:${NODE_VERSION}-slim AS base
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL
ARG REDIS_URL
ENV REDIS_URL=$REDIS_URL
ARG CLICKHOUSE_URL
ENV CLICKHOUSE_URL=$CLICKHOUSE_URL
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN apt update \
&& apt install -y curl \
&& curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n \
&& bash n $NODE_VERSION \
&& rm n \
&& npm install -g n
WORKDIR /app
COPY package.json package.json
COPY pnpm-lock.yaml pnpm-lock.yaml
COPY pnpm-workspace.yaml pnpm-workspace.yaml
COPY apps/public/package.json apps/public/package.json
COPY packages/db/package.json packages/db/package.json
COPY packages/redis/package.json packages/redis/package.json
COPY packages/queue/package.json packages/queue/package.json
COPY packages/common/package.json packages/common/package.json
COPY packages/constants/package.json packages/constants/package.json
COPY packages/validation/package.json packages/validation/package.json
COPY packages/sdks/sdk/package.json packages/sdks/sdk/package.json
COPY packages/sdks/_info/package.json packages/sdks/_info/package.json
# BUILD
FROM base AS build
WORKDIR /app/apps/public
RUN pnpm install --frozen-lockfile --ignore-scripts
WORKDIR /app
COPY apps/public apps/public
COPY packages packages
COPY tooling tooling
RUN pnpm db:codegen
WORKDIR /app/apps/public
RUN pnpm run build
# PROD
FROM base AS prod
WORKDIR /app/apps/public
RUN pnpm install --frozen-lockfile --prod --ignore-scripts
# FINAL
FROM base AS runner
COPY --from=build /app/package.json /app/package.json
COPY --from=prod /app/node_modules /app/node_modules
# Apps
COPY --from=build /app/apps/public /app/apps/public
# Apps node_modules
COPY --from=prod /app/apps/public/node_modules /app/apps/public/node_modules
# Packages
COPY --from=build /app/packages/db /app/packages/db
COPY --from=build /app/packages/redis /app/packages/redis
COPY --from=build /app/packages/common /app/packages/common
COPY --from=build /app/packages/queue /app/packages/queue
COPY --from=build /app/packages/constants /app/packages/constants
COPY --from=build /app/packages/validation /app/packages/validation
COPY --from=build /app/packages/sdks/sdk /app/packages/sdks/sdk
COPY --from=build /app/packages/sdks/_info /app/packages/sdks/_info
# Packages node_modules
COPY --from=prod /app/packages/db/node_modules /app/packages/db/node_modules
COPY --from=prod /app/packages/redis/node_modules /app/packages/redis/node_modules
COPY --from=prod /app/packages/common/node_modules /app/packages/common/node_modules
COPY --from=prod /app/packages/queue/node_modules /app/packages/queue/node_modules
COPY --from=prod /app/packages/validation/node_modules /app/packages/validation/node_modules
RUN pnpm db:codegen
WORKDIR /app/apps/public
EXPOSE 3000
CMD ["pnpm", "start"]

View File

@@ -15,6 +15,25 @@ yarn dev
Open http://localhost:3000 with your browser to see the result. Open http://localhost:3000 with your browser to see the result.
## Explore
In the project, you can see:
- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content.
- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep.
| Route | Description |
| ------------------------- | ------------------------------------------------------ |
| `app/(home)` | The route group for your landing page and other pages. |
| `app/docs` | The documentation layout and pages. |
| `app/api/search/route.ts` | The Route Handler for search. |
### Fumadocs MDX
A `source.config.ts` config file has been included, you can customise different options like frontmatter schema.
Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details.
## Learn More ## Learn More
To learn more about Next.js and Fumadocs, take a look at the following To learn more about Next.js and Fumadocs, take a look at the following
@@ -23,4 +42,4 @@ resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
features and API. features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs - [Fumadocs](https://fumadocs.dev) - learn about Fumadocs

View File

@@ -1,203 +0,0 @@
import { url, getAuthor } from '@/app/layout.config';
import { SingleSwirl } from '@/components/Swirls';
import { ArticleCard } from '@/components/article-card';
import { Logo } from '@/components/logo';
import { SectionHeader } from '@/components/section';
import { Toc } from '@/components/toc';
import { Button } from '@/components/ui/button';
import { articleSource } from '@/lib/source';
import { ArrowLeftIcon } from 'lucide-react';
import type { Metadata } from 'next';
import Image from 'next/image';
import Link from 'next/link';
import { notFound } from 'next/navigation';
import Script from 'next/script';
export async function generateMetadata({
params,
}: {
params: Promise<{ articleSlug: string }>;
}): Promise<Metadata> {
const { articleSlug } = await params;
const article = await articleSource.getPage([articleSlug]);
const author = getAuthor(article?.data.team);
if (!article) {
return {
title: 'Article Not Found',
};
}
return {
title: article.data.title,
description: article.data.description,
authors: [{ name: author.name }],
alternates: {
canonical: url(article.url),
},
openGraph: {
title: article.data.title,
description: article.data.description,
type: 'article',
publishedTime: article.data.date.toISOString(),
authors: author.name,
images: url(article.data.cover),
url: url(article.url),
},
twitter: {
card: 'summary_large_image',
title: article.data.title,
description: article.data.description,
images: url(article.data.cover),
},
};
}
export default async function Page({
params,
}: {
params: Promise<{ articleSlug: string }>;
}) {
const { articleSlug } = await params;
const article = await articleSource.getPage([articleSlug]);
const Body = article?.data.body;
const author = getAuthor(article?.data.team);
const goBackUrl = '/articles';
const relatedArticles = (await articleSource.getPages())
.filter(
(item) =>
item.data.tag === article?.data.tag && item.url !== article?.url,
)
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
if (!Body) {
return notFound();
}
// Create the JSON-LD data
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: article?.data.title,
datePublished: article?.data.date.toISOString(),
author: {
'@type': 'Person',
name: author.name,
},
publisher: {
'@type': 'Organization',
name: 'OpenPanel',
logo: {
'@type': 'ImageObject',
url: url('/logo.png'),
},
},
mainEntityOfPage: {
'@type': 'WebPage',
'@id': url(article.url),
},
image: {
'@type': 'ImageObject',
url: url(article.data.cover),
},
};
return (
<div>
<Script
strategy="beforeInteractive"
id="article-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article className="container max-w-5xl col">
<div className="py-16">
<Link
href={goBackUrl}
className="flex items-center gap-2 mb-4 text-muted-foreground"
>
<ArrowLeftIcon className="w-4 h-4" />
<span>Back to all articles</span>
</Link>
<div className="flex-col-reverse col md:row gap-8">
<div className="col flex-1">
<h1 className="text-5xl font-bold leading-tight">
{article?.data.title}
</h1>
<div className="row gap-4 items-center mt-8">
<div className="size-10 center-center bg-black rounded-full">
{author.image ? (
<Image
className="size-10 object-cover rounded-full"
src={author.image}
alt={author.name}
width={48}
height={48}
/>
) : (
<Logo className="w-6 h-6 fill-white" />
)}
</div>
<div className="col">
<p className="font-medium">{author.name}</p>
<p className="text-muted-foreground text-sm">
{article?.data.date.toLocaleDateString()}
</p>
</div>
</div>
</div>
</div>
</div>
<div className="relative">
<div className="grid grid-cols-1 md:grid-cols-[1fr_300px] gap-0">
<div className="min-w-0">
<div className="prose [&_table]:w-auto [&_img]:max-w-full [&_img]:h-auto">
<Body />
</div>
</div>
<aside className="pl-12 pb-12 gap-8 col">
<Toc toc={article?.data.toc} />
<section className="overflow-hidden relative bg-foreground dark:bg-background-dark text-background dark:text-foreground rounded-xl py-16">
<SingleSwirl className="pointer-events-none absolute top-0 bottom-0 left-0 size-[300px]" />
<SingleSwirl className="pointer-events-none rotate-180 absolute top-0 bottom-0 -right-0 opacity-50 size-[300px]" />
<div className="container center-center col">
<SectionHeader
className="mb-8"
title="Try it"
description="Give it a spin for free. No credit card required."
/>
<Button size="lg" variant="secondary" asChild>
<Link href="https://dashboard.openpanel.dev/onboarding">
Get started today!
</Link>
</Button>
</div>
</section>
</aside>
</div>
{relatedArticles.length > 0 && (
<div className="my-16">
<h3 className="text-2xl font-bold mb-8">Related articles</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{relatedArticles.map((item) => (
<ArticleCard
key={item.url}
url={item.url}
title={item.data.title}
tag={item.data.tag}
cover={item.data.cover}
team={item.data.team}
date={item.data.date}
/>
))}
</div>
</div>
)}
</div>
</article>
</div>
);
}

View File

@@ -1,55 +0,0 @@
import { url } from '@/app/layout.config';
import { ArticleCard } from '@/components/article-card';
import { articleSource } from '@/lib/source';
import type { Metadata } from 'next';
import Image from 'next/image';
import Link from 'next/link';
const title = 'Articles';
const description = 'Read our latest articles';
export const metadata: Metadata = {
title,
description,
alternates: {
canonical: url('/articles'),
},
openGraph: {
title,
description,
type: 'website',
},
twitter: {
card: 'summary_large_image',
title,
description,
},
};
export default async function Page() {
const articles = (await articleSource.getPages()).sort(
(a, b) => b.data.date.getTime() - a.data.date.getTime(),
);
return (
<div>
<div className="container col">
<div className="py-16">
<h1 className="text-center text-7xl font-bold">Articles</h1>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
{articles.map((item) => (
<ArticleCard
key={item.url}
url={item.url}
title={item.data.title}
tag={item.data.tag}
cover={item.data.cover}
team={item.data.team}
date={item.data.date}
/>
))}
</div>
</div>
</div>
);
}

View File

@@ -1,24 +0,0 @@
import { Footer } from '@/components/footer';
import { HeroContainer } from '@/components/hero';
import Navbar from '@/components/navbar';
import type { ReactNode } from 'react';
export default function Layout({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return (
<>
<Navbar />
<main className="overflow-hidden">
<HeroContainer className="h-screen pointer-events-none" />
<div className="absolute h-screen inset-0 radial-gradient-dot-pages select-none pointer-events-none" />
<div className="-mt-[calc(100vh-100px)] relative min-h-[500px] pb-12 -mb-24">
{children}
</div>
</main>
<Footer />
</>
);
}

View File

@@ -1,288 +0,0 @@
import { url } from '@/app/layout.config';
import { HeroContainer } from '@/components/hero';
import { Section, SectionHeader } from '@/components/section';
import { Faq } from '@/components/sections/faq';
import { SupporterPerks } from '@/components/sections/supporter-perks';
import { Testimonials } from '@/components/sections/testimonials';
import { Tag } from '@/components/tag';
import { Button } from '@/components/ui/button';
import {
ArrowDownIcon,
HeartHandshakeIcon,
SparklesIcon,
ZapIcon,
} from 'lucide-react';
import type { Metadata } from 'next';
import Link from 'next/link';
import Script from 'next/script';
export const metadata: Metadata = {
title: 'Become a Supporter',
description:
'Support OpenPanel and get exclusive perks like latest Docker images, prioritized support, and early access to new features.',
alternates: {
canonical: url('/supporter'),
},
openGraph: {
title: 'Become a Supporter',
description:
'Support OpenPanel and get exclusive perks like latest Docker images, prioritized support, and early access to new features.',
type: 'website',
url: url('/supporter'),
},
twitter: {
card: 'summary_large_image',
title: 'Become a Supporter',
description:
'Support OpenPanel and get exclusive perks like latest Docker images, prioritized support, and early access to new features.',
},
};
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: 'Become a Supporter',
publisher: {
'@type': 'Organization',
name: 'OpenPanel',
logo: {
'@type': 'ImageObject',
url: url('/logo.png'),
},
},
mainEntityOfPage: {
'@type': 'WebPage',
'@id': url('/supporter'),
},
};
export default function SupporterPage() {
return (
<div>
<Script
id="supporter-schema"
strategy="beforeInteractive"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<HeroContainer>
<div className="container relative z-10 col sm:py-44 max-sm:pt-32">
<div className="col gap-8 text-center">
<div className="col gap-4">
<Tag className="self-center">
<HeartHandshakeIcon className="size-4 text-rose-600" />
Support Open-Source Analytics
</Tag>
<h1 className="text-4xl md:text-5xl font-extrabold leading-[1.1]">
Help us build the future of{' '}
<span className="text-primary">open analytics</span>
</h1>
<p className="text-xl text-muted-foreground max-w-2xl mx-auto">
Your support accelerates development, funds infrastructure, and
helps us build features faster. Plus, you get exclusive perks
and early access to everything we ship.
</p>
</div>
<div className="col gap-4 justify-center items-center">
<Button size="lg" asChild>
<Link href="https://buy.polar.sh/polar_cl_Az1CruNFzQB2bYdMOZmGHqTevW317knWqV44W1FqZmV">
Become a Supporter
<SparklesIcon className="size-4" />
</Link>
</Button>
<p className="text-sm text-muted-foreground">
Starting at $20/month Cancel anytime
</p>
</div>
</div>
</div>
</HeroContainer>
<div className="container max-w-7xl">
{/* Main Content with Sidebar */}
<div className="grid lg:grid-cols-[1fr_380px] gap-8 mb-16">
{/* Main Content */}
<div className="col gap-12">
{/* Why Support Section */}
<section className="col gap-6">
<h2 className="text-3xl font-bold">Why your support matters</h2>
<div className="col gap-6 text-muted-foreground">
<p className="text-lg">
We're not a big corporation just a small team passionate
about building something useful for developers. OpenPanel
started because we believed analytics tools shouldn't be
complicated or locked behind expensive enterprise
subscriptions.
</p>
<p>When you become a supporter, you're directly funding:</p>
<ul className="col gap-3 list-none pl-0">
<li className="flex items-start gap-3">
<ZapIcon className="size-5 text-primary mt-0.5 shrink-0" />
<div>
<strong className="text-foreground">
Active Development
</strong>
<p className="text-sm mt-1">
More time fixing bugs, adding features, and improving
documentation
</p>
</div>
</li>
<li className="flex items-start gap-3">
<ZapIcon className="size-5 text-primary mt-0.5 shrink-0" />
<div>
<strong className="text-foreground">
Infrastructure
</strong>
<p className="text-sm mt-1">
Keeping servers running, CI/CD pipelines, and
development tools
</p>
</div>
</li>
<li className="flex items-start gap-3">
<ZapIcon className="size-5 text-primary mt-0.5 shrink-0" />
<div>
<strong className="text-foreground">Independence</strong>
<p className="text-sm mt-1">
Staying focused on what matters: building a tool
developers actually want
</p>
</div>
</li>
</ul>
<p>
No corporate speak, no fancy promises just honest work on
making OpenPanel better for everyone. Every contribution, no
matter the size, helps us stay independent and focused on what
matters.
</p>
</div>
</section>
{/* What You Get Section */}
<section className="col gap-6">
<h2 className="text-3xl font-bold">
What you get as a supporter
</h2>
<div className="grid md:grid-cols-2 gap-4">
<div className="p-6 rounded-lg border bg-card">
<h3 className="font-semibold text-lg mb-2">
🚀 Latest Docker Images
</h3>
<p className="text-sm text-muted-foreground mb-3">
Get bleeding-edge builds on every commit. Access new
features weeks before public release.
</p>
<Link
href="/docs/self-hosting/supporter-access-latest-docker-images"
className="text-sm text-primary hover:underline"
>
Learn more →
</Link>
</div>
<div className="p-6 rounded-lg border bg-card">
<h3 className="font-semibold text-lg mb-2">
💬 Prioritized Support
</h3>
<p className="text-sm text-muted-foreground mb-3">
Get help faster with priority support in our Discord
community. Your questions get answered first.
</p>
</div>
<div className="p-6 rounded-lg border bg-card">
<h3 className="font-semibold text-lg mb-2">
✨ Feature Requests
</h3>
<p className="text-sm text-muted-foreground mb-3">
Your ideas and feature requests get prioritized in our
roadmap. Shape the future of OpenPanel.
</p>
</div>
<div className="p-6 rounded-lg border bg-card">
<h3 className="font-semibold text-lg mb-2">
⭐ Exclusive Discord Role
</h3>
<p className="text-sm text-muted-foreground mb-3">
Special badge and recognition in our community. Show your
support with pride.
</p>
</div>
</div>
</section>
{/* Impact Section */}
<section className="p-8 rounded-xl border bg-gradient-to-br from-primary/5 to-primary/10">
<h2 className="text-2xl font-bold mb-4">Your impact</h2>
<p className="text-muted-foreground mb-6">
Every dollar you contribute goes directly into development,
infrastructure, and making OpenPanel better. Here's what your
support enables:
</p>
<div className="grid md:grid-cols-3 gap-4">
<div className="text-center">
<div className="text-3xl font-bold text-primary mb-2">
100%
</div>
<div className="text-sm text-muted-foreground">
Open Source
</div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-primary mb-2">
24/7
</div>
<div className="text-sm text-muted-foreground">
Active Development
</div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-primary mb-2"></div>
<div className="text-sm text-muted-foreground">
Self-Hostable
</div>
</div>
</div>
</section>
</div>
{/* Sidebar */}
<aside className="lg:block hidden">
<SupporterPerks />
</aside>
</div>
{/* Mobile Perks */}
<div className="lg:hidden mb-16">
<SupporterPerks />
</div>
{/* CTA Section */}
<Section className="container my-0 py-20">
<SectionHeader
tag={
<Tag>
<ArrowDownIcon className="size-4" strokeWidth={1.5} />
Starting at $20/month
</Tag>
}
title="Ready to support OpenPanel?"
description="Join our community of supporters and help us build the best open-source alternative to Mixpanel. Every contribution helps accelerate development and make OpenPanel better for everyone."
/>
<div className="center-center">
<Button size="lg" asChild>
<Link href="https://buy.polar.sh/polar_cl_Az1CruNFzQB2bYdMOZmGHqTevW317knWqV44W1FqZmV">
Become a Supporter Now
<HeartHandshakeIcon className="size-4" />
</Link>
</Button>
</div>
</Section>
</div>
<div className="lg:-mx-20 xl:-mx-40 not-prose mt-16">
<Testimonials />
<Faq />
</div>
</div>
);
}

View File

@@ -1,4 +0,0 @@
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
export const { GET } = createFromSource(source);

View File

@@ -1,67 +0,0 @@
import { url, siteName } from '@/app/layout.config';
import { source } from '@/lib/source';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
export default async function Page(props: {
params: Promise<{ slug?: string[] }>;
}) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) notFound();
const MDX = page.data.body;
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={{ ...defaultMdxComponents }} />
</DocsBody>
</DocsPage>
);
}
export async function generateStaticParams() {
return source.generateParams();
}
export async function generateMetadata(props: {
params: Promise<{ slug?: string[] }>;
}) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) notFound();
return {
title: page.data.title,
description: page.data.description,
alternates: {
canonical: url(page.url),
},
icons: {
apple: '/apple-touch-icon.png',
icon: '/favicon.ico',
},
manifest: '/site.webmanifest',
openGraph: {
url: url(page.url),
type: 'article',
images: [
{
url: url('/ogimage.jpg'),
width: 1200,
height: 630,
alt: siteName,
},
],
},
};
}

View File

@@ -1,12 +0,0 @@
import { baseOptions } from '@/app/layout.config';
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
{children}
</DocsLayout>
);
}

View File

@@ -1,224 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--green: 156 71% 67%;
--red: 351 89% 72%;
--background: 0 0% 98%;
--background-light: 0 0% 100%;
--background-dark: 0 0% 96%;
--foreground: 0 0% 9%;
--foreground-dark: 0 0% 7.5%;
--foreground-light: 0 0% 11%;
--card: 0 0% 98%;
--card-foreground: 0 0% 9%;
--popover: 0 0% 98%;
--popover-foreground: 0 0% 9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 9%;
--background-dark: 0 0% 7.5%;
--background-light: 0 0% 11%;
--foreground: 0 0% 98%;
--foreground-light: 0 0% 100%;
--foreground-dark: 0 0% 96%;
--card: 0 0% 9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply !bg-[hsl(var(--background))] text-foreground font-sans text-base antialiased flex flex-col min-h-screen;
}
}
@layer components {
.container {
@apply max-w-6xl mx-auto px-6 md:px-10 lg:px-14 w-full;
}
.pulled {
@apply -mx-2 md:-mx-6 lg:-mx-10 xl:-mx-20;
}
.row {
@apply flex flex-row;
}
.col {
@apply flex flex-col;
}
.center-center {
@apply flex items-center justify-center text-center;
}
}
strong {
@apply font-semibold;
}
.radial-gradient {
background: #BECCDF;
background: radial-gradient(at bottom, hsl(var(--background-light)), hsl(var(--background)));
}
.radial-gradient-dot-1 {
background: #BECCDF;
background: radial-gradient(at 50% 20%, hsl(var(--background-light)), transparent);
}
.radial-gradient-dot-pages {
background: #BECCDF;
background: radial-gradient(at 50% 50%, hsl(var(--background)), hsl(var(--background)/0.2));
}
.animated-iframe-gradient {
position: relative;
overflow: hidden;
background: transparent;
}
.animated-iframe-gradient:before {
content: '';
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 1600px;
height: 1600px;
background: linear-gradient(250deg, hsl(var(--foreground)/0.9), transparent);
animation: GradientRotate 8s linear infinite;
}
@keyframes GradientRotate {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
.line-before {
position: relative;
padding: 16px;
}
.line-before:before {
content: '';
display: block;
position: absolute;
top: calc(4px*-32);
bottom: calc(4px*-32);
left: 0;
width: 1px;
background: hsl(var(--foreground)/0.1);
}
.line-after {
position: relative;
padding: 16px;
}
.line-after:after {
content: '';
display: block;
position: absolute;
top: calc(4px*-32);
bottom: calc(4px*-32);
right: 0;
width: 1px;
background: hsl(var(--foreground)/0.1);
}
.animate-fade-up {
animation: animateFadeUp 0.5s ease-in-out;
animation-fill-mode: both;
}
@keyframes animateFadeUp {
0% { transform: translateY(0.5rem); scale: 0.95; }
100% { transform: translateY(0); scale: 1; }
}
.animate-fade-down {
animation: animateFadeDown 0.5s ease-in-out;
animation-fill-mode: both;
}
@keyframes animateFadeDown {
0% { transform: translateY(-1rem); }
100% { transform: translateY(0); }
}
/* Docs */
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
font-size: inherit !important;
}
.prose pre {
background: hsl(var(--background-dark));
border: 1px solid hsl(var(--background-light));
padding: 10px 15px;
border-radius: 10px;
font-size: 12px;
}
.prose pre code {
background: transparent;
padding: 0;
border-radius: 0;
font-size: inherit;
border: none;
}
div[data-radix-scroll-area-viewport] > div[data-radix-scroll-area-content] {
max-height: 400px;
}
div[data-radix-scroll-area-viewport] > div[data-radix-scroll-area-content] pre{
max-height: none;
}

View File

@@ -1,66 +0,0 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
/**
* Shared layout configurations
*
* you can configure layouts individually from:
* Home Layout: app/(home)/layout.tsx
* Docs Layout: app/docs/layout.tsx
*/
export const siteName = 'OpenPanel';
export const baseUrl = 'https://openpanel.dev';
export const url = (path: string) => `${baseUrl}${path}`;
export const baseOptions: BaseLayoutProps = {
nav: {
title: siteName,
},
links: [
{
type: 'main',
text: 'Home',
url: '/',
active: 'nested-url',
},
{
type: 'main',
text: 'Pricing',
url: '/pricing',
active: 'nested-url',
},
{
type: 'main',
text: 'Supporter',
url: '/supporter',
active: 'nested-url',
},
{
type: 'main',
text: 'Documentation',
url: '/docs',
active: 'nested-url',
},
{
type: 'main',
text: 'Articles',
url: '/articles',
active: 'nested-url',
},
],
} as const;
export const authors = [
{
name: 'OpenPanel Team',
url: 'https://openpanel.com',
},
{
name: 'Carl-Gerhard Lindesvärd',
url: 'https://openpanel.com',
image: '/twitter-carl.jpg',
},
];
export const getAuthor = (author?: string) => {
return authors.find((a) => a.name === author)!;
};

View File

@@ -1,75 +0,0 @@
import { RootProvider } from 'fumadocs-ui/provider';
import type { ReactNode } from 'react';
import './global.css';
import { TooltipProvider } from '@/components/ui/tooltip';
import { OpenPanelComponent } from '@openpanel/nextjs';
import { cn } from 'fumadocs-ui/components/api';
import { GeistMono } from 'geist/font/mono';
import { GeistSans } from 'geist/font/sans';
import type { Metadata, Viewport } from 'next';
import Script from 'next/script';
import { url, baseUrl, siteName } from './layout.config';
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
userScalable: true,
themeColor: [
{ media: '(prefers-color-scheme: light)', color: '#fafafa' },
{ media: '(prefers-color-scheme: dark)', color: '#171717' },
],
};
const description = `${siteName} is a simple, affordable open-source alternative to Mixpanel for web and product analytics. Get powerful insights without the complexity.`;
export const metadata: Metadata = {
title: {
default: siteName,
template: `%s | ${siteName}`,
},
description,
alternates: {
canonical: baseUrl,
},
icons: {
apple: '/apple-touch-icon.png',
icon: '/favicon.ico',
},
manifest: '/site.webmanifest',
openGraph: {
title: siteName,
description,
siteName: siteName,
url: baseUrl,
type: 'website',
images: [
{
url: url('/ogimage.jpg'),
width: 1200,
height: 630,
alt: siteName,
},
],
},
};
export default async function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body className={cn(GeistSans.variable, GeistMono.variable)}>
<RootProvider>
<TooltipProvider>{children}</TooltipProvider>
</RootProvider>
<OpenPanelComponent
apiUrl="/api/op"
cdnUrl="/api/op/op1.js"
clientId="301c6dc1-424c-4bc3-9886-a8beab09b615"
trackAttributes
trackScreenViews
trackOutgoingLinks
/>
</body>
</html>
);
}

View File

@@ -1,22 +0,0 @@
import type { MetadataRoute } from 'next';
import { metadata } from './layout';
export default function manifest(): MetadataRoute.Manifest {
return {
name: metadata.title as string,
short_name: 'Openpanel.dev',
description: metadata.description!,
start_url: '/',
display: 'standalone',
background_color: '#fff',
theme_color: '#fff',
icons: [
{
src: '/favicon.ico',
sizes: 'any',
type: 'image/x-icon',
},
],
};
}

View File

@@ -1,30 +0,0 @@
import { baseOptions } from '@/app/layout.config';
import { Footer } from '@/components/footer';
import { HeroContainer } from '@/components/hero';
import Navbar from '@/components/navbar';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import type { ReactNode } from 'react';
export default function NotFound({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return (
<div>
<Navbar />
<HeroContainer className="h-screen center-center">
<div className="relative z-10 col gap-2">
<div className="text-[150px] font-mono font-bold opacity-5 -mb-4">
404
</div>
<h1 className="text-6xl font-bold">Not Found</h1>
<p className="text-xl text-muted-foreground">
Awkward, we couldn&apos;t find what you were looking for.
</p>
</div>
</HeroContainer>
<Footer />
</div>
);
}

View File

@@ -1,36 +0,0 @@
import { Footer } from '@/components/footer';
import { Hero } from '@/components/hero';
import Navbar from '@/components/navbar';
import { Faq } from '@/components/sections/faq';
import { Features } from '@/components/sections/features';
import { Pricing } from '@/components/sections/pricing';
import { Sdks } from '@/components/sections/sdks';
import { Stats, StatsPure } from '@/components/sections/stats';
import { Testimonials } from '@/components/sections/testimonials';
import { WhyOpenPanel } from '@/components/why-openpanel';
import type { Metadata } from 'next';
import { Suspense } from 'react';
export const metadata: Metadata = {
title: 'OpenPanel | An open-source alternative to Mixpanel',
};
// export const experimental_ppr = true;
export default function HomePage() {
return (
<>
<Navbar />
<main>
<Hero />
<WhyOpenPanel />
<Features />
<Testimonials />
<Faq />
<Pricing />
<Sdks />
</main>
<Footer />
</>
);
}

View File

@@ -1,23 +0,0 @@
'use client';
import { Button } from '@/components/ui/button';
import { useOpenPanel } from '@openpanel/nextjs';
export default function TestPage() {
const op = useOpenPanel();
return (
<div>
<h1>Test Page</h1>
<Button
onClick={async () => {
const deviceId = await op.fetchDeviceId();
alert(`Device ID: ${deviceId}`);
}}
>
Fetch device id
</Button>
<Button onClick={() => op.track('hello')}>Hello</Button>
<Button onClick={() => op.revenue(100)}>Revenue</Button>
</div>
);
}

View File

@@ -1,20 +0,0 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}

View File

@@ -1,36 +0,0 @@
import { cn } from '@/lib/utils';
import Image, { type ImageProps } from 'next/image';
type SwirlProps = Omit<ImageProps, 'src' | 'alt'>;
export function SingleSwirl({ className, ...props }: SwirlProps) {
return (
<Image
{...props}
src="/swirl-2.png"
alt="Swirl"
className={cn(
'pointer-events-none w-full h-full object-cover',
className,
)}
width={1200}
height={1200}
/>
);
}
export function DoubleSwirl({ className, ...props }: SwirlProps) {
return (
<Image
{...props}
src="/swirl.png"
alt="Swirl"
className={cn(
'pointer-events-none w-full h-full object-cover',
className,
)}
width={1200}
height={1200}
/>
);
}

View File

@@ -1,160 +0,0 @@
import { cn } from '@/lib/utils';
import { ChevronRightIcon, ConeIcon } from 'lucide-react';
import Link from 'next/link';
export function SmallFeature({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<div
className={cn(
'bg-background-light rounded-lg p-1 border border-border group',
className,
)}
>
<div className="bg-background-dark rounded-lg p-8 h-full group-hover:bg-background-light transition-colors">
{children}
</div>
</div>
);
}
export function Feature({
children,
media,
reverse = false,
className,
}: {
children: React.ReactNode;
media?: React.ReactNode;
reverse?: boolean;
className?: string;
}) {
return (
<div
className={cn(
'border rounded-lg bg-background-light overflow-hidden p-1',
className,
)}
>
<div
className={cn(
'grid grid-cols-1 md:grid-cols-2 gap-4 items-center',
!media && '!grid-cols-1',
)}
>
<div className={cn(reverse && 'md:order-last', 'p-10')}>{children}</div>
{media && (
<div
className={cn(
'bg-background-dark h-full rounded-md overflow-hidden',
reverse && 'md:order-first',
)}
>
{media}
</div>
)}
</div>
</div>
);
}
export function FeatureContent({
icon,
title,
content,
className,
}: {
icon?: React.ReactNode;
title: string;
content: React.ReactNode[];
className?: string;
}) {
return (
<div className={className}>
{icon && (
<div
data-icon
className="bg-foreground text-background rounded-md p-4 inline-block mb-6 transition-colors"
>
{icon}
</div>
)}
<h2 className="text-lg font-medium mb-2">{title}</h2>
<div className="col gap-2">
{content.map((c, i) => (
<p className="text-muted-foreground" key={i.toString()}>
{c}
</p>
))}
</div>
</div>
);
}
export function FeatureListItem({
icon: Icon,
title,
}: { icon: React.ComponentType<any>; title: string }) {
return (
<div className="row items-center gap-2" key="funnel">
<Icon className="size-4 text-foreground/70" strokeWidth={1.5} /> {title}
</div>
);
}
export function FeatureList({
title,
items,
className,
cols = 2,
}: {
title: string;
items: React.ReactNode[];
className?: string;
cols?: number;
}) {
return (
<div className={className}>
<h3 className="font-semibold text-sm mb-2">{title}</h3>
<div
className={cn(
'-mx-2 [&>div]:p-2 [&>div]:row [&>div]:items-center [&>div]:gap-2 grid',
cols === 1 && 'grid-cols-1',
cols === 2 && 'grid-cols-2',
cols === 3 && 'grid-cols-3',
)}
>
{items.map((i, j) => (
<div key={j.toString()}>{i}</div>
))}
</div>
</div>
);
}
export function FeatureMore({
children,
href,
className,
}: {
children: React.ReactNode;
href: string;
className?: string;
}) {
return (
<Link
href={href}
className={cn(
'font-medium items-center row justify-between border-t py-4',
className,
)}
>
{children} <ChevronRightIcon className="size-4" strokeWidth={1.5} />
</Link>
);
}

View File

@@ -1,158 +0,0 @@
import { baseOptions } from '@/app/layout.config';
import { MailIcon } from 'lucide-react';
import Link from 'next/link';
import { SingleSwirl } from './Swirls';
import { Logo } from './logo';
import { SectionHeader } from './section';
import { Tag } from './tag';
import { Button } from './ui/button';
export function Footer() {
const year = new Date().getFullYear();
return (
<div className="mt-32">
<section className="overflow-hidden relative bg-foreground dark:bg-background-dark text-background dark:text-foreground rounded-xl p-0 pb-32 pt-16 max-w-7xl mx-auto">
<SingleSwirl className="pointer-events-none absolute top-0 bottom-0 left-0" />
<SingleSwirl className="pointer-events-none rotate-180 absolute top-0 bottom-0 -right-0 opacity-50" />
<div className="container center-center col">
<SectionHeader
tag={<Tag>Discover User Insights</Tag>}
title="Effortless web & product analytics"
description="Simplify your web & product analytics with our user-friendly platform. Collect, analyze, and optimize your data in minutes."
/>
<Button size="lg" variant="secondary" asChild>
<Link href="https://dashboard.openpanel.dev/onboarding">
Get started today!
</Link>
</Button>
</div>
</section>
<footer className="pt-32 text-sm relative overflow-hidden">
<div className="absolute -bottom-20 md:-bottom-32 left-0 right-0 center-center opacity-5 pointer-events-none">
<Logo className="w-[900px] shrink-0" />
</div>
<div className="container grid grid-cols-1 md:grid-cols-5 gap-12 md:gap-8 relative">
<div>
<Link href="/" className="row items-center font-medium">
<Logo className="h-6" />
{baseOptions.nav?.title}
</Link>
</div>
<div className="col gap-3">
<h3 className="font-medium">Useful links</h3>
<ul className="gap-2 col text-muted-foreground">
<li>
<Link href="/pricing">Pricing</Link>
</li>
<li>
<Link href="/about">About</Link>
</li>
<li>
<Link href="/contact">Contact</Link>
</li>
<li>
<Link href="/supporter">Become a supporter</Link>
</li>
</ul>
</div>
<div className="col gap-3 ">
<h3 className="font-medium">Articles</h3>
<ul className="gap-2 col text-muted-foreground">
<li>
<Link href="/articles/vs-mixpanel">OpenPanel vs Mixpanel</Link>
</li>
<li>
<Link href="/articles/mixpanel-alternatives">
Mixpanel alternatives
</Link>
</li>
</ul>
</div>
<div className="md:col-span-2 md:items-end col gap-4">
<div className="[&_svg]:size-6 row gap-4">
<Link
title="Go to GitHub"
href="https://github.com/Openpanel-dev/openpanel"
rel="noreferrer noopener nofollow"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="fill-current"
>
<title>GitHub</title>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
</Link>
<Link
title="Go to X"
href="https://x.com/openpaneldev"
rel="noreferrer noopener nofollow"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="fill-current"
>
<title>X</title>
<path d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H3.298Z" />
</svg>
</Link>
<Link
title="Join Discord"
href="https://go.openpanel.dev/discord"
rel="noreferrer noopener nofollow"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="fill-current"
>
<title>Discord</title>
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z" />
</svg>
</Link>
<Link
title="Send an email"
href="mailto:hello@openpanel.dev"
rel="noreferrer noopener nofollow"
>
<MailIcon className="size-6" />
</Link>
</div>
<a
target="_blank"
href="https://status.openpanel.dev"
className="row gap-2 items-center border rounded-full px-2 py-1 max-md:self-start"
rel="noreferrer noopener nofollow"
>
<span>Operational</span>
<div className="size-2 bg-emerald-500 rounded-full" />
</a>
</div>
</div>
<div className="text-muted-foreground border-t pt-4 mt-16 gap-8 relative bg-background/70 pb-32">
<div className="container col md:row justify-between">
<div>Copyright © {year} OpenPanel. All rights reserved.</div>
<div className="col lg:row gap-2 md:gap-4">
<Link href="/sitemap.xml">Sitemap</Link>
<Link href="/privacy">Privacy Policy</Link>
<Link href="/terms">Terms of Service</Link>
<Link href="/cookies">Cookie Policy (just kidding)</Link>
</div>
</div>
</div>
</footer>
</div>
);
}

View File

@@ -1,145 +0,0 @@
import { cn } from '@/lib/utils';
import { motion } from 'framer-motion';
import NextImage from 'next/image';
import { useState } from 'react';
import { Button } from './ui/button';
type Frame = {
id: string;
label: string;
key: string;
Component: React.ComponentType;
};
function LivePreview() {
return (
<iframe
src={
'https://dashboard.openpanel.dev/share/overview/zef2XC?header=0&range=30d'
}
className="w-full h-full"
title="Live preview"
scrolling="no"
/>
);
}
function Image({ src }: { src: string }) {
return (
<div>
<NextImage
className="w-full h-full block dark:hidden"
src={`/${src}-light.png`}
alt={`${src} light`}
width={1200}
height={800}
/>
<NextImage
className="w-full h-full hidden dark:block"
src={`/${src}-dark.png`}
alt={`${src} dark`}
width={1200}
height={800}
/>
</div>
);
}
export function HeroCarousel() {
const frames: Frame[] = [
{
id: 'overview',
key: 'overview',
label: 'Live preview',
Component: LivePreview,
},
{
id: 'analytics',
key: 'analytics',
label: 'Product analytics',
Component: () => <Image src="dashboard" />,
},
{
id: 'funnels',
key: 'funnels',
label: 'Funnels',
Component: () => <Image src="funnel" />,
},
{
id: 'retention',
key: 'retention',
label: 'Retention',
Component: () => <Image src="retention" />,
},
{
id: 'profile',
key: 'profile',
label: 'Inspect profile',
Component: () => <Image src="profile" />,
},
];
const [activeFrames, setActiveFrames] = useState<Frame[]>([frames[0]]);
const activeFrame = activeFrames[activeFrames.length - 1];
return (
<div className="col gap-6 w-full">
<div className="flex-wrap row gap-x-4 gap-y-2 justify-center [&>div]:font-medium mt-1">
{frames.map((frame) => (
<div key={frame.id} className="relative">
<Button
variant="naked"
type="button"
onClick={() => {
if (activeFrame.id === frame.id) {
return;
}
const newFrame = {
...frame,
key: Math.random().toString().slice(2, 11),
};
setActiveFrames((p) => [...p.slice(-2), newFrame]);
}}
className="relative"
>
{frame.label}
</Button>
<motion.div
className="h-1 bg-foreground rounded-full"
initial={false}
animate={{
width: activeFrame.id === frame.id ? '100%' : '0%',
opacity: activeFrame.id === frame.id ? 1 : 0,
}}
whileHover={{
width: '100%',
opacity: 0.5,
}}
transition={{ duration: 0.2, ease: 'easeInOut' }}
/>
</div>
))}
</div>
<div className="pulled animated-iframe-gradient p-px pb-0 rounded-t-xl">
<div className="overflow-hidden rounded-xl rounded-b-none w-full bg-background">
<div
className={cn(
'relative w-full h-[750px]',
activeFrame.id !== 'overview' && 'h-auto aspect-[5/3]',
)}
>
{activeFrames.slice(-1).map((frame) => (
<div key={frame.key} className="absolute inset-0 w-full h-full">
<div className="bg-background rounded-xl h-full w-full">
<frame.Component />
</div>
</div>
))}
</div>
</div>
</div>
</div>
);
}

View File

@@ -1,20 +0,0 @@
import { motion, useScroll, useTransform } from 'framer-motion';
import { WorldMap } from './world-map';
export function HeroMap() {
const { scrollY } = useScroll();
const y = useTransform(scrollY, [0, 250], [0, 50], { clamp: true });
const scale = useTransform(scrollY, [0, 250], [1, 1.1], { clamp: true });
return (
<motion.div
style={{ y, scale }}
className="absolute inset-0 top-20 center-center items-start select-none"
>
<div className="min-w-[1400px] w-full">
<WorldMap />
</div>
</motion.div>
);
}

View File

@@ -1,138 +0,0 @@
import { cn } from '@/lib/utils';
import {
ArrowRightIcon,
CalendarIcon,
ChevronRightIcon,
CookieIcon,
CreditCardIcon,
DatabaseIcon,
FlaskRoundIcon,
GithubIcon,
ServerIcon,
StarIcon,
} from 'lucide-react';
import Link from 'next/link';
import { Competition } from './competition';
import { Tag } from './tag';
import { Button } from './ui/button';
const perks = [
{ text: 'Free trial 30 days', icon: CalendarIcon },
{ text: 'No credit card required', icon: CreditCardIcon },
{ text: 'Cookie-less tracking', icon: CookieIcon },
{ text: 'Open-source', icon: GithubIcon },
{ text: 'Your data, your rules', icon: DatabaseIcon },
{ text: 'Self-hostable', icon: ServerIcon },
];
export function Hero() {
return (
<HeroContainer>
<div className="container relative z-10 col sm:row sm:py-44 max-sm:pt-32">
<div className="col gap-8 w-full sm:w-1/2 sm:pr-12">
<div className="col gap-4">
<Tag className="self-start">
<StarIcon className="size-4 fill-yellow-500 text-yellow-500" />
Trusted by +2000 projects
</Tag>
<h1
className="text-4xl md:text-5xl font-extrabold leading-[1.1]"
title="An open-source alternative to Mixpanel"
>
An open-source alternative to <Competition />
</h1>
<p className="text-xl text-muted-foreground">
An open-source web and product analytics platform that combines
the power of Mixpanel with the ease of Plausible and one of the
best Google Analytics replacements.
</p>
</div>
<Button size="lg" asChild className="group w-72">
<Link href="https://dashboard.openpanel.dev/onboarding">
Get started now
<ChevronRightIcon className="size-4 group-hover:translate-x-1 transition-transform group-hover:scale-125" />
</Link>
</Button>
<ul className="grid grid-cols-2 gap-2">
{perks.map((perk) => (
<li key={perk.text} className="text-sm text-muted-foreground">
<perk.icon className="size-4 inline-block mr-1" />
{perk.text}
</li>
))}
</ul>
</div>
<div className="col sm:w-1/2 relative group">
<div
className={cn([
'overflow-hidden rounded-lg border border-border bg-background shadow-lg',
'sm:absolute sm:left-0 sm:-top-12 sm:w-[800px] sm:-bottom-32',
'max-sm:h-[800px] max-sm:-mx-4 max-sm:mt-12 relative',
])}
>
{/* Window controls */}
<div className="flex items-center gap-2 px-4 py-2 border-b border-border bg-muted/50 h-12">
<div className="flex gap-1.5">
<div className="w-3 h-3 rounded-full bg-red-500" />
<div className="w-3 h-3 rounded-full bg-yellow-500" />
<div className="w-3 h-3 rounded-full bg-green-500" />
</div>
{/* URL bar */}
<a
target="_blank"
rel="noreferrer noopener nofollow"
href="https://demo.openpanel.dev/demo/shoey"
className="group flex-1 mx-4 px-3 py-1 text-sm bg-background rounded-md border border-border flex items-center gap-2"
>
<span className="text-muted-foreground flex-1">
https://demo.openpanel.dev
</span>
<ArrowRightIcon className="size-4 opacity-0 group-hover:opacity-100 transition-opacity" />
</a>
</div>
<iframe
src={'https://demo.openpanel.dev/demo/shoey?range=lastHour'}
className="w-full h-full"
title="Live preview"
scrolling="no"
/>
<div className="pointer-events-none absolute inset-0 top-12 center-center group-hover:bg-foreground/20 transition-colors">
<Button
asChild
className="group-hover:opacity-100 opacity-0 transition-opacity pointer-events-auto"
>
<Link
href="https://demo.openpanel.dev/demo/shoey"
rel="noreferrer noopener nofollow"
target="_blank"
>
Test live demo
<FlaskRoundIcon className="size-4" />
</Link>
</Button>
</div>
</div>
</div>
</div>
</HeroContainer>
);
}
export function HeroContainer({
children,
className,
}: {
children?: React.ReactNode;
className?: string;
}): React.ReactElement {
return (
<section className={cn('radial-gradient overflow-hidden relative')}>
<div className={cn('relative z-10', className)}>{children}</div>
{/* Shadow bottom */}
<div className="w-full absolute bottom-0 h-32 bg-gradient-to-t from-background to-transparent" />
</section>
);
}

View File

@@ -1,34 +0,0 @@
import { cn } from '@/lib/utils';
export function PlusLine({ className }: { className?: string }) {
return (
<div className={cn('absolute', className)}>
<div className="relative">
<div className="w-px h-8 bg-foreground/40 -bottom-4 left-0 absolute animate-pulse" />
<div className="w-8 h-px bg-foreground/40 -bottom-px -left-4 absolute animate-pulse" />
</div>
</div>
);
}
export function VerticalLine({ className }: { className?: string }) {
return (
<div
className={cn(
'w-px bg-gradient-to-t from-transparent via-foreground/30 to-transparent absolute -top-12 -bottom-12',
className,
)}
/>
);
}
export function HorizontalLine({ className }: { className?: string }) {
return (
<div
className={cn(
'h-px bg-gradient-to-r from-transparent via-foreground/30 to-transparent absolute left-0 right-0',
className,
)}
/>
);
}

View File

@@ -1,135 +0,0 @@
'use client';
import { baseOptions } from '@/app/layout.config';
import { cn } from '@/lib/utils';
import { AnimatePresence, motion } from 'framer-motion';
import { MenuIcon } from 'lucide-react';
import Link from 'next/link';
import { useEffect, useRef, useState } from 'react';
import { GithubButton } from './github-button';
import { Logo } from './logo';
import { Button } from './ui/button';
const Navbar = () => {
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const navbarRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
useEffect(() => {
// If click outside of the menu, close it
const handleClick = (e: MouseEvent) => {
if (isMobileMenuOpen && !navbarRef.current?.contains(e.target as Node)) {
setIsMobileMenuOpen(false);
}
};
window.addEventListener('click', handleClick);
return () => window.removeEventListener('click', handleClick);
}, [isMobileMenuOpen]);
return (
<nav className="fixed top-4 z-50 w-full" ref={navbarRef}>
<div className="container">
<div
className={cn(
'flex justify-between border border-transparent backdrop-blur-lg items-center p-4 -mx-4 rounded-full transition-colors',
isScrolled
? 'bg-background/90 border-foreground/10'
: 'bg-transparent',
)}
>
{/* Logo */}
<div className="flex-shrink-0">
<Link href="/" className="row items-center font-medium">
<Logo className="h-6" />
{baseOptions.nav?.title}
</Link>
</div>
<div className="row items-center gap-8">
{/* Desktop Navigation */}
<div className="hidden md:flex items-center space-x-8 text-sm">
{baseOptions.links?.map((link) => {
if (link.type !== 'main') {
return null;
}
return (
<Link
key={link.url}
href={link.url!}
className="text-foreground/80 hover:text-foreground font-medium"
>
{link.text}
</Link>
);
})}
</div>
{/* Right side buttons */}
<div className="flex items-center gap-2">
<GithubButton />
{/* Sign in button */}
<Button asChild>
<Link
className="hidden md:flex"
href="https://dashboard.openpanel.dev/login"
>
Sign in
</Link>
</Button>
<Button
className="md:hidden -my-2"
size="icon"
variant="ghost"
onClick={() => {
setIsMobileMenuOpen((p) => !p);
}}
>
<MenuIcon className="w-4 h-4" />
</Button>
</div>
</div>
</div>
{/* Mobile menu */}
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.2 }}
className="overflow-hidden -mx-4"
>
<div className="rounded-xl bg-background/90 border border-foreground/10 mt-4 md:hidden backdrop-blur-lg">
<div className="col text-sm divide-y divide-foreground/10">
{baseOptions.links?.map((link) => {
if (link.type !== 'main') return null;
return (
<Link
key={link.url}
href={link.url!}
className="text-foreground/80 hover:text-foreground text-xl font-medium p-4 px-4"
onClick={() => setIsMobileMenuOpen(false)}
>
{link.text}
</Link>
);
})}
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</nav>
);
};
export default Navbar;

View File

@@ -1,31 +0,0 @@
import { cn } from '@/lib/utils';
export function Section({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return <section className={cn('my-32 col', className)}>{children}</section>;
}
export function SectionHeader({
tag,
title,
description,
className,
}: {
tag?: React.ReactNode;
title: string;
description: string;
className?: string;
}) {
return (
<div className={cn('col gap-4 center-center mb-16', className)}>
{tag}
<h2 className="text-4xl font-medium">{title}</h2>
<p className="text-muted-foreground max-w-screen-sm">{description}</p>
</div>
);
}

View File

@@ -1,141 +0,0 @@
import { ShieldQuestionIcon } from 'lucide-react';
import Script from 'next/script';
import { Section, SectionHeader } from '../section';
import { Tag } from '../tag';
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '../ui/accordion';
const questions = [
{
question: 'Does OpenPanel have a free tier?',
answer: [
'For our Cloud plan we offer a 30 days free trial, this is mostly for you to be able to try out OpenPanel before committing to a paid plan.',
'OpenPanel is also open-source and you can self-host it for free!',
'',
'Why does OpenPanel not have a free tier?',
'We want to make sure that OpenPanel is used by people who are serious about using it. We also need to invest time and resources to maintain the platform and provide support to our users.',
],
},
{
question: 'Is everything really unlimited?',
answer: [
'Everything except the amount of events is unlimited.',
'We do not limit the amount of users, projects, dashboards, etc. We want a transparent and fair pricing model and we think unlimited is the best way to do this.',
],
},
{
question: 'What is the difference between web and product analytics?',
answer: [
'Web analytics focuses on website traffic metrics like page views, bounce rates, and visitor sources. Product analytics goes deeper into user behavior, tracking specific actions, user journeys, and feature usage within your application.',
],
},
{
question: 'Do I need to modify my code to use OpenPanel?',
answer: [
'Minimal setup is required. Simply add our lightweight JavaScript snippet to your website or use one of our SDKs for your preferred framework. Most common frameworks like React, Vue, and Next.js are supported.',
],
},
{
question: 'Is my data GDPR compliant?',
answer: [
'Yes, OpenPanel is fully GDPR compliant. We collect only essential data, do not use cookies for tracking, and provide tools to help you maintain compliance with privacy regulations.',
'You can self-host OpenPanel to keep full control of your data.',
],
},
{
question: 'How does OpenPanel compare to Mixpanel?',
answer: [
'OpenPanel offers most of Mixpanel report features such as funnels, retention and visualizations of your data. If you miss something, please let us know. The biggest difference is that OpenPanel offers better web analytics.',
'Other than that OpenPanel is way cheaper and can also be self-hosted.',
],
},
{
question: 'How does OpenPanel compare to Plausible?',
answer: [
`OpenPanel's web analytics is inspired by Plausible like many other analytics tools. The difference is that OpenPanel offers more tools for product analytics and better support for none web devices (iOS,Android and servers).`,
],
},
{
question: 'How does OpenPanel compare to Google Analytics?',
answer: [
'OpenPanel offers a more privacy-focused, user-friendly alternative to Google Analytics. We provide real-time data, no sampling, and more intuitive product analytics features.',
'Unlike GA4, our interface is designed to be simple yet powerful, making it easier to find the insights you need.',
],
},
{
question: 'Can I export my data?',
answer: [
'Currently you can export your data with our API. Depending on how many events you have this can be an issue.',
'We are working on better export options and will be finished around Q1 2025.',
],
},
{
question: 'What kind of support do you offer?',
answer: ['Currently we offer support through GitHub and Discord.'],
},
];
export default Faq;
export function Faq() {
// Create the JSON-LD structured data
const faqJsonLd = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: questions.map((q) => ({
'@type': 'Question',
name: q.question,
acceptedAnswer: {
'@type': 'Answer',
text: q.answer.join(' '),
},
})),
};
return (
<Section className="container">
{/* Add the JSON-LD script */}
<Script
strategy="beforeInteractive"
id="faq-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqJsonLd) }}
/>
<SectionHeader
tag={
<Tag>
<ShieldQuestionIcon className="size-4" strokeWidth={1.5} />
Get answers today
</Tag>
}
title="FAQ"
description="Some of the most common questions we get asked."
/>
<Accordion
type="single"
collapsible
className="w-full max-w-screen-md self-center"
>
{questions.map((q) => (
<AccordionItem value={q.question} key={q.question}>
<AccordionTrigger className="text-left">
{q.question}
</AccordionTrigger>
<AccordionContent>
<div className="max-w-2xl col gap-2">
{q.answer.map((a) => (
<p key={a}>{a}</p>
))}
</div>
</AccordionContent>
</AccordionItem>
))}
</Accordion>
</Section>
);
}

View File

@@ -1,321 +0,0 @@
import {
Feature,
FeatureContent,
FeatureList,
FeatureListItem,
FeatureMore,
SmallFeature,
} from '@/components/feature';
import { Section, SectionHeader } from '@/components/section';
import { Tag } from '@/components/tag';
import {
ActivityIcon,
AreaChartIcon,
BarChart2Icon,
BarChartIcon,
CheckIcon,
ClockIcon,
CloudIcon,
ConeIcon,
CookieIcon,
DatabaseIcon,
GithubIcon,
LayersIcon,
LineChartIcon,
LockIcon,
MapIcon,
PieChartIcon,
ServerIcon,
Share2Icon,
ShieldIcon,
UserIcon,
WalletIcon,
ZapIcon,
} from 'lucide-react';
import { BatteryIcon } from '../battery-icon';
import { EventsFeature } from './features/events-feature';
import { ProductAnalyticsFeature } from './features/product-analytics-feature';
import { ProfilesFeature } from './features/profiles-feature';
import { WebAnalyticsFeature } from './features/web-analytics-feature';
export function Features() {
return (
<Section className="container">
<SectionHeader
className="mb-16"
tag={
<Tag>
<BatteryIcon className="size-4" strokeWidth={1.5} />
Batteries included
</Tag>
}
title="Everything you need"
description="We have combined the best features from the most popular analytics tools into one simple to use platform."
/>
<div className="col gap-16">
<Feature media={<WebAnalyticsFeature />}>
<FeatureContent
title="Web analytics"
content={[
'Privacy-friendly analytics with all the important metrics you need, in a simple and modern interface.',
]}
/>
<FeatureList
className="mt-4"
title="Get a quick overview"
items={[
<FeatureListItem key="line" icon={CheckIcon} title="Visitors" />,
<FeatureListItem key="line" icon={CheckIcon} title="Referrals" />,
<FeatureListItem key="line" icon={CheckIcon} title="Top pages" />,
<FeatureListItem
key="line"
icon={CheckIcon}
title="Top entries"
/>,
<FeatureListItem
key="line"
icon={CheckIcon}
title="Top exists"
/>,
<FeatureListItem key="line" icon={CheckIcon} title="Devices" />,
<FeatureListItem key="line" icon={CheckIcon} title="Sessions" />,
<FeatureListItem
key="line"
icon={CheckIcon}
title="Bounce rate"
/>,
<FeatureListItem key="line" icon={CheckIcon} title="Duration" />,
<FeatureListItem key="line" icon={CheckIcon} title="Geography" />,
]}
/>
</Feature>
<Feature reverse media={<ProductAnalyticsFeature />}>
<FeatureContent
title="Product analytics"
content={[
'Turn data into decisions with powerful visualizations and real-time insights.',
]}
/>
<FeatureList
className="mt-4"
title="Understand your product"
items={[
<FeatureListItem key="funnel" icon={ConeIcon} title="Funnel" />,
<FeatureListItem
key="retention"
icon={UserIcon}
title="Retention"
/>,
<FeatureListItem
key="bar"
icon={BarChartIcon}
title="A/B tests"
/>,
<FeatureListItem
key="pie"
icon={PieChartIcon}
title="Conversion"
/>,
]}
/>
<FeatureList
className="mt-4"
title="Supported charts"
items={[
<FeatureListItem key="line" icon={LineChartIcon} title="Line" />,
<FeatureListItem key="bar" icon={BarChartIcon} title="Bar" />,
<FeatureListItem key="pie" icon={PieChartIcon} title="Pie" />,
<FeatureListItem key="area" icon={AreaChartIcon} title="Area" />,
<FeatureListItem
key="histogram"
icon={BarChart2Icon}
title="Histogram"
/>,
<FeatureListItem key="map" icon={MapIcon} title="Map" />,
]}
/>
</Feature>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<SmallFeature className="[&_[data-icon]]:hover:bg-blue-500">
<FeatureContent
icon={<ClockIcon className="size-8" strokeWidth={1} />}
title="Real time analytics"
content={[
'Get instant insights into your data. No need to wait for data to be processed, like other tools out there, looking at you GA4...',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-purple-500">
<FeatureContent
icon={<DatabaseIcon className="size-8" strokeWidth={1} />}
title="Own your own data"
content={[
'Own your data, no vendor lock-in. Export all your data with our export API.',
'Self-host it on your own infrastructure to have complete control.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-indigo-500">
<FeatureContent
icon={<CloudIcon className="size-8" strokeWidth={1} />}
title="Cloud or self-hosted"
content={[
'We offer a cloud version of the platform, but you can also self-host it on your own infrastructure.',
]}
/>
<FeatureMore
href="/docs/self-hosting/self-hosting"
className="mt-4 -mb-4"
>
More about self-hosting
</FeatureMore>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-green-500">
<FeatureContent
icon={<CookieIcon className="size-8" strokeWidth={1} />}
title="No cookies"
content={[
'We care about your privacy, so our tracker does not use cookies. This keeps your data safe and secure.',
'We follow GDPR guidelines closely, ensuring your personal information is protected without using invasive technologies.',
]}
/>
<FeatureMore
href="/articles/cookieless-analytics"
className="mt-4 -mb-4"
>
Cookieless analytics
</FeatureMore>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-gray-500">
<FeatureContent
icon={<GithubIcon className="size-8" strokeWidth={1} />}
title="Open-source"
content={[
'Our code is open and transparent. Contribute, fork, or learn from our implementation.',
]}
/>
<FeatureMore
href="https://git.new/openpanel"
className="mt-4 -mb-4"
>
View the code
</FeatureMore>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-purple-500">
<FeatureContent
icon={<LockIcon className="size-8" strokeWidth={1} />}
title="Your data, your rules"
content={[
'Complete control over your data. Export, delete, or manage it however you need.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-yellow-500">
<FeatureContent
icon={<WalletIcon className="size-8" strokeWidth={1} />}
title="Affordably priced"
content={[
'Transparent pricing that scales with your needs. No hidden fees or surprise charges.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-orange-500">
<FeatureContent
icon={<ZapIcon className="size-8" strokeWidth={1} />}
title="Moving fast"
content={[
'Regular updates and improvements. We move quickly to add features you need.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-blue-500">
<FeatureContent
icon={<ActivityIcon className="size-8" strokeWidth={1} />}
title="Real-time data"
content={[
'See your analytics as they happen. No waiting for data processing or updates.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-indigo-500">
<FeatureContent
icon={<Share2Icon className="size-8" strokeWidth={1} />}
title="Sharable reports"
content={[
'Easily share insights with your team. Export and distribute reports with a single click.',
<i key="soon">Coming soon</i>,
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-pink-500">
<FeatureContent
icon={<BarChart2Icon className="size-8" strokeWidth={1} />}
title="Visualize your data"
content={[
'Beautiful, interactive visualizations that make your data easy to understand.',
]}
/>
</SmallFeature>
<SmallFeature className="[&_[data-icon]]:hover:bg-indigo-500">
<FeatureContent
icon={<LayersIcon className="size-8" strokeWidth={1} />}
title="Best of both worlds"
content={[
'Combine the power of self-hosting with the convenience of cloud deployment.',
]}
/>
</SmallFeature>
</div>
<Feature media={<EventsFeature />}>
<FeatureContent
title="Your events"
content={[
'Track every user interaction with powerful real-time event analytics. See all event properties, user actions, and conversion data in one place.',
'From pageviews to custom events, get complete visibility into how users actually use your product.',
]}
/>
<FeatureList
cols={1}
className="mt-4"
title="Some goodies"
items={[
'• Events arrive within seconds',
'• Filter on any property or attribute',
'• Get notified on important events',
'• Export and analyze event data',
'• Track user journeys and conversions',
]}
/>
</Feature>
<Feature reverse media={<ProfilesFeature />}>
<FeatureContent
title="Profiles and sessions"
content={[
'Get detailed insights into how users interact with your product through comprehensive profile and session tracking. See everything from basic metrics to detailed behavioral patterns.',
'Track session duration, page views, and user journeys to understand how people actually use your product.',
]}
/>
<FeatureList
cols={1}
className="mt-4"
title="What can you see?"
items={[
'• First and last seen dates',
'• Session duration and counts',
'• Page views and activity patterns',
'• User location and device info',
'• Browser and OS details',
'• Event history and interactions',
'• Real-time activity tracking',
]}
/>
</Feature>
</div>
</Section>
);
}

View File

@@ -1,272 +0,0 @@
'use client';
import { AnimatePresence, motion } from 'framer-motion';
import {
BellIcon,
BookOpenIcon,
DownloadIcon,
EyeIcon,
HeartIcon,
LogOutIcon,
MessageSquareIcon,
SearchIcon,
SettingsIcon,
Share2Icon,
ShoppingCartIcon,
StarIcon,
ThumbsUpIcon,
UserPlusIcon,
} from 'lucide-react';
import { useEffect, useState } from 'react';
interface Event {
id: number;
action: string;
location: string;
platform: string;
icon: any;
color: string;
}
const locations = [
'Gothenburg',
'Stockholm',
'Oslo',
'Copenhagen',
'Berlin',
'New York',
'Singapore',
'London',
'Paris',
'Madrid',
'Rome',
'Barcelona',
'Amsterdam',
'Vienna',
];
const platforms = ['iOS', 'Android', 'Windows', 'macOS'];
const browsers = ['WebKit', 'Chrome', 'Firefox', 'Safari'];
const getCountryFlag = (country: (typeof locations)[number]) => {
switch (country) {
case 'Gothenburg':
return '🇸🇪';
case 'Stockholm':
return '🇸🇪';
case 'Oslo':
return '🇳🇴';
case 'Copenhagen':
return '🇩🇰';
case 'Berlin':
return '🇩🇪';
case 'New York':
return '🇺🇸';
case 'Singapore':
return '🇸🇬';
case 'London':
return '🇬🇧';
case 'Paris':
return '🇫🇷';
case 'Madrid':
return '🇪🇸';
case 'Rome':
return '🇮🇹';
case 'Barcelona':
return '🇪🇸';
case 'Amsterdam':
return '🇳🇱';
case 'Vienna':
return '🇦🇹';
}
};
const getPlatformIcon = (platform: (typeof platforms)[number]) => {
switch (platform) {
case 'iOS':
return '🍎';
case 'Android':
return '🤖';
case 'Windows':
return '💻';
case 'macOS':
return '🍎';
}
};
const TOTAL_EVENTS = 10;
export function EventsFeature() {
const [events, setEvents] = useState<Event[]>([
{
id: 1730663803358.4075,
action: 'purchase',
location: 'New York',
platform: 'macOS',
icon: ShoppingCartIcon,
color: 'bg-blue-500',
},
{
id: 1730663801358.3079,
action: 'logout',
location: 'Copenhagen',
platform: 'Windows',
icon: LogOutIcon,
color: 'bg-red-500',
},
{
id: 1730663799358.0283,
action: 'sign up',
location: 'Berlin',
platform: 'Android',
icon: UserPlusIcon,
color: 'bg-green-500',
},
{
id: 1730663797357.2036,
action: 'share',
location: 'Barcelona',
platform: 'macOS',
icon: Share2Icon,
color: 'bg-cyan-500',
},
{
id: 1730663795358.763,
action: 'sign up',
location: 'New York',
platform: 'macOS',
icon: UserPlusIcon,
color: 'bg-green-500',
},
{
id: 1730663792067.689,
action: 'share',
location: 'New York',
platform: 'macOS',
icon: Share2Icon,
color: 'bg-cyan-500',
},
{
id: 1730663790075.3435,
action: 'like',
location: 'Copenhagen',
platform: 'iOS',
icon: HeartIcon,
color: 'bg-pink-500',
},
{
id: 1730663788070.351,
action: 'recommend',
location: 'Oslo',
platform: 'Android',
icon: ThumbsUpIcon,
color: 'bg-orange-500',
},
{
id: 1730663786074.429,
action: 'read',
location: 'New York',
platform: 'Windows',
icon: BookOpenIcon,
color: 'bg-teal-500',
},
{
id: 1730663784065.6309,
action: 'sign up',
location: 'Gothenburg',
platform: 'iOS',
icon: UserPlusIcon,
color: 'bg-green-500',
},
]);
useEffect(() => {
// Prepend new event every 2 seconds
const interval = setInterval(() => {
setEvents((prevEvents) => [
generateEvent(),
...prevEvents.slice(0, TOTAL_EVENTS - 1),
]);
}, 2000);
return () => clearInterval(interval);
}, []);
return (
<div className="overflow-hidden p-8 max-h-[700px]">
<div
className="min-w-[500px] gap-4 flex flex-col overflow-hidden relative isolate"
// style={{ height: 60 * TOTAL_EVENTS + 16 * (TOTAL_EVENTS - 1) }}
>
<AnimatePresence mode="popLayout" initial={false}>
{events.map((event) => (
<motion.div
key={event.id}
className="flex items-center shadow bg-background-light rounded"
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: '60px' }}
exit={{ opacity: 0, height: 0 }}
transition={{
duration: 0.3,
type: 'spring',
stiffness: 500,
damping: 50,
opacity: { duration: 0.2 },
}}
>
<div className="flex items-center gap-2 w-[200px] py-2 px-4">
<div
className={`size-8 rounded-full bg-background flex items-center justify-center ${event.color} text-white `}
>
{event.icon && <event.icon size={16} />}
</div>
<span className="font-medium truncate">{event.action}</span>
</div>
<div className="w-[150px] py-2 px-4 truncate">
<span className="mr-2 text-xl relative top-px">
{getCountryFlag(event.location)}
</span>
{event.location}
</div>
<div className="w-[150px] py-2 px-4 truncate">
<span className="mr-2 text-xl relative top-px">
{getPlatformIcon(event.platform)}
</span>
{event.platform}
</div>
</motion.div>
))}
</AnimatePresence>
</div>
</div>
);
}
// Helper function to generate events (moved outside component)
function generateEvent() {
const actions = [
{ text: 'sign up', icon: UserPlusIcon, color: 'bg-green-500' },
{ text: 'purchase', icon: ShoppingCartIcon, color: 'bg-blue-500' },
{ text: 'screen view', icon: EyeIcon, color: 'bg-purple-500' },
{ text: 'logout', icon: LogOutIcon, color: 'bg-red-500' },
{ text: 'like', icon: HeartIcon, color: 'bg-pink-500' },
{ text: 'comment', icon: MessageSquareIcon, color: 'bg-indigo-500' },
{ text: 'share', icon: Share2Icon, color: 'bg-cyan-500' },
{ text: 'download', icon: DownloadIcon, color: 'bg-emerald-500' },
{ text: 'notification', icon: BellIcon, color: 'bg-violet-500' },
{ text: 'settings', icon: SettingsIcon, color: 'bg-slate-500' },
{ text: 'search', icon: SearchIcon, color: 'bg-violet-500' },
{ text: 'read', icon: BookOpenIcon, color: 'bg-teal-500' },
{ text: 'recommend', icon: ThumbsUpIcon, color: 'bg-orange-500' },
{ text: 'favorite', icon: StarIcon, color: 'bg-yellow-500' },
];
const selectedAction = actions[Math.floor(Math.random() * actions.length)];
return {
id: Date.now() + Math.random(),
action: selectedAction.text,
location: locations[Math.floor(Math.random() * locations.length)],
platform: platforms[Math.floor(Math.random() * platforms.length)],
icon: selectedAction.icon,
color: selectedAction.color,
};
}

View File

@@ -1,193 +0,0 @@
'use client';
import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';
// Mock data structure for retention cohort
const COHORT_DATA = [
{
week: 'Week 1',
users: '2,543',
retention: [100, 84, 73, 67, 62, 58],
},
{
week: 'Week 2',
users: '2,148',
retention: [100, 80, 69, 63, 59, 55],
},
{
week: 'Week 3',
users: '1,958',
retention: [100, 82, 71, 64, 60, 56],
},
{
week: 'Week 4',
users: '2,034',
retention: [100, 83, 72, 65, 61, 57],
},
{
week: 'Week 5',
users: '1,987',
retention: [100, 81, 70, 64, 60, 56],
},
{
week: 'Week 6',
users: '2,245',
retention: [100, 85, 74, 68, 64, 60],
},
{
week: 'Week 7',
users: '2,108',
retention: [100, 82, 71, 65, 61],
},
{
week: 'Week 8',
users: '1,896',
retention: [100, 83, 72, 66],
},
{
week: 'Week 9',
users: '2,156',
retention: [100, 81, 70],
},
];
const COHORT_DATA_ALT = [
{
week: 'Week 1',
users: '2,876',
retention: [100, 79, 76, 70, 65, 61],
},
{
week: 'Week 2',
users: '2,543',
retention: [100, 85, 73, 67, 62, 58],
},
{
week: 'Week 3',
users: '2,234',
retention: [100, 79, 75, 68, 63, 59],
},
{
week: 'Week 4',
users: '2,456',
retention: [100, 88, 77, 69, 65, 61],
},
{
week: 'Week 5',
users: '2,321',
retention: [100, 77, 73, 67, 54, 42],
},
{
week: 'Week 6',
users: '2,654',
retention: [100, 91, 83, 69, 66, 62],
},
{
week: 'Week 7',
users: '2,432',
retention: [100, 93, 88, 72, 64],
},
{
week: 'Week 8',
users: '2,123',
retention: [100, 78, 76, 69],
},
{
week: 'Week 9',
users: '2,567',
retention: [100, 70, 64],
},
];
function RetentionCell({ percentage }: { percentage: number }) {
// Calculate color intensity based on percentage
const getBackgroundColor = (value: number) => {
if (value === 0) return 'bg-transparent';
// Using CSS color mixing to create a gradient from light to dark blue
return `rgb(${Math.round(239 - value * 1.39)} ${Math.round(246 - value * 1.46)} ${Math.round(255 - value * 0.55)})`;
};
return (
<div className="flex items-center justify-center p-px text-sm font-medium w-[80px]">
<div
className="flex text-white items-center justify-center w-full h-full rounded"
style={{
backgroundColor: getBackgroundColor(percentage),
}}
>
<motion.span
key={percentage}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
{percentage}%
</motion.span>
</div>
</div>
);
}
export function ProductAnalyticsFeature() {
const [currentData, setCurrentData] = useState(COHORT_DATA);
useEffect(() => {
const interval = setInterval(() => {
setCurrentData((current) =>
current === COHORT_DATA ? COHORT_DATA_ALT : COHORT_DATA,
);
}, 3000);
return () => clearInterval(interval);
}, []);
return (
<div className="p-4 w-full overflow-hidden">
<div className="flex">
{/* Header row */}
<div className="min-w-[70px] flex flex-col">
<div className="p-2 font-medium text-xs text-muted-foreground">
Cohort
</div>
</div>
{/* Week numbers - changed length to 6 */}
<div className="flex">
{Array.from({ length: 6 }).map((_, i) => (
<div
key={i.toString()}
className="text-muted-foreground w-[80px] text-xs text-center p-2 font-medium"
>
W{i + 1}
</div>
))}
</div>
</div>
{/* Data rows */}
<div className="flex flex-col">
{currentData.map((cohort, rowIndex) => (
<div key={rowIndex.toString()} className="flex">
<div className="min-w-[70px] flex flex-col">
<div className="p-2 text-sm whitespace-nowrap text-muted-foreground">
{cohort.week}
</div>
</div>
<div className="flex">
{cohort.retention.map((value, cellIndex) => (
<RetentionCell key={cellIndex.toString()} percentage={value} />
))}
{/* Fill empty cells - changed length to 6 */}
{Array.from({ length: 6 - cohort.retention.length }).map(
(_, i) => (
<div key={`empty-${i.toString()}`} className="w-[80px] p-px">
<div className="h-full w-full rounded bg-background" />
</div>
),
)}
</div>
</div>
))}
</div>
</div>
);
}

View File

@@ -1,139 +0,0 @@
'use client';
import Image from 'next/image';
import { useEffect, useState } from 'react';
const PROFILES = [
{
name: 'Joe Bloggs',
email: 'joe@bloggs.com',
avatar: '/avatar.jpg',
stats: {
firstSeen: 'about 2 months',
lastSeen: '41 minutes',
sessions: '8',
avgSession: '5m 59s',
p90Session: '7m 42s',
pageViews: '41',
},
},
{
name: 'Jane Smith',
email: 'jane@smith.com',
avatar: '/avatar-2.jpg',
stats: {
firstSeen: 'about 1 month',
lastSeen: '2 hours',
sessions: '12',
avgSession: '4m 32s',
p90Session: '6m 15s',
pageViews: '35',
},
},
{
name: 'Alex Johnson',
email: 'alex@johnson.com',
avatar: '/avatar-3.jpg',
stats: {
firstSeen: 'about 3 months',
lastSeen: '15 minutes',
sessions: '15',
avgSession: '6m 20s',
p90Session: '8m 10s',
pageViews: '52',
},
},
];
export function ProfilesFeature() {
const [currentIndex, setCurrentIndex] = useState(0);
const [isTransitioning, setIsTransitioning] = useState(true);
useEffect(() => {
const timer = setInterval(() => {
if (currentIndex === PROFILES.length) {
setIsTransitioning(false);
setCurrentIndex(0);
setTimeout(() => setIsTransitioning(true), 50);
} else {
setCurrentIndex((current) => current + 1);
}
}, 3000);
return () => clearInterval(timer);
}, [currentIndex]);
return (
<div className="overflow-hidden">
<div
className={`flex ${isTransitioning ? 'transition-transform duration-500 ease-in-out' : ''}`}
style={{ transform: `translateX(-${currentIndex * 100}%)` }}
>
{[...PROFILES, PROFILES[0]].map((profile, index) => (
<div
key={profile.name + index.toString()}
className="w-full flex-shrink-0 p-8"
>
<div className="col md:row justify-center md:justify-start items-center gap-4">
<Image
src={profile.avatar}
className="size-32 rounded-full"
width={128}
height={128}
alt={profile.name}
/>
<div>
<div className="text-3xl font-semibold">{profile.name}</div>
<div className="text-muted-foreground text-center md:text-left">
{profile.email}
</div>
</div>
</div>
<div className="mt-8 grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">First seen</div>
<div className="text-lg font-medium">
{profile.stats.firstSeen}
</div>
</div>
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">Last seen</div>
<div className="text-lg font-medium">
{profile.stats.lastSeen}
</div>
</div>
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">Sessions</div>
<div className="text-lg font-medium">
{profile.stats.sessions}
</div>
</div>
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">
Avg. Session
</div>
<div className="text-lg font-medium">
{profile.stats.avgSession}
</div>
</div>
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">
P90. Session
</div>
<div className="text-lg font-medium">
{profile.stats.p90Session}
</div>
</div>
<div className="rounded-lg border p-4 bg-background-light">
<div className="text-sm text-muted-foreground">Page views</div>
<div className="text-lg font-medium">
{profile.stats.pageViews}
</div>
</div>
</div>
</div>
))}
</div>
</div>
);
}

View File

@@ -1,194 +0,0 @@
import { cn } from '@/lib/utils';
import { PRICING } from '@openpanel/payments/src/prices';
import { CheckIcon, ChevronRightIcon, DollarSignIcon } from 'lucide-react';
import Link from 'next/link';
import { DoubleSwirl } from '../Swirls';
import { Section, SectionHeader } from '../section';
import { Tag } from '../tag';
import { Button } from '../ui/button';
import { Tooltiper } from '../ui/tooltip';
export default Pricing;
export function Pricing({ className }: { className?: string }) {
return (
<Section
className={cn(
'overflow-hidden relative bg-foreground dark:bg-background-dark text-background dark:text-foreground xl:rounded-xl p-0 pb-32 pt-16 max-w-7xl mx-auto',
className,
)}
>
<DoubleSwirl className="absolute top-0 left-0" />
<div className="container relative z-10 col">
<SectionHeader
tag={
<Tag variant={'dark'}>
<DollarSignIcon className="size-4" />
Simple and predictable
</Tag>
}
title="Simple pricing"
description="Just pick how many events you want to track each month. No hidden costs."
/>
<div className="grid self-center md:grid-cols-[200px_1fr] lg:grid-cols-[300px_1fr] gap-8">
<div className="col gap-4">
<h3 className="font-medium text-xl text-background/90 dark:text-foreground/90">
Stop overpaying for features
</h3>
<ul className="gap-1 col text-background/70 dark:text-foreground/70">
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />
Unlimited websites or apps
</li>
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />{' '}
Unlimited users
</li>
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />{' '}
Unlimited dashboards
</li>
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />{' '}
Unlimited charts
</li>
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />{' '}
Unlimited tracked profiles
</li>
<li className="flex items-center gap-2">
<CheckIcon className="text-background/30 dark:text-foreground/30 size-4" />{' '}
Yes, we have no limits or hidden costs
</li>
</ul>
<Button
variant="secondary"
size="lg"
asChild
className="self-start mt-4 px-8 group"
>
<Link href="https://dashboard.openpanel.dev/onboarding">
Get started now
<ChevronRightIcon className="size-4 group-hover:translate-x-1 transition-transform group-hover:scale-125" />
</Link>
</Button>
</div>
<div className="col justify-between gap-4 max-w-lg">
<div className="space-y-2">
{PRICING.map((tier) => (
<div
key={tier.events}
className={cn(
'group col',
'backdrop-blur-3xl bg-foreground/70 dark:bg-background-dark/70',
'p-4 py-2 border border-background/20 dark:border-foreground/20 rounded-lg hover:bg-background/5 dark:hover:bg-foreground/5 transition-colors',
'mx-2',
tier.discount &&
'mx-0 px-6 py-3 !bg-emerald-900/20 hover:!bg-emerald-900/30',
tier.popular &&
'mx-0 px-6 py-3 !bg-orange-900/20 hover:!bg-orange-900/30',
)}
>
<div className="row justify-between">
<div>
{new Intl.NumberFormat('en-US', {}).format(tier.events)}{' '}
<span className="text-muted-foreground text-sm max-[420px]:hidden">
events / month
</span>
</div>
<div className="row gap-4">
{tier.popular && (
<>
<Tag variant="dark" className="hidden md:inline-flex">
🔥 Popular
</Tag>
<span className="md:hidden">🔥</span>
</>
)}
{tier.discount && (
<>
<Tag
variant="dark"
className="hidden md:inline-flex whitespace-nowrap"
>
💸 Discount
</Tag>
<span className="md:hidden">💸</span>
</>
)}
<div className="row gap-1">
{tier.discount && (
<span className={cn('text-md font-semibold')}>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(tier.price * (1 - tier.discount.amount))}
</span>
)}
<span
className={cn(
'text-md font-semibold',
tier.discount && 'line-through opacity-50',
)}
>
{new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(tier.price)}
</span>
</div>
</div>
</div>
{tier.discount && (
<div className="text-sm text-muted-foreground mt-2">
Limited discount code available:{' '}
<Tooltiper
content={`Get ${tier.discount.amount * 100}% off your first year`}
delayDuration={0}
side="bottom"
>
<strong>{tier.discount.code}</strong>
</Tooltiper>
</div>
)}
</div>
))}
<div
className={cn(
'group',
'row justify-between p-4 py-2 border border-background/20 dark:border-foreground/20 rounded-lg hover:bg-background/5 dark:hover:bg-foreground/5 transition-colors',
'mx-2',
)}
>
<div className="whitespace-nowrap">
Over{' '}
{new Intl.NumberFormat('en-US', {}).format(
PRICING[PRICING.length - 1].events,
)}
</div>
<div className="text-md font-semibold">
<Link
href="mailto:support@openpanel.dev"
className="group-hover:underline"
>
Contact us
</Link>
</div>
</div>
</div>
<div className="self-center text-sm text-muted-foreground mt-4 text-center max-w-[70%] w-full">
<strong className="text-background/80 dark:text-foreground/80">
All features are included upfront - no hidden costs.
</strong>{' '}
You choose how many events to track each month.
</div>
</div>
</div>
</div>
</Section>
);
}

View File

@@ -1,86 +0,0 @@
import { Section, SectionHeader } from '@/components/section';
import { Tag } from '@/components/tag';
import { type Framework, frameworks } from '@openpanel/sdk-info';
import { CodeIcon, ShieldQuestionIcon } from 'lucide-react';
import Link from 'next/link';
import { HorizontalLine, PlusLine, VerticalLine } from '../line';
import { Button } from '../ui/button';
export function Sdks() {
return (
<Section className="container overflow-hidden">
<SectionHeader
tag={
<Tag>
<ShieldQuestionIcon className="size-4" strokeWidth={1.5} />
Easy to use
</Tag>
}
title="SDKs"
description="Use our modules to integrate with your favourite framework and start collecting events with ease. Enjoy quick and seamless setup."
/>
<div className="col gap-16">
<div className="relative">
<HorizontalLine className="-top-px opacity-40 -left-32 -right-32" />
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 container">
{frameworks.slice(0, 5).map((sdk, index) => (
<SdkCard key={sdk.name} sdk={sdk} index={index} />
))}
</div>
<HorizontalLine className="opacity-40 -left-32 -right-32" />
</div>
<div className="relative">
<HorizontalLine className="-top-px opacity-40 -left-32 -right-32" />
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 container">
{frameworks.slice(5, 10).map((sdk, index) => (
<SdkCard key={sdk.name} sdk={sdk} index={index} />
))}
</div>
<HorizontalLine className="opacity-40 -left-32 -right-32" />
</div>
<div className="center-center gap-2 col">
<h3 className="text-muted-foreground text-sm">And many more!</h3>
<Button asChild>
<Link href="/docs">Read our docs</Link>
</Button>
</div>
</div>
</Section>
);
}
function SdkCard({
sdk,
index,
}: {
sdk: Framework;
index: number;
}) {
return (
<Link
key={sdk.name}
href={sdk.href}
className="group relative z-10 col gap-2 uppercase center-center aspect-video bg-background-light rounded-lg shadow-[inset_0_0_0_1px_theme(colors.border),0_0_30px_0px_hsl(var(--border)/0.5)] transition-all hover:scale-105 hover:bg-background-dark"
>
{index === 0 && <PlusLine className="opacity-30 top-0 left-0" />}
{index === 2 && <PlusLine className="opacity-80 bottom-0 right-0" />}
<VerticalLine className="left-0 opacity-40" />
<VerticalLine className="right-0 opacity-40" />
<div className="absolute inset-0 center-center overflow-hidden opacity-20">
<sdk.IconComponent className="size-32 top-[33%] relative group-hover:top-[30%] group-hover:scale-105 transition-all" />
</div>
<div
className="center-center gap-1 col w-full h-full relative rounded-lg"
style={{
background:
'radial-gradient(circle, hsl(var(--background)) 0%, hsl(var(--background)/0.7) 100%)',
}}
>
<sdk.IconComponent className="size-8" />
{/* <h4 className="text-muted-foreground text-[10px]">{sdk.name}</h4> */}
</div>
</Link>
);
}

View File

@@ -1,93 +0,0 @@
import Link from 'next/link';
import { VerticalLine } from '../line';
import { PlusLine } from '../line';
import { HorizontalLine } from '../line';
import { Section } from '../section';
import { Button } from '../ui/button';
import { WorldMap } from '../world-map';
function shortNumber(num: number) {
if (num < 1e3) return num;
if (num >= 1e3 && num < 1e6) return `${+(num / 1e3).toFixed(1)}K`;
if (num >= 1e6 && num < 1e9) return `${+(num / 1e6).toFixed(1)}M`;
if (num >= 1e9 && num < 1e12) return `${+(num / 1e9).toFixed(1)}B`;
if (num >= 1e12) return `${+(num / 1e12).toFixed(1)}T`;
}
export async function Stats() {
const { projectsCount, eventsCount, eventsLast24hCount } = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/misc/stats`,
)
.then((res) => res.json())
.catch(() => ({
projectsCount: 0,
eventsCount: 0,
eventsLast24hCount: 0,
}));
return (
<StatsPure
projectCount={projectsCount}
eventCount={eventsCount}
last24hCount={eventsLast24hCount}
/>
);
}
export function StatsPure({
projectCount,
eventCount,
last24hCount,
}: { projectCount: number; eventCount: number; last24hCount: number }) {
return (
<Section className="bg-gradient-to-b from-background via-background-dark to-background-dark py-64 pt-44 relative overflow-hidden -mt-16">
{/* Map */}
<div className="absolute inset-0 -top-20 center-center items-start select-none opacity-10">
<div className="min-w-[1400px] w-full">
<WorldMap />
{/* Gradient over Map */}
<div className="absolute inset-0 bg-gradient-to-b from-background via-transparent to-background" />
</div>
</div>
<div className="relative">
<HorizontalLine />
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 container center-center">
<div className="col gap-2 uppercase center-center relative p-4">
<VerticalLine className="hidden lg:block left-0" />
<PlusLine className="hidden lg:block top-0 left-0" />
<div className="text-muted-foreground text-xs">Active projects</div>
<div className="text-5xl font-bold font-mono">{projectCount}</div>
</div>
<div className="col gap-2 uppercase center-center relative p-4">
<VerticalLine className="hidden lg:block left-0" />
<div className="text-muted-foreground text-xs">Total events</div>
<div className="text-5xl font-bold font-mono">
{shortNumber(eventCount)}
</div>
</div>
<div className="col gap-2 uppercase center-center relative p-4">
<VerticalLine className="hidden lg:block left-0" />
<VerticalLine className="hidden lg:block right-0" />
<PlusLine className="hidden lg:block bottom-0 left-0" />
<div className="text-muted-foreground text-xs">
Events last 24 h
</div>
<div className="text-5xl font-bold font-mono">
{shortNumber(last24hCount)}
</div>
</div>
</div>
<HorizontalLine />
</div>
<div className="center-center col gap-4 absolute bottom-20 left-0 right-0 z-10">
<p>Get the analytics you deserve</p>
<Button asChild>
<Link href="https://dashboard.openpanel.dev/onboarding">
Try it for free
</Link>
</Button>
</div>
</Section>
);
}

View File

@@ -1,113 +0,0 @@
import { Section, SectionHeader } from '@/components/section';
import { Tag } from '@/components/tag';
import { TwitterCard } from '@/components/twitter-card';
import { MessageCircleIcon } from 'lucide-react';
const testimonials = [
{
verified: true,
avatarUrl: '/twitter-steven.jpg',
name: 'Steven Tey',
handle: 'steventey',
content: [
'Open-source Mixpanel alternative just dropped → http://git.new/openpanel',
'It combines the power of Mixpanel + the ease of use of @PlausibleHQ into a fully open-source product.',
'Built by @CarlLindesvard and its already tracking 750K+ events 🤩',
],
replies: 25,
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-pontus.jpg',
name: 'Pontus Abrahamsson — oss/acc',
handle: 'pontusab',
content: ['Thanks, OpenPanel is a beast, love it!'],
replies: 25,
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-piotr.jpg',
name: 'Piotr Kulpinski',
handle: 'piotrkulpinski',
content: [
'The Overview tab in OpenPanel is great. It has everything I need from my analytics: the stats, the graph, traffic sources, locations, devices, etc.',
'The UI is beautiful ✨ Clean, modern look, very pleasing to the eye.',
],
replies: 25,
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-greg.png',
name: 'greg hodson 🍜',
handle: 'h0dson',
content: ['i second this, openpanel is killing it'],
replies: 25,
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-jacob.jpg',
name: 'Jacob 🍀 Build in Public',
handle: 'javayhuwx',
content: [
"🤯 wow, it's amazing! Just integrate @OpenPanelDev into http://indiehackers.site last night, and now I can see visitors coming from all round the world.",
'OpenPanel has a more beautiful UI and much more powerful features when compared to Umami.',
'#buildinpublic #indiehackers',
],
replies: 25,
retweets: 68,
likes: 648,
},
{
verified: true,
avatarUrl: '/twitter-lee.jpg',
name: 'Lee',
handle: 'DutchEngIishman',
content: [
'Day two of marketing.',
'I like this upward trend..',
'P.S. website went live on Sunday',
'P.P.S. Openpanel by @CarlLindesvard is awesome.',
],
replies: 25,
retweets: 68,
likes: 648,
},
];
export default Testimonials;
export function Testimonials() {
return (
<Section className="container">
<SectionHeader
tag={
<Tag>
<MessageCircleIcon className="size-4" strokeWidth={1.5} />
Testimonials
</Tag>
}
title="What people say"
description="What our customers say about us."
/>
<div className="col md:row gap-4">
<div className="col gap-4 flex-1">
{testimonials.slice(0, testimonials.length / 2).map((testimonial) => (
<TwitterCard key={testimonial.handle} {...testimonial} />
))}
</div>
<div className="col gap-4 flex-1">
{testimonials.slice(testimonials.length / 2).map((testimonial) => (
<TwitterCard key={testimonial.handle} {...testimonial} />
))}
</div>
</div>
</Section>
);
}

View File

@@ -1,87 +0,0 @@
import { cn } from '@/lib/utils';
import { ArrowDownIcon } from 'lucide-react';
import Image from 'next/image';
import { Section, SectionHeader } from './section';
import { Tag } from './tag';
import { Tooltip } from './ui/tooltip';
const images = [
{
name: 'Helpy UI',
url: 'https://helpy-ui.com',
logo: 'helpy-ui.png',
border: true,
},
{
name: 'KiddoKitchen',
url: 'https://kiddokitchen.se',
logo: 'kiddokitchen.png',
border: false,
},
{
name: 'Maneken',
url: 'https://maneken.app',
logo: 'maneken.jpg',
border: false,
},
{
name: 'Midday',
url: 'https://midday.ai',
logo: 'midday.png',
border: true,
},
{
name: 'Screenzen',
url: 'https://www.screenzen.co',
logo: 'screenzen.avif',
border: true,
},
{
name: 'Tiptip',
url: 'https://tiptip.id',
logo: 'tiptip.jpg',
border: true,
},
];
export function WhyOpenPanel() {
return (
<div className="bg-background-light my-12 col">
<Section className="container my-0 py-20">
<SectionHeader
title="Why OpenPanel?"
description="We built OpenPanel to get the best of both web and product analytics. With that in mind we have created a simple but very powerful platform that can handle most companies needs."
/>
<div className="center-center col gap-4 -mt-4">
<Tag>
<ArrowDownIcon className="size-4" strokeWidth={1.5} />
With 2000+ registered projects
</Tag>
<div className="row gap-4 justify-center flex-wrap">
{images.map((image) => (
<a
href={image.url}
target="_blank"
rel="noopener noreferrer nofollow"
key={image.logo}
className={cn(
'group rounded-lg bg-white center-center size-20 hover:scale-110 transition-all duration-300',
image.border && 'p-2 border border-border shadow-sm',
)}
title={image.name}
>
<Image
src={`/logos/${image.logo}`}
alt={image.name}
width={80}
height={80}
className="rounded-lg grayscale group-hover:grayscale-0 transition-all duration-300"
/>
</a>
))}
</div>
</div>
</Section>
</div>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,154 +0,0 @@
'use client';
import DottedMap from 'dotted-map/without-countries';
import { useEffect, useMemo, useState } from 'react';
import { mapJsonString } from './world-map-string';
// Static coordinates list with 50 points
const COORDINATES = [
// Western Hemisphere (Focused on West Coast)
{ lat: 47.6062, lng: -122.3321 }, // Seattle, USA
{ lat: 45.5155, lng: -122.6789 }, // Portland, USA
{ lat: 37.7749, lng: -122.4194 }, // San Francisco, USA
{ lat: 34.0522, lng: -118.2437 }, // Los Angeles, USA
{ lat: 32.7157, lng: -117.1611 }, // San Diego, USA
{ lat: 49.2827, lng: -123.1207 }, // Vancouver, Canada
{ lat: 58.3019, lng: -134.4197 }, // Juneau, Alaska
{ lat: 61.2181, lng: -149.9003 }, // Anchorage, Alaska
{ lat: 64.8378, lng: -147.7164 }, // Fairbanks, Alaska
{ lat: 71.2906, lng: -156.7886 }, // Utqiaġvik (Barrow), Alaska
{ lat: 60.5544, lng: -151.2583 }, // Kenai, Alaska
{ lat: 61.5815, lng: -149.444 }, // Wasilla, Alaska
{ lat: 66.1666, lng: -153.3707 }, // Bettles, Alaska
{ lat: 63.8659, lng: -145.637 }, // Delta Junction, Alaska
{ lat: 55.3422, lng: -131.6461 }, // Ketchikan, Alaska
// Eastern Hemisphere (Focused on East Asia)
{ lat: 35.6762, lng: 139.6503 }, // Tokyo, Japan
{ lat: 43.0621, lng: 141.3544 }, // Sapporo, Japan
{ lat: 26.2286, lng: 127.6809 }, // Naha, Japan
{ lat: 31.2304, lng: 121.4737 }, // Shanghai, China
{ lat: 22.3193, lng: 114.1694 }, // Hong Kong
{ lat: 37.5665, lng: 126.978 }, // Seoul, South Korea
{ lat: 25.033, lng: 121.5654 }, // Taipei, Taiwan
// Russian Far East
{ lat: 64.7336, lng: 177.5169 }, // Anadyr, Russia
{ lat: 59.5613, lng: 150.8086 }, // Magadan, Russia
{ lat: 43.1332, lng: 131.9113 }, // Vladivostok, Russia
{ lat: 53.0444, lng: 158.6478 }, // Petropavlovsk-Kamchatsky, Russia
{ lat: 62.0355, lng: 129.6755 }, // Yakutsk, Russia
{ lat: 48.4827, lng: 135.0846 }, // Khabarovsk, Russia
{ lat: 46.9589, lng: 142.7319 }, // Yuzhno-Sakhalinsk, Russia
{ lat: 52.9651, lng: 158.2728 }, // Yelizovo, Russia
{ lat: 56.1304, lng: 101.614 }, // Bratsk, Russia
// Australia & New Zealand (Main Cities)
{ lat: -33.8688, lng: 151.2093 }, // Sydney, Australia
{ lat: -37.8136, lng: 144.9631 }, // Melbourne, Australia
{ lat: -27.4698, lng: 153.0251 }, // Brisbane, Australia
{ lat: -31.9505, lng: 115.8605 }, // Perth, Australia
{ lat: -12.4634, lng: 130.8456 }, // Darwin, Australia
{ lat: -34.9285, lng: 138.6007 }, // Adelaide, Australia
{ lat: -42.8821, lng: 147.3272 }, // Hobart, Australia
{ lat: -16.9186, lng: 145.7781 }, // Cairns, Australia
{ lat: -23.7041, lng: 133.8814 }, // Alice Springs, Australia
{ lat: -41.2865, lng: 174.7762 }, // Wellington, New Zealand
{ lat: -36.8485, lng: 174.7633 }, // Auckland, New Zealand
{ lat: -43.532, lng: 172.6306 }, // Christchurch, New Zealand
];
const getRandomCoordinates = (count: number) => {
const shuffled = [...COORDINATES].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
};
export function WorldMap() {
const [visiblePins, setVisiblePins] = useState<typeof COORDINATES>([
{ lat: 61.2181, lng: -149.9003 },
{ lat: 31.2304, lng: 121.4737 },
{ lat: 59.5613, lng: 150.8086 },
{ lat: 64.8378, lng: -147.7164 },
{ lat: -33.8688, lng: 151.2093 },
{ lat: 43.0621, lng: 141.3544 },
{ lat: 58.3019, lng: -134.4197 },
{ lat: 37.5665, lng: 126.978 },
{ lat: -41.2865, lng: 174.7762 },
{ lat: -36.8485, lng: 174.7633 },
{ lat: -31.9505, lng: 115.8605 },
{ lat: 35.6762, lng: 139.6503 },
{ lat: 49.2827, lng: -123.1207 },
{ lat: -12.4634, lng: 130.8456 },
{ lat: 56.1304, lng: 101.614 },
{ lat: 22.3193, lng: 114.1694 },
{ lat: 55.3422, lng: -131.6461 },
{ lat: 32.7157, lng: -117.1611 },
{ lat: 61.5815, lng: -149.444 },
{ lat: 60.5544, lng: -151.2583 },
]);
const activePinColor = '#2265EC';
const inactivePinColor = '#818181';
const visiblePinsCount = 20;
// Helper function to update pins
const updatePins = () => {
setVisiblePins((current) => {
const newPins = [...current];
// Remove 2 random pins
const pinsToAdd = 4;
if (newPins.length >= pinsToAdd) {
for (let i = 0; i < pinsToAdd; i++) {
const randomIndex = Math.floor(Math.random() * newPins.length);
newPins.splice(randomIndex, 1);
}
}
// Add 2 new random pins from the main coordinates
const availablePins = COORDINATES.filter(
(coord) =>
!newPins.some(
(pin) => pin.lat === coord.lat && pin.lng === coord.lng,
),
);
const newRandomPins = availablePins
.sort(() => 0.5 - Math.random())
.slice(0, pinsToAdd);
return [...newPins, ...newRandomPins].slice(0, visiblePinsCount);
});
};
useEffect(() => {
// Update pins every 4 seconds
const interval = setInterval(updatePins, 4000);
return () => clearInterval(interval);
}, []);
const map = useMemo(() => {
const map = new DottedMap({ map: mapJsonString as any });
visiblePins.forEach((coord) => {
map.addPin({
lat: coord.lat,
lng: coord.lng,
svgOptions: { color: activePinColor, radius: 0.3 },
});
});
return map.getSVG({
radius: 0.2,
color: inactivePinColor,
shape: 'circle',
});
}, [visiblePins]);
return (
<div>
<img
loading="lazy"
alt="World map with active users"
src={`data:image/svg+xml;utf8,${encodeURIComponent(map)}`}
className="object-contain w-full h-full"
width={1200}
height={630}
/>
</div>
);
}

View File

@@ -181,7 +181,7 @@ It might not be the best fit if:
Installing GroupMQ is straightforward: Installing GroupMQ is straightforward:
```bash ```npm
npm install groupmq npm install groupmq
``` ```

View File

@@ -0,0 +1,507 @@
{
"slug": "ackee-alternative",
"page_type": "alternative",
"seo": {
"title": "Ackee Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Ackee Analytics. Discover why teams choose OpenPanel as their Ackee alternative for product analytics, user identification, and scalable analytics while maintaining privacy.",
"noindex": false
},
"hero": {
"heading": "Ackee Alternative",
"subheading": "Love Ackee's privacy-first approach and self-hosting simplicity? OpenPanel adds product analytics capabilities - funnels, cohorts, retention, and user identification - with a modern architecture built for scale.",
"badges": [
"Open-source",
"Privacy-first",
"Product Analytics",
"Self-hostable"
]
},
"competitor": {
"name": "Ackee",
"logo": "/logos/ackee.svg",
"url": "https://ackee.electerious.com",
"short_description": "Minimalist, self-hosted, privacy-focused web analytics with anonymous tracking and a clean interface.",
"founded": 2016,
"headquarters": "Germany"
},
"summary_comparison": {
"title": "OpenPanel vs Ackee: Which is right for you?",
"intro": "Both are privacy-focused open source analytics tools. Ackee focuses on simple web metrics with anonymous tracking. OpenPanel adds product analytics capabilities with user identification.",
"one_liner": "Ackee is ultra-minimal web analytics; OpenPanel adds product analytics features like funnels, retention, and user identification.",
"best_for_openpanel": [
"Teams needing product analytics (funnels, retention, cohorts)",
"Apps requiring user identification and tracking",
"Projects that need to scale with ClickHouse architecture",
"Mobile app analytics with native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Personal blogs and small sites wanting simple stats",
"Privacy maximalists who want zero user identification",
"Developers comfortable with GraphQL API customization",
"Sites that can run on MongoDB for analytics"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Ackee compare on the factors that matter most.",
"items": [
{
"label": "Analytics Depth",
"openpanel": "Web + Product Analytics",
"competitor": "Web Analytics Only",
"notes": "OpenPanel combines web analytics with product analytics - funnels, retention, cohorts, and user profiles. Ackee provides essential web metrics like page views, referrers, and durations."
},
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Ackee intentionally anonymizes all data and cannot track returning users for individual pages."
},
{
"label": "Database Architecture",
"openpanel": "ClickHouse (optimized for analytics)",
"competitor": "MongoDB (general purpose)",
"notes": "OpenPanel uses ClickHouse, purpose-built for analytical queries. Ackee uses MongoDB, which works well for small sites but may struggle with high-volume analytics workloads."
},
{
"label": "Deployment Options",
"openpanel": "Cloud + Self-hosted",
"competitor": "Self-hosted only",
"notes": "OpenPanel offers both managed cloud and self-hosted options. Ackee is self-hosted only - you must run your own server and MongoDB instance."
},
{
"label": "Open Source",
"openpanel": "Yes (MIT License)",
"competitor": "Yes (MIT License)",
"notes": "Both platforms are fully open source under the MIT license, allowing complete code inspection and modification."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are open source and privacy-focused, but with different capabilities and depth.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views",
"openpanel": true,
"competitor": true
},
{
"name": "Referrers",
"openpanel": true,
"competitor": true
},
{
"name": "Visit Duration",
"openpanel": true,
"competitor": true,
"notes": "Ackee tracks duration by updating records constantly"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true,
"notes": "Ackee requires 'detailed' mode for full device info"
},
{
"name": "Screen Sizes",
"openpanel": true,
"competitor": true,
"notes": "Ackee requires 'detailed' mode enabled"
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true,
"notes": "Ackee shows active visitors in real-time"
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Ackee supports custom events with key-value data"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": false,
"notes": "Ackee has no funnel visualization or analysis"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Ackee cannot track returning users by design"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Ackee intentionally anonymizes all user data"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "Ackee's anonymous model doesn't support cohorts"
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": false,
"notes": "Ackee cannot reconstruct user browsing history"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Ackee is analytics-only, no experimentation"
},
{
"name": "GraphQL API",
"openpanel": false,
"competitor": true,
"notes": "Ackee's entire UI is powered by its GraphQL API"
},
{
"name": "REST API",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel uses REST; Ackee uses GraphQL only"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": false,
"notes": "Ackee has no built-in reporting - requires custom tools"
},
{
"name": "Multiple Domains",
"openpanel": true,
"competitor": true,
"notes": "Both support unlimited domains from one instance"
},
{
"name": "Ignore Own Visits",
"openpanel": true,
"competitor": true,
"notes": "Ackee can ignore logged-in dashboard visits"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true,
"notes": "Both are cookieless by default"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true,
"notes": "Ackee uses daily-rotating salt hashes for anonymization"
},
{
"name": "Data Anonymization",
"openpanel": true,
"competitor": true,
"notes": "Ackee uses multi-step anonymization with daily salt rotation"
},
{
"name": "Self-Hosted Option",
"openpanel": true,
"competitor": true,
"notes": "Ackee is self-hosted ONLY; OpenPanel offers both"
},
{
"name": "EU Data Residency",
"openpanel": true,
"competitor": true,
"notes": "Both can be hosted anywhere; Ackee requires self-hosting"
}
]
},
{
"group": "Integrations & SDKs",
"features": [
{
"name": "JavaScript SDK",
"openpanel": true,
"competitor": true,
"notes": "ackee-tracker available via npm or self-served"
},
{
"name": "React Integration",
"openpanel": true,
"competitor": true,
"notes": "use-ackee React hook available"
},
{
"name": "Vue/Nuxt Integration",
"openpanel": true,
"competitor": true,
"notes": "nuxt-ackee module available"
},
{
"name": "Gatsby Plugin",
"openpanel": true,
"competitor": true,
"notes": "gatsby-plugin-ackee-tracker available"
},
{
"name": "Native iOS SDK",
"openpanel": true,
"competitor": false,
"notes": "Ackee is web-focused only"
},
{
"name": "Native Android SDK",
"openpanel": true,
"competitor": false,
"notes": "Ackee has no official mobile SDKs"
},
{
"name": "WordPress Plugin",
"openpanel": true,
"competitor": true,
"notes": "Soapberry plugin available for WordPress"
},
{
"name": "Flutter/Dart SDK",
"openpanel": false,
"competitor": true,
"notes": "ackee_dart community package available"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "~6 KB (gzipped), served from your Ackee instance",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"React (use-ackee)",
"Nuxt.js",
"Vue",
"Gatsby",
"Svelte",
"Angular",
"WordPress",
"Dart/Flutter"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Yes - MIT License",
"notes": "Both are MIT licensed and fully open source"
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Docker with MongoDB required, or deploy to Vercel/Netlify/Heroku with MongoDB Atlas",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse (columnar, analytics-optimized)",
"competitor": "MongoDB (document database)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Unlimited (depends on your MongoDB storage)",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Node.js",
"notes": null
},
{
"label": "API",
"openpanel": "REST API",
"competitor": "GraphQL API",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Both offer free self-hosting. OpenPanel also offers managed cloud options.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "100% Free (self-hosted only)",
"description": "Completely free - no paid tiers exist. You pay only for your own infrastructure (MongoDB and server hosting). MongoDB Atlas free tier (512MB) works for small sites.",
"free_tier": "Self-hosted: Free forever, no paid option",
"pricing_url": null
}
},
"migration": {
"title": "Migrating from Ackee to OpenPanel",
"intro": "Switching from Ackee to OpenPanel is straightforward. Both are lightweight with similar integration approaches.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Replace the ackee-tracker script with OpenPanel's lightweight tracking code."
},
{
"title": "Map Events to OpenPanel",
"description": "Ackee events translate to OpenPanel events. Replace instance.action() calls with op.track() - the structure is similar."
},
{
"title": "Add User Identification (New)",
"description": "Unlike Ackee, OpenPanel can identify users. Add op.identify() calls to unlock retention, cohorts, and user profiles - a major upgrade from Ackee's anonymous-only model."
},
{
"title": "Configure Dashboards",
"description": "Set up your OpenPanel dashboards. You'll now have access to funnels, retention charts, and cohort analysis that weren't possible in Ackee."
},
{
"title": "Remove Ackee",
"description": "Once verified, remove the Ackee tracker script and optionally decommission your Ackee server and MongoDB instance."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use simple event tracking APIs. Ackee's instance.action() becomes OpenPanel's op.track()."
},
"historical_data": {
"can_import": false,
"notes": "Ackee intentionally anonymizes data, making historical import challenging. Most teams start fresh with OpenPanel."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Ackee",
"intro": "Choose OpenPanel when you need more than simple web stats - funnels, retention, user identification, and scalability.",
"items": [
{
"title": "Scaling Beyond MongoDB",
"description": "Ackee uses MongoDB which works for small sites but isn't optimized for analytical queries at scale. OpenPanel's ClickHouse backend is purpose-built for analytics workloads.",
"icon": "trending-up"
},
{
"title": "Teams Needing Product Analytics",
"description": "Ackee provides basic web metrics. If you need funnels, retention analysis, cohort breakdowns, or user journey mapping, OpenPanel adds these capabilities while maintaining privacy.",
"icon": "bar-chart"
},
{
"title": "Wanting a Cloud Option",
"description": "Ackee is self-hosted only with no managed cloud option. If you want analytics without managing servers, MongoDB, and backups, OpenPanel offers a free cloud tier.",
"icon": "cloud"
},
{
"title": "Apps Requiring User Identification",
"description": "Ackee intentionally cannot identify users or track returning visitors. If you need to understand individual user behavior or measure retention, OpenPanel provides these features.",
"icon": "user-check"
},
{
"title": "Mobile App Analytics",
"description": "Ackee is designed for websites with no official mobile SDKs. OpenPanel offers native SDKs for iOS, Android, and React Native with full product analytics capabilities.",
"icon": "smartphone"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Ackee to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Ackee?",
"answer": "Yes! Both are cookie-free by default and can be GDPR compliant without consent banners. The key difference is that OpenPanel allows optional user identification for product analytics, while Ackee is strictly anonymous. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Ackee to OpenPanel?",
"answer": "Teams typically switch when they need: product analytics (funnels, retention, cohorts), user identification, a managed cloud option, mobile SDKs, or a database optimized for analytics. Ackee excels at simple, anonymous web stats but lacks these capabilities."
},
{
"question": "Is Ackee really free?",
"answer": "Yes, Ackee itself is 100% free and open source. However, you must pay for your own hosting - a server to run Ackee and MongoDB. Using free tiers (Vercel + MongoDB Atlas 512MB), you can run Ackee at zero cost for small sites."
},
{
"question": "Does OpenPanel have a GraphQL API like Ackee?",
"answer": "No, OpenPanel uses a REST API while Ackee uses GraphQL. Both approaches allow building custom tools and integrations. Ackee's entire UI is powered by its GraphQL API, making it very extensible."
},
{
"question": "Can Ackee track mobile apps?",
"answer": "Not officially. Ackee is designed for web analytics. There's a community Dart/Flutter package, but no official iOS or Android SDKs. OpenPanel offers native mobile SDKs with full product analytics."
},
{
"question": "What will I lose switching from Ackee?",
"answer": "Ackee's GraphQL API (OpenPanel uses REST), the ability to host on platforms like Vercel/Netlify as serverless functions, and the community plugins like Svelte and Angular integrations. You'll gain product analytics, user identification, and a managed cloud option."
},
{
"question": "How does the database compare?",
"answer": "Ackee uses MongoDB (general-purpose document database) while OpenPanel uses ClickHouse (columnar database optimized for analytics). ClickHouse is significantly faster for analytical queries, especially at scale."
},
{
"question": "Can Ackee track unique visitors?",
"answer": "Yes, but with limitations. Ackee uses a daily-rotating salt hash (IP + user-agent + domain + salt) to identify visitors within a single day. It cannot track returning visitors across days or track unique views per page - this is by design for privacy."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,470 @@
{
"slug": "amplitude-alternative",
"page_type": "alternative",
"seo": {
"title": "Amplitude alternative",
"description": "Compare OpenPanel with Amplitude: open-source, privacy-first analytics with a lighter SDK. Get web and product analytics without the complexity or enterprise pricing.",
"noindex": false
},
"hero": {
"heading": "Amplitude alternative",
"subheading": "OpenPanel is an open-source, privacy-first alternative to Amplitude. Get powerful product analytics with web analytics built in, cookie-free tracking, and the freedom to self-host or use our cloud.",
"badges": [
"Open-source",
"Cookie-free",
"EU-only hosting",
"Self-hostable"
]
},
"competitor": {
"name": "Amplitude",
"logo": "/logos/amplitude.svg",
"url": "https://amplitude.com",
"short_description": "Enterprise digital analytics platform for product teams, offering behavioral analytics, experimentation, and customer data management.",
"founded": 2012,
"headquarters": "San Francisco, CA"
},
"summary_comparison": {
"title": "OpenPanel vs Amplitude: Which is right for you?",
"intro": "Both platforms help product teams understand user behavior. The key differences are pricing model, complexity, privacy approach, and deployment options.",
"one_liner": "OpenPanel is simpler, open-source, and privacy-focused; Amplitude is an enterprise-grade platform with a steep learning curve.",
"best_for_openpanel": [
"Teams that want powerful analytics without enterprise complexity",
"Privacy-conscious organizations that need cookie-free tracking",
"Developers who want to self-host or need a lightweight SDK",
"Startups and SMBs looking for transparent, predictable pricing"
],
"best_for_competitor": [
"Large enterprises with dedicated analytics teams",
"Organizations that need advanced experimentation and feature flags",
"Teams requiring sophisticated behavioral cohorts and predictive analytics",
"Companies wanting an all-in-one platform with session replay and guides"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Amplitude compare on the factors that matter most.",
"items": [
{
"label": "Price",
"openpanel": "From $2.50/month (or free self-hosted)",
"competitor": "Free tier (50K MTUs), then $49+/month"
},
{
"label": "Cookies required",
"openpanel": "No (cookie-free by default)",
"competitor": "Yes (first-party cookies)"
},
{
"label": "Consent banner needed",
"openpanel": "No",
"competitor": "Yes (for GDPR/ePrivacy)"
},
{
"label": "Data location",
"openpanel": "EU-only (or your own servers)",
"competitor": "US or EU (Frankfurt)"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel combines web analytics with product analytics in a simpler interface. Amplitude focuses on deep behavioral analytics for enterprise product teams.",
"groups": [
{
"group": "Web analytics",
"features": [
{
"name": "Page views & visitors",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Traffic sources",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Geographic data",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Device & browser stats",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "UTM tracking",
"openpanel": true,
"competitor": true,
"notes": "Amplitude has advanced marketing attribution"
},
{
"name": "Real-time dashboard",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Product analytics",
"features": [
{
"name": "Custom event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": "Amplitude has advanced conversion funnels"
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": "Amplitude has multiple retention views"
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": "Amplitude has behavioral and predictive cohorts"
},
{
"name": "Revenue tracking",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": true,
"notes": "Amplitude Experiment is full-featured"
},
{
"name": "Feature flags",
"openpanel": false,
"competitor": true,
"notes": "Amplitude includes unlimited feature flags"
},
{
"name": "Session replay",
"openpanel": false,
"competitor": true,
"notes": "Included in Amplitude platform"
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Pathfinder/Journey maps",
"openpanel": true,
"competitor": true,
"notes": "Amplitude pathfinder is highly advanced"
},
{
"name": "Predictive analytics",
"openpanel": false,
"competitor": true,
"notes": "Amplitude has ML-powered predictions (Growth+)"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Cookie-free tracking",
"openpanel": true,
"competitor": false,
"notes": "Amplitude uses first-party cookies"
},
{
"name": "No consent banner needed",
"openpanel": true,
"competitor": false,
"notes": "Amplitude requires consent under GDPR"
},
{
"name": "EU data residency",
"openpanel": true,
"competitor": true,
"notes": "Amplitude offers EU data center in Frankfurt"
},
{
"name": "IP anonymization",
"openpanel": true,
"competitor": true,
"notes": "Amplitude can disable IP storage"
},
{
"name": "Self-hosting option",
"openpanel": true,
"competitor": false,
"notes": "Amplitude is cloud-only"
},
{
"name": "DPA available",
"openpanel": "on request",
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": "Amplitude supports S3, Snowflake, BigQuery"
},
{
"name": "CDP integrations",
"openpanel": true,
"competitor": true,
"notes": "Amplitude has its own CDP product"
},
{
"name": "Webhook notifications",
"openpanel": true,
"competitor": true,
"notes": null
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the SDKs and technical implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~36 KB gzipped (analytics only), ~96 KB unified",
"notes": "Amplitude's unified SDK includes analytics, experiment, session replay, and guides"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Node.js",
"Python",
"Swift",
"Kotlin",
"React Native",
"Astro",
"Remix",
"Express"
],
"competitor": [
"JavaScript",
"TypeScript",
"React Native",
"iOS",
"Android",
"Flutter",
"Unity",
"Node.js",
"Python",
"Go",
"JRE/Java"
],
"notes": "Both have comprehensive SDK coverage"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No (SDKs are open, platform is not)",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup script",
"competitor": "Not available",
"notes": "Amplitude is cloud-only"
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary (AWS-hosted)",
"notes": "OpenPanel gives you direct SQL access to your data"
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted) or plan-based",
"competitor": "Unlimited storage, 3-year query limit on charts",
"notes": "Amplitude stores data but limits chart date ranges"
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Amplitude has a free tier but pricing scales quickly. OpenPanel offers simpler, more predictable costs.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing starting at $2.50/month for 5,000 events. 100,000 events costs $20/month. Self-host for free with unlimited events. No limits on users, dashboards, or data retention."
},
"competitor": {
"model": "MTU-based with event limits",
"description": "Starter (Free): Up to 50K MTUs and 10M events. Plus: $49-1,000+/month based on MTUs (1K-300K). Growth: Custom pricing, typically $22K-254K/year. Enterprise: Custom pricing for large organizations. Overages charged at 1.2x rate.",
"free_tier": "Yes (50K MTUs, limited features)",
"pricing_url": "https://amplitude.com/pricing"
}
},
"migration": {
"title": "Migrating from Amplitude to OpenPanel",
"intro": "Switching from Amplitude to OpenPanel is straightforward. The event tracking APIs are similar, and you can run both tools in parallel during transition.",
"difficulty": "easy",
"estimated_time": "2-4 hours",
"steps": [
{
"title": "Install the OpenPanel SDK",
"description": "Add the lightweight OpenPanel SDK to your app. At 2.3 KB, it's significantly smaller than Amplitude's SDK."
},
{
"title": "Map your events",
"description": "Review your Amplitude tracking plan and map events to OpenPanel. The track() API is similar: amplitude.track('event') becomes op.track('event')."
},
{
"title": "Configure user identification",
"description": "Set up user identification in OpenPanel. The identify() method works similarly to Amplitude's."
},
{
"title": "Set up dashboards",
"description": "Create your key reports in OpenPanel. While you'll lose Amplitude's advanced features like predictive cohorts, core analytics translate directly."
},
{
"title": "Run in parallel and validate",
"description": "Keep both tools running for a week to compare data and ensure accuracy before removing Amplitude."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with similar APIs. amplitude.track('Purchase', {amount: 99}) becomes op.track('Purchase', {amount: 99})."
},
"historical_data": {
"can_import": false,
"notes": "Amplitude data export is available for paid plans but requires manual transformation. Most teams start fresh with OpenPanel."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Amplitude",
"intro": "OpenPanel shines for teams that want powerful analytics without enterprise complexity, pricing, or privacy concerns.",
"items": [
{
"title": "Startups and growing teams",
"description": "Get the product analytics you need without Amplitude's complexity or enterprise pricing. Start free and scale predictably.",
"icon": "rocket"
},
{
"title": "Privacy-first products",
"description": "Cookie-free tracking means no consent banners and happier users. Perfect for GDPR compliance without compromise.",
"icon": "shield"
},
{
"title": "Self-hosted requirements",
"description": "Deploy OpenPanel on your own infrastructure for complete data ownership. Amplitude is cloud-only with no self-hosting option.",
"icon": "server"
},
{
"title": "Faster websites and apps",
"description": "OpenPanel's 2.3 KB SDK vs Amplitude's 36-96 KB means better performance, faster loads, and improved user experience.",
"icon": "zap"
},
{
"title": "Simpler analytics needs",
"description": "If you don't need predictive ML models, feature flags, or session replay, OpenPanel gives you core analytics without the bloat.",
"icon": "target"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Amplitude to OpenPanel.",
"items": [
{
"question": "Is Amplitude free?",
"answer": "Amplitude offers a free Starter plan with up to 50,000 Monthly Tracked Users (MTUs) and 10 million events. However, it has limited features, no customer support, and you'll need to upgrade quickly as you grow. The Plus plan starts at $49/month for just 1,000 MTUs."
},
{
"question": "Why switch from Amplitude?",
"answer": "Common reasons include: pricing that escalates quickly as you grow, complexity that requires dedicated analysts to use effectively, privacy concerns with cookies and consent requirements, no self-hosting option, and a heavy SDK that impacts page performance."
},
{
"question": "Do I need a cookie consent banner with OpenPanel?",
"answer": "No. OpenPanel is cookie-free by default and doesn't collect personal data, so no consent banner is required for analytics. Amplitude requires cookies and therefore needs consent under GDPR."
},
{
"question": "Does Amplitude offer EU data hosting?",
"answer": "Yes, Amplitude has an EU data center in Frankfurt, Germany. However, you still need cookie consent because Amplitude uses first-party cookies. OpenPanel offers EU-only hosting plus cookie-free tracking."
},
{
"question": "What Amplitude features will I lose?",
"answer": "OpenPanel doesn't have feature flags, session replay, predictive cohorts, or the Guides & Surveys product. If you rely heavily on these enterprise features, Amplitude may still be the better fit."
},
{
"question": "How does the SDK size affect my app?",
"answer": "OpenPanel's JavaScript SDK is ~2.3 KB gzipped compared to Amplitude's 36 KB (analytics only) or 96 KB (unified). This means faster initial page loads, better Core Web Vitals, and reduced bandwidth costs."
},
{
"question": "Can I import my Amplitude data?",
"answer": "Amplitude allows data export on paid plans (to S3, Snowflake, etc.), but there's no direct import into OpenPanel. Most teams run both tools briefly in parallel, then start fresh with OpenPanel."
},
{
"question": "Is OpenPanel as powerful as Amplitude?",
"answer": "OpenPanel covers core product analytics (events, funnels, retention, cohorts, user profiles) and adds web analytics. Amplitude has more advanced features like predictive analytics and feature flags, but many teams don't need that complexity."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,426 @@
{
"slug": "appsflyer-alternative",
"page_type": "alternative",
"seo": {
"title": "AppsFlyer Alternative",
"description": "Compare OpenPanel with AppsFlyer: pricing, features, and focus. OpenPanel provides product analytics; AppsFlyer specializes in mobile attribution.",
"noindex": false
},
"hero": {
"heading": "AppsFlyer alternative",
"subheading": "Need to understand user behavior, not just ad attribution? OpenPanel provides product analytics—funnels, retention, cohorts, and user profiles—at a fraction of AppsFlyer's cost, without complex enterprise contracts.",
"badges": [
"Product analytics",
"Self-hostable",
"Transparent pricing",
"Open-source"
]
},
"competitor": {
"name": "AppsFlyer",
"logo": "/logos/appsflyer.svg",
"url": "https://www.appsflyer.com",
"short_description": "Mobile Measurement Partner (MMP) focused on attributing app installs to marketing campaigns with fraud protection.",
"founded": 2011,
"headquarters": "San Francisco, CA"
},
"summary_comparison": {
"title": "OpenPanel vs AppsFlyer: Which is right for you?",
"intro": "These tools serve different primary purposes. AppsFlyer focuses on mobile attribution (which ad drove an install); OpenPanel focuses on product analytics (what users do in your app).",
"one_liner": "OpenPanel is for product analytics and user behavior; AppsFlyer is for mobile attribution and marketing measurement.",
"best_for_openpanel": [
"Product teams needing user behavior analytics and funnels",
"Startups seeking affordable analytics without enterprise pricing",
"Teams wanting self-hosted analytics for data ownership",
"Web-first products and SaaS applications",
"Open source preference for transparency and auditability"
],
"best_for_competitor": [
"Mobile marketers needing install attribution",
"Teams requiring multi-touch attribution across ad networks",
"Apps needing deep linking and deferred deep linking",
"Mobile games requiring SKAdNetwork support",
"Organizations needing fraud protection for ad spend"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and AppsFlyer compare on the factors that matter most.",
"items": [
{
"label": "Primary focus",
"openpanel": "Product analytics",
"competitor": "Mobile attribution"
},
{
"label": "Pricing model",
"openpanel": "Simple event-based",
"competitor": "Per-conversion + add-ons"
},
{
"label": "Self-hosting",
"openpanel": "Yes, with Docker",
"competitor": "No (cloud only)"
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary)"
},
{
"label": "Ad network integrations",
"openpanel": "Limited",
"competitor": "5,000+ partners"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel and AppsFlyer serve different primary needs—product analytics vs mobile attribution.",
"groups": [
{
"group": "Product analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": false,
"notes": "AppsFlyer has attribution funnels, not product funnels"
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": "AppsFlyer offers for LTV analysis"
},
{
"name": "User path analysis",
"openpanel": true,
"competitor": false,
"notes": null
}
]
},
{
"group": "Mobile attribution",
"features": [
{
"name": "Install attribution",
"openpanel": false,
"competitor": true,
"notes": "AppsFlyer's core feature"
},
{
"name": "Multi-touch attribution",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Deep linking",
"openpanel": false,
"competitor": true,
"notes": "AppsFlyer OneLink"
},
{
"name": "SKAdNetwork support",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Uninstall tracking",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "Fraud protection",
"openpanel": false,
"competitor": true,
"notes": "AppsFlyer Protect360"
},
{
"name": "A/B testing",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Audience segmentation",
"openpanel": true,
"competitor": true,
"notes": "AppsFlyer Audiences is premium add-on"
},
{
"name": "Cost aggregation",
"openpanel": false,
"competitor": true,
"notes": "AppsFlyer Xpend"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data residency options",
"openpanel": "Via self-hosting",
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Mobile SDKs",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Ad network integrations",
"openpanel": false,
"competitor": true,
"notes": "5,000+ marketing partners"
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": "AppsFlyer Data Locker is premium"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (mobile)",
"openpanel": "~2.3 KB for web",
"competitor": "Lightweight (<1% app size)",
"notes": "Both maintain small SDK footprints"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python"
],
"competitor": [
"iOS",
"Android",
"Unity",
"React Native",
"Flutter",
"Web",
"Smart TV",
"CTV/OTT"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers simple event-based pricing. AppsFlyer uses per-conversion pricing with expensive add-ons.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Per-conversion with add-ons",
"description": "Zero plan: 12K lifetime conversions free. Growth: $0.05-0.07/conversion. Enterprise: ~$0.03/conversion. Premium add-ons (fraud protection, data locker) cost extra. Enterprise contracts typically $3,000-$100,000+ annually.",
"free_tier": "Yes (12K lifetime conversions)",
"pricing_url": "https://www.appsflyer.com/pricing"
}
},
"migration": {
"title": "Migrating from AppsFlyer to OpenPanel",
"intro": "Consider whether you need attribution (AppsFlyer) or product analytics (OpenPanel). Many teams use both.",
"difficulty": "moderate",
"estimated_time": "1-2 days for basic setup",
"steps": [
{
"title": "Assess your needs",
"description": "Determine if you need mobile attribution (AppsFlyer's strength) or product analytics (OpenPanel's strength). Many teams use both tools."
},
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK alongside or instead of AppsFlyer. Available for iOS, Android, React Native, and web."
},
{
"title": "Map events",
"description": "Translate your AppsFlyer in-app events to OpenPanel events. Both use similar event-tracking patterns."
},
{
"title": "Set up user identification",
"description": "OpenPanel provides detailed user profiles and journey tracking. Add identify() calls to unlock retention and cohort analytics."
},
{
"title": "Configure product analytics",
"description": "Set up funnels, retention charts, and dashboards in OpenPanel—features not available in AppsFlyer."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use standard event tracking APIs. OpenPanel focuses on product analytics; AppsFlyer on attribution."
},
"historical_data": {
"can_import": false,
"notes": "Attribution data from AppsFlyer typically doesn't need migration if using OpenPanel for product analytics."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than AppsFlyer",
"intro": "OpenPanel excels when you need product analytics rather than mobile attribution.",
"items": [
{
"title": "Product teams needing behavior analytics",
"description": "AppsFlyer tells you which ad brought a user. OpenPanel tells you what that user does in your product—funnels, feature usage, retention patterns.",
"icon": "chart"
},
{
"title": "Startups seeking affordable analytics",
"description": "AppsFlyer's pricing can reach tens of thousands monthly. OpenPanel offers a generous free tier and simple pricing without expensive add-ons.",
"icon": "dollar"
},
{
"title": "Teams wanting self-hosted analytics",
"description": "AppsFlyer is cloud-only. OpenPanel can be self-hosted with Docker for complete data ownership and compliance requirements.",
"icon": "server"
},
{
"title": "Web-first products",
"description": "AppsFlyer is designed primarily for mobile attribution. OpenPanel works equally well for web, SaaS, and mobile apps.",
"icon": "globe"
},
{
"title": "Open source preference",
"description": "If you value transparency and auditability, OpenPanel's open source codebase provides what AppsFlyer's proprietary system cannot.",
"icon": "code"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about AppsFlyer and OpenPanel.",
"items": [
{
"question": "Are AppsFlyer and OpenPanel competitors?",
"answer": "They solve different problems. AppsFlyer is a Mobile Measurement Partner (MMP) focused on attributing app installs to marketing campaigns. OpenPanel is a product analytics platform focused on understanding user behavior within your product. Many companies use both."
},
{
"question": "Can OpenPanel replace AppsFlyer?",
"answer": "It depends on your needs. If you primarily need mobile attribution (knowing which ad campaign drove an install), you need an MMP like AppsFlyer. If you need product analytics (understanding what users do in your app), OpenPanel is the better choice."
},
{
"question": "Why is AppsFlyer so expensive?",
"answer": "AppsFlyer charges per attributed conversion ($0.05-0.07 on Growth plan) plus premium add-ons for fraud protection, raw data access, and audience segmentation. Enterprise contracts can cost $50,000-$100,000+ annually. This pricing reflects their position as the market-leading MMP."
},
{
"question": "Does OpenPanel have fraud protection like AppsFlyer?",
"answer": "No. Fraud protection is specific to mobile attribution—detecting fake installs and click fraud. Since OpenPanel focuses on product analytics rather than attribution, fraud protection isn't applicable."
},
{
"question": "Can OpenPanel do deep linking like AppsFlyer?",
"answer": "No. Deep linking (routing users from ads/web to specific app content) is an attribution feature. OpenPanel focuses on analytics after users are in your product."
},
{
"question": "Which is better for mobile games?",
"answer": "For user acquisition attribution and ad monetization tracking, AppsFlyer (or similar MMPs) is essential. For understanding player behavior, progression funnels, and retention, OpenPanel provides the product analytics that AppsFlyer lacks. Mobile game studios typically use both."
},
{
"question": "Can I self-host AppsFlyer?",
"answer": "No. AppsFlyer is a cloud-only SaaS platform with no self-hosting option. OpenPanel can be fully self-hosted using Docker."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,478 @@
{
"slug": "cabin-analytics-alternative",
"page_type": "alternative",
"seo": {
"title": "Cabin Analytics Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Cabin Analytics. Discover why teams choose OpenPanel as their Cabin alternative for deeper product analytics, self-hosting, and mobile SDKs while maintaining environmental responsibility.",
"noindex": false
},
"hero": {
"heading": "Cabin Analytics alternative",
"subheading": "Love Cabin's carbon-conscious approach and privacy focus? OpenPanel adds deeper product analytics—self-hosting, mobile SDKs, user identification, funnels, and retention analysis—while staying open source and lightweight.",
"badges": [
"Open-source",
"Self-hostable",
"Mobile SDKs",
"Product analytics"
]
},
"competitor": {
"name": "Cabin Analytics",
"logo": "/logos/cabin.svg",
"url": "https://withcabin.com",
"short_description": "Privacy-first, carbon-conscious web analytics alternative to Google Analytics with ultra-lightweight tracking.",
"founded": 2020,
"headquarters": "London, UK"
},
"summary_comparison": {
"title": "OpenPanel vs Cabin: Which is right for you?",
"intro": "Both platforms prioritize privacy and lightweight tracking. The key differences are depth of analytics, self-hosting capabilities, and platform support.",
"one_liner": "Cabin is simpler and carbon-conscious for web analytics; OpenPanel offers deeper product analytics with mobile SDKs and self-hosting.",
"best_for_openpanel": [
"Teams requiring self-hosting for data ownership and compliance",
"SaaS products needing user-level analytics and retention tracking",
"Mobile app analytics with native iOS and Android SDKs",
"Teams needing funnel analysis and cohort tracking",
"Products requiring A/B testing capabilities"
],
"best_for_competitor": [
"Teams prioritizing carbon footprint tracking and environmental responsibility",
"Simple web analytics without user identification requirements",
"Ultra-lightweight tracking (1KB script) for performance",
"Projects needing renewable energy hosting",
"Teams wanting flat pricing regardless of traffic"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Cabin compare on the factors that matter most.",
"items": [
{
"label": "Self-hosting",
"openpanel": "Yes, completely free",
"competitor": "No (cloud only)"
},
{
"label": "Product analytics",
"openpanel": "Funnels, retention, cohorts",
"competitor": "Web analytics only"
},
{
"label": "User identification",
"openpanel": "Yes, track individual users",
"competitor": "No (anonymous only)"
},
{
"label": "Mobile SDKs",
"openpanel": "iOS, Android, React Native",
"competitor": "Web only"
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "Partial (client only)"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel covers product analytics and web analytics, while Cabin focuses on simple web metrics with unique carbon tracking.",
"groups": [
{
"group": "Web analytics",
"features": [
{
"name": "Page views & visitors",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Traffic sources",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Geographic data",
"openpanel": true,
"competitor": true,
"notes": "OpenPanel offers country, region, city. Cabin country only"
},
{
"name": "Device & browser stats",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "UTM tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": false,
"notes": "Cabin doesn't offer real-time monitoring"
},
{
"name": "Bounce rate",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Page load time",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Product analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": "Cabin custom events require Pro plan"
},
{
"name": "Funnels",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": false,
"notes": "Cabin is anonymous only"
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "User identification",
"openpanel": true,
"competitor": false,
"notes": "Cabin is strictly anonymous by design"
},
{
"name": "User path analysis",
"openpanel": true,
"competitor": false,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Carbon footprint tracking",
"openpanel": false,
"competitor": true,
"notes": "Unique Cabin feature"
},
{
"name": "Renewable energy hosting",
"openpanel": false,
"competitor": true,
"notes": "Cabin runs on 100% renewable energy"
},
{
"name": "Custom properties",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Public dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Email reports",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Cookie-free tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "CCPA compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "No IP tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "No consent banner required",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Cabin API requires Pro plan"
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Mobile SDKs",
"openpanel": true,
"competitor": false,
"notes": "Cabin is web-only"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~1 KB gzipped",
"notes": "Cabin has the lighter script"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Nuxt",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go"
],
"competitor": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Nuxt",
"SvelteKit",
"Astro",
"Hugo",
"Ghost"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "Partial (client only)",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary",
"notes": null
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted)",
"competitor": "30 days free, unlimited Pro",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Both offer generous free tiers with different pricing models—event-based vs flat monthly.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. No limits on users, dashboards, or features at any tier."
},
"competitor": {
"model": "Flat monthly pricing",
"description": "Free tier: 1 website, 30-day retention, unlimited pageviews. Pro: $19/month for unlimited sites, unlimited retention, custom events, API access.",
"free_tier": "Yes (1 site, 30-day retention)",
"pricing_url": "https://withcabin.com/pricing"
}
},
"migration": {
"title": "Migrating from Cabin to OpenPanel",
"intro": "Switching from Cabin to OpenPanel is straightforward for basic tracking, with added capabilities for product analytics.",
"difficulty": "easy",
"estimated_time": "30 minutes to 1 hour",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. The script is slightly larger (~2.3KB) but still lightweight."
},
{
"title": "Map custom events",
"description": "If you use Cabin custom events (Pro), translate them to OpenPanel format. cabin.event('signup') becomes op.track('signup', {properties})."
},
{
"title": "Add user identification",
"description": "Unlike Cabin which is anonymous, OpenPanel supports user identification. Add op.identify() calls to unlock user profiles and retention analysis."
},
{
"title": "Set up funnels and retention",
"description": "Create funnels and retention reports in OpenPanel—features not available in Cabin."
},
{
"title": "Remove Cabin script",
"description": "Once verified, remove the Cabin tracking script. Both are cookie-free so no consent flow changes needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use similar event tracking patterns. OpenPanel adds user identification capabilities not available in Cabin."
},
"historical_data": {
"can_import": false,
"notes": "Cabin doesn't provide data export on the free plan. Historical data migration requires Pro plan export."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Cabin",
"intro": "OpenPanel shines when you need deeper product analytics and platform flexibility beyond simple web tracking.",
"items": [
{
"title": "Teams requiring self-hosting",
"description": "Cabin is cloud-only. If you need data on your own infrastructure for compliance or security, OpenPanel provides full self-hosting with Docker.",
"icon": "server"
},
{
"title": "SaaS products needing user-level analytics",
"description": "Cabin anonymizes all visitors. If you need to track logged-in users, analyze retention, or build cohorts, OpenPanel provides these capabilities.",
"icon": "users"
},
{
"title": "Mobile app analytics",
"description": "Cabin is web-only. OpenPanel provides native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams needing funnel analysis",
"description": "Track user flows through signup, onboarding, or purchase processes with OpenPanel's funnel analysis.",
"icon": "chart"
},
{
"title": "Products requiring A/B testing",
"description": "OpenPanel includes built-in experimentation capabilities. Cabin is analytics-only.",
"icon": "flask"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Cabin to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Cabin?",
"answer": "Both are cookie-free by default and GDPR/CCPA compliant. The key difference is that OpenPanel allows optional user identification for product analytics, while Cabin is strictly anonymous. Cabin stores data exclusively in the EU; OpenPanel lets you choose with self-hosting."
},
{
"question": "Why switch from Cabin to OpenPanel?",
"answer": "Teams typically switch when they need self-hosting, user identification, mobile SDKs, funnel analysis, or retention tracking. Cabin excels at simple, anonymous web analytics with carbon tracking, but if you need deeper product insights, OpenPanel provides these capabilities."
},
{
"question": "Does OpenPanel track carbon footprint like Cabin?",
"answer": "No. Carbon footprint tracking is a unique Cabin feature. If environmental impact tracking is critical for your organization, you may want to keep Cabin or use another tool for this specific capability."
},
{
"question": "Which has the smaller tracking script?",
"answer": "Cabin's script is smaller at approximately 1KB (77x smaller than Google Analytics). OpenPanel's script is 2.3KB gzipped. Both are significantly lighter than traditional analytics tools."
},
{
"question": "Can I self-host Cabin?",
"answer": "No. Cabin is cloud-only with no self-hosting option. Your data is always stored on their EU servers. OpenPanel offers full self-hosting with Docker if you need data on your own infrastructure."
},
{
"question": "How does pricing compare?",
"answer": "Cabin uses flat pricing: Free (1 site, 30-day retention) or $19/month Pro (unlimited sites and retention). OpenPanel uses event-based pricing with 10,000 free events/month. For high-traffic sites, Cabin's flat fee may be more cost-effective."
},
{
"question": "Does Cabin support mobile apps?",
"answer": "No. Cabin is web-only with no mobile SDKs. OpenPanel provides native iOS, Android, and React Native SDKs for mobile app analytics."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,518 @@
{
"slug": "countly-alternative",
"page_type": "alternative",
"seo": {
"title": "Countly Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Countly. Discover why teams choose OpenPanel as their Countly alternative for simpler pricing, lighter weight, and modern product analytics while maintaining privacy and self-hosting options.",
"noindex": false
},
"hero": {
"heading": "Countly Alternative",
"subheading": "Want Countly's product analytics without the complexity? OpenPanel offers a simpler, more affordable approach to user analytics with self-hosting, mobile SDKs, and modern product analytics - all with transparent pricing.",
"badges": [
"Open-source",
"Simple Pricing",
"Lightweight",
"MIT License"
]
},
"competitor": {
"name": "Countly",
"logo": "/logos/countly.svg",
"url": "https://countly.com",
"short_description": "All-in-one product analytics platform with engagement features like push notifications, crash reporting, and surveys.",
"founded": 2013,
"headquarters": "London, UK"
},
"summary_comparison": {
"title": "OpenPanel vs Countly: Which is right for you?",
"intro": "Both offer product analytics with self-hosting. Countly is an all-in-one platform with many features. OpenPanel focuses on analytics with simpler pricing.",
"one_liner": "Countly is an all-in-one platform with push/crash features; OpenPanel focuses purely on analytics with simpler pricing.",
"best_for_openpanel": [
"Teams wanting simple analytics without push notifications or crash reporting",
"Startups needing affordable, predictable event-based pricing",
"Developers wanting true open source (MIT) without commercial restrictions",
"Teams preferring lightweight Docker deployment over MongoDB setup"
],
"best_for_competitor": [
"Mobile apps needing push notifications and crash reporting in one platform",
"Teams requiring remote configuration and in-app messaging",
"Enterprise customers needing ISO 27001 and SOC2 certifications",
"Products needing Flutter, Unity, or desktop (Windows/Mac) SDKs"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Countly compare on key factors.",
"items": [
{
"label": "Pricing Model",
"openpanel": "Event-based (10K free/month)",
"competitor": "MAU-based (starts at $80/month for 2K MAUs)",
"notes": "OpenPanel offers simple event-based pricing with 10,000 free events/month. Countly Flex charges by Monthly Active Users starting at $80/month for 2,000 MAUs, which can get expensive quickly."
},
{
"label": "Open Source License",
"openpanel": "MIT License (fully permissive)",
"competitor": "AGPL-3.0 (copyleft, non-commercial use only)",
"notes": "OpenPanel uses the permissive MIT license allowing any commercial use. Countly Lite uses AGPL-3.0 with modified terms that prohibit commercial use - you must purchase Enterprise for business use."
},
{
"label": "Setup Complexity",
"openpanel": "Simple Docker deployment",
"competitor": "Complex (MongoDB, Node.js, Nginx)",
"notes": "OpenPanel runs in a simple Docker container. Countly requires MongoDB, Node.js, and Nginx with a more complex installation process and upgrade path."
},
{
"label": "Push Notifications",
"openpanel": "Not built-in",
"competitor": "Built-in rich push notifications",
"notes": "Countly includes rich, interactive push notifications for iOS and Android as a core feature. OpenPanel focuses on analytics and doesn't include push notification functionality."
},
{
"label": "Crash Analytics",
"openpanel": "Not built-in",
"competitor": "Full crash reporting with symbolication",
"notes": "Countly provides comprehensive crash and error reporting with symbolication support across all platforms. OpenPanel focuses on product analytics rather than crash reporting."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Countly is an all-in-one platform. OpenPanel focuses purely on analytics.",
"groups": [
{
"group": "Core Analytics",
"features": [
{
"name": "Page Views & Sessions",
"openpanel": true,
"competitor": true
},
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "User Identification",
"openpanel": true,
"competitor": true,
"notes": "Both support user profiles and identification"
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "Both offer country and city-level data"
},
{
"name": "Device & Platform Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
},
{
"name": "Custom Dashboards",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true,
"notes": "Countly calls this 'Funnels' plugin"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": true
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": true,
"notes": "Countly has advanced behavioral cohorts"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": true
},
{
"name": "User Flows/Journeys",
"openpanel": true,
"competitor": true,
"notes": "Countly has 'Flows' feature for journey visualization"
},
{
"name": "A/B Testing",
"openpanel": true,
"competitor": true,
"notes": "Countly A/B testing tied to Remote Config"
},
{
"name": "Revenue Analytics",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Engagement Features",
"features": [
{
"name": "Push Notifications",
"openpanel": false,
"competitor": true,
"notes": "Countly has rich, interactive push for iOS/Android"
},
{
"name": "In-App Messaging",
"openpanel": false,
"competitor": true
},
{
"name": "Surveys & NPS",
"openpanel": false,
"competitor": true,
"notes": "Countly includes surveys, ratings, and NPS"
},
{
"name": "Remote Configuration",
"openpanel": false,
"competitor": true,
"notes": "Countly can change app behavior remotely"
},
{
"name": "Automated Workflows",
"openpanel": false,
"competitor": true,
"notes": "Countly has hooks and automated push"
}
]
},
{
"group": "Performance & Debugging",
"features": [
{
"name": "Crash Reporting",
"openpanel": false,
"competitor": true,
"notes": "Countly has full crash analytics with symbolication"
},
{
"name": "Performance Monitoring (APM)",
"openpanel": false,
"competitor": true,
"notes": "Countly monitors network and device performance"
},
{
"name": "Error Tracking",
"openpanel": false,
"competitor": true
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": true,
"notes": "Both offer self-hosted deployment"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "Consent Management",
"openpanel": true,
"competitor": true,
"notes": "Countly has a 'Compliance Hub' feature"
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true
},
{
"name": "ISO 27001 Certified",
"openpanel": false,
"competitor": true
},
{
"name": "SOC2 Certified",
"openpanel": false,
"competitor": true
}
]
},
{
"group": "Integrations & SDKs",
"features": [
{
"name": "JavaScript/Web SDK",
"openpanel": true,
"competitor": true
},
{
"name": "iOS SDK",
"openpanel": true,
"competitor": true
},
{
"name": "Android SDK",
"openpanel": true,
"competitor": true
},
{
"name": "React Native SDK",
"openpanel": true,
"competitor": true
},
{
"name": "Flutter SDK",
"openpanel": false,
"competitor": true
},
{
"name": "Unity SDK",
"openpanel": false,
"competitor": true,
"notes": "Countly supports game development with Unity"
},
{
"name": "Desktop SDKs (Windows/Mac)",
"openpanel": false,
"competitor": true,
"notes": "Countly has C++ and Windows SDKs"
},
{
"name": "Node.js SDK",
"openpanel": true,
"competitor": true
},
{
"name": "REST API",
"openpanel": true,
"competitor": true
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "Varies by platform (larger, full-featured SDKs)",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript/Web",
"iOS",
"Android",
"React Native",
"Flutter",
"Unity",
"C++",
"Java",
"Windows",
"Node.js"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Partial - AGPL (non-commercial only)",
"notes": "OpenPanel is fully MIT licensed. Countly Lite is AGPL-3.0 (non-commercial only). Countly Enterprise is proprietary."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Docker or install script (requires MongoDB, Node.js, Nginx)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "MongoDB",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "6 months (Flex free), configurable as add-on",
"notes": null
},
{
"label": "Certifications",
"openpanel": "None listed",
"competitor": "ISO 27001, SOC2",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Countly's MAU-based pricing with add-ons can get expensive. OpenPanel offers simple event-based pricing.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "MAU-based with feature add-ons",
"description": "Lite: Self-hosted, AGPL, non-commercial only. Flex Free: 500 MAUs. Flex Tier 1: $80/month for 2,000 MAUs. Core analytics included, advanced features (A/B testing, surveys, push) are add-ons. Fully-featured Flex can cost $132,000+/year at scale.",
"free_tier": "Lite (non-commercial only) or Flex Free (500 MAUs)",
"pricing_url": "https://countly.com/pricing"
}
},
"migration": {
"title": "Migrating from Countly to OpenPanel",
"intro": "Switching from Countly to OpenPanel is straightforward for analytics. You'll need separate tools for push notifications and crash reporting.",
"difficulty": "moderate",
"estimated_time": "1-4 hours depending on feature usage",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Replace Countly SDK with OpenPanel. OpenPanel's SDK is significantly lighter and simpler to integrate."
},
{
"title": "Map Events and Properties",
"description": "Countly events map directly to OpenPanel events. Countly.recordEvent() becomes op.track(). User properties translate similarly."
},
{
"title": "Set Up User Identification",
"description": "Both platforms support user identification. Replace Countly's device ID management with OpenPanel's identify() method."
},
{
"title": "Recreate Funnels and Cohorts",
"description": "Set up your conversion funnels and user cohorts in OpenPanel. The concepts are similar, though OpenPanel's interface is simpler."
},
{
"title": "Plan for Feature Gaps",
"description": "If you use Countly's push notifications, crash reporting, or remote config, you'll need separate tools. OpenPanel focuses purely on analytics."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with similar APIs."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Countly",
"intro": "Choose OpenPanel when you want analytics without the complexity and cost of an all-in-one platform.",
"items": [
{
"title": "Teams Wanting Simpler, Cheaper Analytics",
"description": "Countly's MAU-based pricing gets expensive quickly, and the feature add-on model adds complexity. OpenPanel offers straightforward event-based pricing with all features included.",
"icon": "dollar-sign"
},
{
"title": "Open Source Commercial Use",
"description": "Countly Lite's AGPL license prohibits commercial use - you must buy Enterprise. OpenPanel's MIT license allows unlimited commercial use for free.",
"icon": "unlock"
},
{
"title": "Lightweight Self-Hosting",
"description": "Countly requires MongoDB, Node.js, and Nginx with complex upgrade procedures. OpenPanel runs in a simple Docker container with ClickHouse for faster queries.",
"icon": "server"
},
{
"title": "Pure Product Analytics Focus",
"description": "If you only need analytics without push notifications, crash reporting, or remote config, OpenPanel provides a focused, less complex solution.",
"icon": "bar-chart"
},
{
"title": "Startups with Limited Budgets",
"description": "Countly's pricing can reach $132,000+/year for full features at scale. OpenPanel's event-based model is more predictable and affordable for growing startups.",
"icon": "trending-up"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Countly to OpenPanel.",
"items": [
{
"question": "Is Countly really open source?",
"answer": "Partially. Countly Lite is open source under AGPL-3.0 with modified terms, but it explicitly prohibits commercial use. For business use, you must purchase Countly Enterprise or use Countly Flex (their SaaS). OpenPanel is fully open source under MIT license with no commercial restrictions."
},
{
"question": "Why is OpenPanel cheaper than Countly?",
"answer": "OpenPanel uses event-based pricing with 10,000 free events/month. Countly charges by Monthly Active Users (MAUs) starting at $80/month for just 2,000 MAUs, plus additional fees for features like A/B testing, surveys, and push notifications as add-ons."
},
{
"question": "Does OpenPanel have push notifications like Countly?",
"answer": "No. Countly is an all-in-one platform including push notifications, surveys, and remote configuration. OpenPanel focuses purely on product analytics. You would need separate tools like OneSignal or Firebase for push notifications."
},
{
"question": "Does OpenPanel have crash reporting?",
"answer": "No. Countly includes comprehensive crash and error reporting with symbolication. OpenPanel focuses on product analytics. For crash reporting, consider tools like Sentry or Crashlytics alongside OpenPanel."
},
{
"question": "How does self-hosting compare?",
"answer": "OpenPanel runs in a simple Docker container with ClickHouse. Countly requires MongoDB, Node.js, and Nginx with a more complex installation script. Countly's upgrade process can be tedious for older versions."
},
{
"question": "Which has better mobile SDK support?",
"answer": "Countly has broader SDK coverage including Flutter, Unity, and desktop (Windows/Mac). OpenPanel supports iOS, Android, and React Native. Choose based on your specific platform needs."
},
{
"question": "Is Countly better for enterprise?",
"answer": "Countly Enterprise offers ISO 27001 and SOC2 certifications, SLAs, and direct support - important for large enterprises with strict compliance needs. OpenPanel is better suited for startups and teams prioritizing simplicity and cost."
},
{
"question": "Can I use Countly Lite for my startup?",
"answer": "No. Countly Lite's license explicitly states: 'you cannot use Countly Lite for commercial or non-commercial purposes, to provide Countly as a service to your customers.' For business use, you must purchase Countly Enterprise or Flex."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,420 @@
{
"slug": "crazy-egg-alternative",
"page_type": "alternative",
"seo": {
"title": "Crazy Egg Alternative",
"description": "Compare OpenPanel with Crazy Egg: pricing, features, and focus. OpenPanel offers product analytics with mobile SDKs; Crazy Egg excels at heatmaps and A/B testing.",
"noindex": false
},
"hero": {
"heading": "Crazy Egg alternative",
"subheading": "Get full product analytics capabilities beyond heatmaps. OpenPanel delivers funnel analysis, retention tracking, mobile SDKs, and user identification—fully open source and self-hostable.",
"badges": [
"Open-source",
"Self-hostable",
"Mobile SDKs",
"Product analytics"
]
},
"competitor": {
"name": "Crazy Egg",
"logo": "/logos/crazy-egg.svg",
"url": "https://www.crazyegg.com",
"short_description": "Website optimization platform with heatmaps, A/B testing, surveys, and session recordings. Founded by Neil Patel and Hiten Shah in 2005.",
"founded": 2005,
"headquarters": "La Mirada, CA"
},
"summary_comparison": {
"title": "OpenPanel vs Crazy Egg: Which is right for you?",
"intro": "Crazy Egg focuses on visual website optimization with heatmaps and A/B testing. OpenPanel focuses on product analytics with mobile support.",
"one_liner": "OpenPanel is for product analytics with mobile SDKs and self-hosting; Crazy Egg is for visual website optimization with heatmaps.",
"best_for_openpanel": [
"Teams needing mobile app analytics with native SDKs",
"Product analytics focus (funnels, retention, cohorts)",
"Organizations requiring self-hosting for data ownership",
"Open source requirements for transparency",
"User-level analytics across platforms"
],
"best_for_competitor": [
"Teams requiring comprehensive heatmaps for visual analysis",
"Website conversion optimization with A/B testing",
"On-site surveys and feedback collection",
"Popup CTA creation and management",
"Visual website optimization without mobile requirements"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Crazy Egg compare on the factors that matter most.",
"items": [
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, with Docker",
"competitor": "No (cloud only)"
},
{
"label": "Mobile SDKs",
"openpanel": "iOS, Android, RN, Flutter",
"competitor": "Web only"
},
{
"label": "Heatmaps",
"openpanel": "Not available",
"competitor": "Click, scroll, confetti, overlay"
},
{
"label": "A/B testing",
"openpanel": "Not built-in",
"competitor": "Visual editor with optimization"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel focuses on product analytics; Crazy Egg focuses on visual website optimization.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": false,
"notes": "Crazy Egg is pageview-focused"
},
{
"name": "Funnels",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Visual website optimization",
"features": [
{
"name": "Heatmaps",
"openpanel": false,
"competitor": true,
"notes": "Crazy Egg's flagship feature"
},
{
"name": "Scroll maps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Confetti reports",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "A/B testing",
"openpanel": false,
"competitor": true,
"notes": "Visual editor"
},
{
"name": "Session recordings",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Popup CTAs",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Feedback & surveys",
"features": [
{
"name": "On-site surveys",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "NPS scoring",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cookie-free option",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "HIPAA compliant",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Crazy Egg has limited API"
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Mobile SDKs",
"openpanel": true,
"competitor": false,
"notes": "Crazy Egg is web only"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "Async script (minimal impact)",
"notes": null
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Flutter"
],
"competitor": [
"JavaScript (web only)"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary",
"notes": null
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted)",
"competitor": "6 months to 2 years",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Both offer generous free tiers with different pricing models—event-based vs pageview-based.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Pageview-based, annual billing",
"description": "Free plan with limited features. Starter: $29/month for 5,000 pageviews. Plus: $99/month for 150,000 pageviews with A/B testing. Enterprise: $599/month for 1M pageviews.",
"free_tier": "Yes (limited features)",
"pricing_url": "https://www.crazyegg.com/pricing"
}
},
"migration": {
"title": "Migrating from Crazy Egg to OpenPanel",
"intro": "Consider if heatmaps and A/B testing are critical before switching, as these are Crazy Egg's core strengths.",
"difficulty": "easy",
"estimated_time": "1-2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your website. The SDK is lightweight and loads asynchronously."
},
{
"title": "Define event tracking strategy",
"description": "Unlike Crazy Egg's pageview focus, OpenPanel tracks custom events. Define key actions using track() calls."
},
{
"title": "Set up user identification",
"description": "Crazy Egg tracks anonymous sessions. With OpenPanel, identify users with identify() to track individual journeys."
},
{
"title": "Build funnels and dashboards",
"description": "Recreate conversion tracking from Crazy Egg as OpenPanel funnels."
},
{
"title": "Remove Crazy Egg script",
"description": "Once verified, remove the Crazy Egg tracking code. Note: You will lose heatmaps, A/B testing, and surveys."
}
],
"sdk_compatibility": {
"similar_api": false,
"notes": "Different tracking philosophies: Crazy Egg is pageview/visual focused, OpenPanel is event-based."
},
"historical_data": {
"can_import": false,
"notes": "Crazy Egg data export depends on your plan. Historical heatmap data cannot be migrated."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Crazy Egg",
"intro": "OpenPanel excels when you need product analytics beyond visual website optimization.",
"items": [
{
"title": "Mobile app analytics",
"description": "Crazy Egg is web-only. OpenPanel offers native SDKs for iOS, Android, React Native, and Flutter.",
"icon": "smartphone"
},
{
"title": "Product analytics beyond heatmaps",
"description": "OpenPanel provides funnel analysis, retention cohorts, user profiles, and path analysis.",
"icon": "chart"
},
{
"title": "Self-hosting requirements",
"description": "Crazy Egg is cloud-only. OpenPanel offers Docker deployment for complete data control.",
"icon": "server"
},
{
"title": "Open source requirements",
"description": "Full source code transparency under MIT license. Crazy Egg is proprietary.",
"icon": "code"
},
{
"title": "User-level analytics",
"description": "Track individual users and their complete journey across sessions. Crazy Egg focuses on aggregate pageview data.",
"icon": "users"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Crazy Egg to OpenPanel.",
"items": [
{
"question": "What will I lose switching from Crazy Egg to OpenPanel?",
"answer": "Crazy Egg's core features are heatmaps, A/B testing, on-site surveys, and popup CTAs. OpenPanel does not offer these features—it focuses on product analytics instead."
},
{
"question": "Does OpenPanel have heatmaps like Crazy Egg?",
"answer": "No. OpenPanel is focused on event-based product analytics (funnels, retention, user identification) rather than visual website optimization."
},
{
"question": "How does pricing compare?",
"answer": "Crazy Egg pricing starts at $29/month for 5,000 pageviews (annual billing). OpenPanel offers 10,000 events/month free, then $0.00005/event. For similar traffic, OpenPanel is typically more affordable."
},
{
"question": "Can I track mobile apps with Crazy Egg?",
"answer": "No. Crazy Egg is designed exclusively for website analytics. OpenPanel offers native SDKs for iOS, Android, React Native, and Flutter."
},
{
"question": "Does OpenPanel have A/B testing like Crazy Egg?",
"answer": "No. Crazy Egg includes a visual A/B testing editor as a core feature. OpenPanel focuses on analytics rather than experimentation."
},
{
"question": "Is Crazy Egg open source?",
"answer": "No. Crazy Egg is proprietary closed-source. OpenPanel is fully open source under the MIT license."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,166 @@
import { readFile, readdir } from 'node:fs/promises';
import { join } from 'node:path';
interface FileStructure {
filename: string;
rootKeys: string[];
structureKey: string; // normalized structure identifier
hasContent: boolean;
error?: string;
}
async function analyzeJsonFiles(): Promise<void> {
const dirPath = join(import.meta.dirname || __dirname);
const files = await readdir(dirPath);
const jsonFiles = files.filter((f) => f.endsWith('.json'));
console.log(`\n📊 Analyzing ${jsonFiles.length} JSON files...\n`);
const structures: FileStructure[] = [];
// Read and analyze each JSON file
for (const filename of jsonFiles) {
const filePath = join(dirPath, filename);
try {
const content = await readFile(filePath, 'utf-8');
if (!content.trim()) {
structures.push({
filename,
rootKeys: [],
structureKey: 'empty',
hasContent: false,
error: 'File is empty',
});
continue;
}
const data = JSON.parse(content);
const rootKeys = Object.keys(data).sort();
const structureKey = rootKeys.join('|');
structures.push({
filename,
rootKeys,
structureKey,
hasContent: true,
});
} catch (error) {
structures.push({
filename,
rootKeys: [],
structureKey: 'error',
hasContent: false,
error: error instanceof Error ? error.message : String(error),
});
}
}
// Group files by structure
const groups = new Map<string, FileStructure[]>();
for (const structure of structures) {
const key = structure.structureKey;
if (!groups.has(key)) {
groups.set(key, []);
}
groups.get(key)!.push(structure);
}
// Display results
const separator = '='.repeat(80);
console.log(separator);
console.log('📋 ALL ROOT KEYS FOUND ACROSS ALL FILES:');
console.log(separator);
const allKeys = new Set<string>();
structures.forEach((s) => {
s.rootKeys.forEach((k) => allKeys.add(k));
});
const sortedKeys = Array.from(allKeys).sort();
sortedKeys.forEach((key) => {
const filesWithKey = structures.filter((s) => s.rootKeys.includes(key));
console.log(`${key.padEnd(30)} (in ${filesWithKey.length} files)`);
});
console.log(`\n${separator}`);
console.log('📦 FILES GROUPED BY STRUCTURE:');
console.log(separator);
const sortedGroups = Array.from(groups.entries()).sort(
(a, b) => b[1].length - a[1].length,
);
sortedGroups.forEach(([structureKey, files], index) => {
const fileCount = files.length;
const plural = fileCount > 1 ? 's' : '';
console.log(`\n🔹 Group ${index + 1} (${fileCount} file${plural}):`);
console.log(` Structure: ${structureKey || '(empty/error)'}`);
if (files[0].rootKeys.length > 0) {
console.log(` Root keys: ${files[0].rootKeys.join(', ')}`);
}
console.log(' Files:');
files.forEach((file) => {
const status = file.hasContent ? '✓' : file.error ? '✗' : '○';
console.log(` ${status} ${file.filename}`);
if (file.error) {
console.log(` Error: ${file.error}`);
}
});
});
// Validation summary
console.log(`\n${separator}`);
console.log('✅ VALIDATION SUMMARY:');
console.log(separator);
const validFiles = structures.filter((s) => s.hasContent && !s.error);
const emptyFiles = structures.filter((s) => !s.hasContent && !s.error);
const errorFiles = structures.filter((s) => s.error);
console.log(` Total files: ${structures.length}`);
const validCount = validFiles.length;
const emptyCount = emptyFiles.length;
const errorCount = errorFiles.length;
console.log(` ✓ Valid JSON files: ${validCount}`);
console.log(` ○ Empty files: ${emptyCount}`);
console.log(` ✗ Files with errors: ${errorCount}`);
if (validFiles.length > 0) {
const uniqueStructures = new Set(validFiles.map((s) => s.structureKey));
const uniqueCount = uniqueStructures.size;
console.log(`\n 📊 Unique structures: ${uniqueCount}`);
if (uniqueCount > 1) {
console.log('\n ⚠️ WARNING: Files have inconsistent structures!');
console.log(` Found ${uniqueCount} different structure(s).`);
} else {
console.log('\n ✓ All valid files have consistent structure!');
}
}
// Show structure differences in detail
if (sortedGroups.length > 1) {
console.log(`\n${separator}`);
console.log('🔍 STRUCTURE DIFFERENCES:');
console.log(separator);
sortedGroups.forEach(([structureKey, files], index) => {
if (structureKey === 'empty' || structureKey === 'error') return;
const groupNum = index + 1;
console.log(`\nGroup ${groupNum} structure:`);
const sample = files[0];
sample.rootKeys.forEach((key) => {
console.log(` - ${key}`);
});
});
}
console.log(`\n${separator}\n`);
}
// Run the analysis
analyzeJsonFiles().catch(console.error);

View File

@@ -0,0 +1,471 @@
{
"slug": "fathom-alternative",
"page_type": "alternative",
"seo": {
"title": "Fathom Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Fathom Analytics. Discover why teams choose OpenPanel as their Fathom alternative for product analytics, user identification, and self-hosting while maintaining privacy-first principles.",
"noindex": false
},
"hero": {
"heading": "Fathom Alternative",
"subheading": "Love Fathom's simplicity and privacy focus? OpenPanel adds product analytics capabilities - funnels, cohorts, retention, and user identification - plus self-hosting options and a free tier.",
"badges": [
"Open-source",
"Privacy-first",
"Self-hostable",
"Free Tier"
]
},
"competitor": {
"name": "Fathom Analytics",
"logo": "/logos/fathom.svg",
"url": "https://usefathom.com",
"short_description": "Privacy-focused, simple Google Analytics alternative for websites with beautiful dashboard and EU-based hosting.",
"founded": 2018,
"headquarters": "Canada"
},
"summary_comparison": {
"title": "OpenPanel vs Fathom: Which is right for you?",
"intro": "Both are privacy-focused analytics platforms. Fathom focuses on simple web traffic metrics. OpenPanel adds product analytics with user identification and self-hosting.",
"one_liner": "Fathom excels at simple web analytics; OpenPanel adds product analytics, self-hosting, and a free tier.",
"best_for_openpanel": [
"SaaS products needing user-level analytics and retention tracking",
"Teams wanting self-hosting for complete data control",
"Startups needing a free tier to get started",
"Mobile app developers needing native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Simple content sites and blogs wanting traffic stats only",
"Teams valuing Fathom's beautiful, minimal dashboard design",
"Users wanting excellent Google Analytics import tool",
"Organizations committed to paying for sustainable software"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Fathom compare on key factors.",
"items": [
{
"label": "Analytics Depth",
"openpanel": "Web + Product Analytics",
"competitor": "Web Analytics Only",
"notes": "OpenPanel combines web analytics with product analytics including funnels, retention, cohorts, and user profiles. Fathom focuses on simple website traffic metrics and conversions."
},
{
"label": "Self-Hosting",
"openpanel": "Full self-hosting available",
"competitor": "Cloud-only (no self-host option)",
"notes": "OpenPanel offers full self-hosting in a single Docker container. Fathom is cloud-only; their legacy open-source version (Fathom Lite) uses cookies and is no longer actively developed."
},
{
"label": "Free Tier",
"openpanel": "10,000 events/month free",
"competitor": "No free tier (7-day trial only)",
"notes": "OpenPanel offers a generous free tier. Fathom has no free option - just a 7-day trial before requiring a $15/month minimum subscription."
},
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Fathom uses anonymization and doesn't track individuals."
},
{
"label": "Cookie-Free",
"openpanel": "Yes (by default)",
"competitor": "Yes (by default)",
"notes": "Both platforms are cookie-free by default and don't require consent banners under GDPR for basic analytics."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are privacy-focused, but with different capabilities and depths.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "Both offer country and region-level data"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Fathom events count toward pageview quota"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": false,
"notes": "Fathom tracks simple conversions but no multi-step funnels"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Fathom's anonymous model doesn't support retention"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Fathom intentionally doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "Fathom provides aggregate data only"
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": false,
"notes": "Fathom shows top pages but not user journeys"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Fathom is analytics-only, no experimentation"
},
{
"name": "Revenue Tracking",
"openpanel": true,
"competitor": true,
"notes": "Fathom supports event values in cents"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": true,
"notes": "Both offer scheduled email reports"
},
{
"name": "Dashboard Sharing",
"openpanel": true,
"competitor": true,
"notes": "Both support public and private dashboard sharing"
},
{
"name": "Google Analytics Import",
"openpanel": false,
"competitor": true,
"notes": "Fathom has a well-regarded GA importer"
},
{
"name": "Ad-Blocker Bypass",
"openpanel": true,
"competitor": true,
"notes": "Both support custom domains to bypass blockers"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true,
"notes": "Both are cookieless by default"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "EU Data Residency",
"openpanel": true,
"competitor": true,
"notes": "Fathom has EU Isolation enabled by default for all customers"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": false,
"notes": "Fathom is cloud-only; Fathom Lite is legacy and uses cookies"
},
{
"name": "Data Processing Agreement",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Fathom has a comprehensive API"
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true,
"notes": "CSV export available on both"
},
{
"name": "WordPress Plugin",
"openpanel": true,
"competitor": true,
"notes": "Fathom has official WordPress plugin"
},
{
"name": "NPM Package",
"openpanel": true,
"competitor": true,
"notes": "fathom-client package available"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "~2 KB (gzipped)",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"WordPress",
"Webflow",
"Next.js",
"Vue.js",
"Ghost",
"ConvertKit",
"Various CMS integrations"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "No - Closed source",
"notes": "Fathom Analytics is closed-source. Fathom Lite (legacy) is open-source but limited and uses cookies."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Not available (cloud-only service)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "Proprietary cloud infrastructure (serverless on AWS)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Forever (as long as you're a customer)",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Unknown (closed-source)",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Fathom has no free tier. OpenPanel offers free cloud and self-hosting.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "Pageview-based with 7-day trial",
"description": "100K pageviews: $15/month ($150/year). Up to 50 sites included. All features included. Custom events count as pageviews. Annual billing saves 2 months. Fathom has no free tier and never does discounts.",
"free_tier": "No free tier (7-day trial only)",
"pricing_url": "https://usefathom.com/pricing"
}
},
"migration": {
"title": "Migrating from Fathom to OpenPanel",
"intro": "Both use lightweight scripts and simple event tracking, making migration straightforward.",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts, so the transition is straightforward."
},
{
"title": "Map Events",
"description": "Fathom's trackEvent() becomes OpenPanel's op.track(). Event values translate directly."
},
{
"title": "Set Up User Identification (New)",
"description": "Unlike Fathom, OpenPanel can identify users. Add op.identify() calls to unlock retention, cohorts, and user profiles."
},
{
"title": "Configure Product Analytics (New)",
"description": "Set up funnels, retention reports, and cohorts. These features aren't available in Fathom."
},
{
"title": "Remove Fathom Script",
"description": "Once verified, remove the Fathom tracking script. Both are cookie-free so no consent changes needed."
}
],
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use simple event tracking APIs. Fathom's trackEvent() becomes OpenPanel's op.track()."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Fathom",
"intro": "Choose OpenPanel when you need product analytics beyond simple web traffic.",
"items": [
{
"title": "SaaS Products Needing User Analytics",
"description": "Fathom shows aggregate website traffic. If you need to understand individual user journeys, retention, and behavior within your product, OpenPanel adds these capabilities while staying privacy-friendly.",
"icon": "users"
},
{
"title": "Teams Who Want Self-Hosting",
"description": "Fathom is cloud-only with no self-hosting option. If data sovereignty or compliance requirements mean you need to host your own analytics, OpenPanel provides full self-hosting in a single Docker container.",
"icon": "server"
},
{
"title": "Startups Needing a Free Tier",
"description": "Fathom has no free option, requiring a minimum $15/month commitment. OpenPanel offers 10,000 free events monthly, perfect for early-stage products or side projects.",
"icon": "trending-up"
},
{
"title": "Mobile App Analytics",
"description": "Fathom is designed for websites and doesn't provide native mobile SDKs. OpenPanel offers native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams Needing Funnel Analysis",
"description": "Fathom tracks simple conversions but doesn't offer multi-step funnel analysis. If understanding conversion paths matters, OpenPanel provides detailed funnel visualization.",
"icon": "filter"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Fathom to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Fathom?",
"answer": "Yes! Both are cookie-free by default and don't require consent banners. The key difference is that OpenPanel allows optional user identification for product analytics, while Fathom is strictly anonymous. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Fathom to OpenPanel?",
"answer": "Teams typically switch when they need: 1) Product analytics (funnels, retention, cohorts), 2) User identification, 3) Self-hosting options, or 4) A free tier for starting out. Fathom excels at simple web analytics but doesn't offer these capabilities."
},
{
"question": "Does Fathom have a free tier?",
"answer": "No. Fathom offers a 7-day free trial, then requires a minimum $15/month subscription. They intentionally don't offer a free tier or discounts. OpenPanel provides 10,000 free events monthly."
},
{
"question": "Can I self-host Fathom?",
"answer": "No. Fathom Analytics is cloud-only. Their legacy open-source version (Fathom Lite) exists but uses cookies, has limited features, and is no longer actively developed. OpenPanel offers full self-hosting in a single Docker container."
},
{
"question": "Which has the smaller tracking script?",
"answer": "They're similar. Fathom's script is approximately 2KB, and OpenPanel's is 2.3KB. Both are significantly smaller than Google Analytics (45KB+) or other enterprise tools."
},
{
"question": "Can Fathom track mobile apps?",
"answer": "Not natively. Fathom is designed for web analytics and doesn't provide mobile SDKs. You could send events via their API, but there are no mobile-specific features. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "What will I lose switching from Fathom?",
"answer": "Fathom's Google Analytics import tool is well-regarded if you're migrating historical data. Their EU Isolation feature is enabled by default for all customers. However, you'll gain product analytics, self-hosting options, and a free tier that Fathom doesn't offer."
},
{
"question": "Is Fathom or OpenPanel better for blogs/content sites?",
"answer": "For simple content sites where you just need traffic stats, Fathom's simplicity is excellent and their GA importer helps with transitions. If you're running a SaaS, e-commerce, or any product where understanding user behavior matters, OpenPanel's product analytics features provide more value."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,430 @@
{
"slug": "fullstory-alternative",
"page_type": "alternative",
"seo": {
"title": "FullStory Alternative",
"description": "Compare OpenPanel with FullStory: pricing, privacy, self-hosting, and features. OpenPanel offers product analytics with transparent pricing and self-hosting.",
"noindex": false
},
"hero": {
"heading": "FullStory alternative",
"subheading": "Get powerful product analytics without FullStory's enterprise pricing. OpenPanel delivers funnel analysis, retention tracking, and user identification—fully open source and self-hostable with transparent pricing.",
"badges": [
"Open-source",
"Self-hostable",
"Transparent pricing",
"Product analytics"
]
},
"competitor": {
"name": "FullStory",
"logo": "/logos/fullstory.svg",
"url": "https://www.fullstory.com",
"short_description": "Digital Experience Intelligence (DXI) platform known for pixel-perfect session replay and frustration signal detection.",
"founded": 2014,
"headquarters": "Atlanta, GA"
},
"summary_comparison": {
"title": "OpenPanel vs FullStory: Which is right for you?",
"intro": "Both platforms provide analytics and session replay, but FullStory focuses on visual debugging while OpenPanel emphasizes product analytics.",
"one_liner": "OpenPanel is open source with transparent pricing for product analytics; FullStory excels at session replay with enterprise pricing.",
"best_for_openpanel": [
"Teams needing open source analytics for transparency",
"Organizations requiring self-hosting for data sovereignty",
"Budget-conscious teams seeking transparent pricing",
"Product analytics focus over visual UX debugging",
"Teams avoiding vendor lock-in"
],
"best_for_competitor": [
"Teams requiring pixel-perfect session replay",
"Organizations needing sophisticated frustration detection",
"Enterprise teams with budget for premium features",
"UX teams requiring heatmaps and DevTools integration",
"Companies needing AI-powered session summaries"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and FullStory compare on the factors that matter most.",
"items": [
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, with Docker",
"competitor": "No (cloud only)"
},
{
"label": "Transparent pricing",
"openpanel": "Public pricing, free tier",
"competitor": "Sales-required pricing"
},
{
"label": "Session replay",
"openpanel": "Basic",
"competitor": "Pixel-perfect with DevTools"
},
{
"label": "Heatmaps",
"openpanel": "Not available",
"competitor": "Click, scroll, engagement"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel focuses on product analytics; FullStory excels at session replay and visual debugging.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": "FullStory uses autocapture"
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": "FullStory on Advanced/Enterprise plans"
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Visual analytics",
"features": [
{
"name": "Session replay",
"openpanel": true,
"competitor": true,
"notes": "FullStory's core strength"
},
{
"name": "Heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Rage click detection",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Frustration signals",
"openpanel": false,
"competitor": true,
"notes": "FullStory's proprietary feature"
},
{
"name": "DevTools integration",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "AI session summaries",
"openpanel": false,
"competitor": true,
"notes": "StoryAI"
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Autocapture",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": "FullStory Data Direct"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cookie-free option",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "SOC 2 certified",
"openpanel": false,
"competitor": true,
"notes": "Type II"
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data warehouse sync",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Mobile SDKs",
"openpanel": true,
"competitor": true,
"notes": null
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~10+ KB (autocapture)",
"notes": null
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js"
],
"competitor": [
"JavaScript",
"iOS",
"Android",
"React Native",
"Flutter"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary",
"notes": null
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted)",
"competitor": "2-60 months depending on plan",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers transparent pricing. FullStory requires sales conversations with enterprise pricing.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Session-based, sales-required",
"description": "14-day trial with 5,000 sessions. Business/Advanced/Enterprise plans require custom quotes. Pricing reportedly starts at $12,000-50,000+/year for most teams.",
"free_tier": "14-day trial (limited)",
"pricing_url": "https://www.fullstory.com/pricing"
}
},
"migration": {
"title": "Migrating from FullStory to OpenPanel",
"intro": "Switching means trading session replay features for open source, self-hosting, and transparent pricing.",
"difficulty": "moderate",
"estimated_time": "2-4 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. The SDK is lightweight (~2.3KB) compared to FullStory's autocapture script."
},
{
"title": "Map event tracking",
"description": "FullStory uses autocapture for most events. With OpenPanel, you'll define explicit event tracking using track() calls."
},
{
"title": "Transfer user identification",
"description": "FullStory's identify() maps to OpenPanel's identify(). Transfer your user ID and custom user variables."
},
{
"title": "Set up funnels and analytics",
"description": "Recreate your FullStory funnels in OpenPanel. Build custom dashboards for key metrics."
},
{
"title": "Remove FullStory script",
"description": "Once verified, remove the FullStory snippet. Note: You'll lose access to session replay and heatmaps."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both support similar identification and event tracking patterns. Main difference is autocapture vs explicit tracking."
},
"historical_data": {
"can_import": false,
"notes": "FullStory's session data is proprietary. Contact us if you need assistance with data migration."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than FullStory",
"intro": "OpenPanel excels when you need product analytics with data ownership and transparent pricing.",
"items": [
{
"title": "Teams needing open source analytics",
"description": "FullStory is proprietary with no source code access. OpenPanel provides full source code transparency under MIT license.",
"icon": "code"
},
{
"title": "Self-hosting requirements",
"description": "FullStory is cloud-only. OpenPanel can be deployed on your servers for complete data control.",
"icon": "server"
},
{
"title": "Budget-conscious teams",
"description": "FullStory's enterprise pricing (reportedly $12,000-50,000+/year) is prohibitive. OpenPanel offers transparent pricing starting at $2.50/month.",
"icon": "dollar"
},
{
"title": "Product analytics focus",
"description": "If your primary need is product analytics—funnels, retention, cohorts—rather than visual debugging, OpenPanel provides these at a fraction of the cost.",
"icon": "chart"
},
{
"title": "Avoiding vendor lock-in",
"description": "FullStory's proprietary platform creates vendor lock-in. OpenPanel's open source nature prevents dependency on a single vendor.",
"icon": "lock"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from FullStory to OpenPanel.",
"items": [
{
"question": "What will I lose switching from FullStory to OpenPanel?",
"answer": "FullStory's core strengths are session replay, heatmaps, and frustration signals (rage clicks, dead clicks). OpenPanel has basic session replay but lacks heatmaps and FullStory's sophisticated frustration detection. If visual UX debugging is critical, consider keeping FullStory for that use case."
},
{
"question": "Is OpenPanel as feature-rich as FullStory for product analytics?",
"answer": "For pure product analytics (funnels, retention, cohorts, user profiles), OpenPanel offers comparable capabilities. FullStory bundles product analytics with its DXI platform, but many teams find they're paying for session replay features they don't heavily use."
},
{
"question": "How does pricing compare?",
"answer": "FullStory requires sales conversations with pricing reportedly starting at $12,000/year. OpenPanel offers transparent pricing: 10,000 events/month free, then $0.00005/event. Most teams will save 80-90% with OpenPanel."
},
{
"question": "Can I self-host FullStory?",
"answer": "No. FullStory is cloud-only SaaS. OpenPanel offers full self-hosting via Docker for complete data control."
},
{
"question": "Is FullStory open source?",
"answer": "No. FullStory is proprietary closed-source. OpenPanel is fully open source under the MIT license."
},
{
"question": "Does OpenPanel have autocapture like FullStory?",
"answer": "OpenPanel uses explicit event tracking rather than FullStory's autocapture. This means more intentional instrumentation but cleaner data without noise."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,476 @@
{
"slug": "funnelio-alternative",
"page_type": "alternative",
"seo": {
"title": "Funnel.io Alternative: Why Teams Choose OpenPanel for Product Analytics",
"description": "Compare OpenPanel vs Funnel.io. Understand the key differences between product analytics and marketing data integration, and discover why teams choose OpenPanel for tracking user behavior.",
"noindex": false
},
"hero": {
"heading": "Funnel.io Alternative",
"subheading": "Funnel.io aggregates marketing data from ad platforms. OpenPanel tracks user behavior in your product. Different tools for different needs - discover which is right for you.",
"badges": [
"Open-source",
"Product Analytics",
"User Behavior Tracking",
"Self-hostable"
]
},
"competitor": {
"name": "Funnel.io",
"logo": "/logos/funnelio.svg",
"url": "https://funnel.io",
"short_description": "Marketing data integration platform that aggregates data from 500+ ad platforms and marketing tools into unified reports.",
"founded": 2014,
"headquarters": "Stockholm, Sweden"
},
"summary_comparison": {
"title": "OpenPanel vs Funnel.io: Which is right for you?",
"intro": "Funnel.io and OpenPanel serve fundamentally different purposes. Funnel.io aggregates marketing spend and campaign data from external platforms (Google Ads, Facebook Ads, etc.). OpenPanel tracks user behavior within your product.",
"one_liner": "OpenPanel is for product analytics (how users interact with your product); Funnel.io is for marketing data integration (aggregating ad platform data).",
"best_for_openpanel": [
"Product teams who need to track user behavior in their website or app",
"Startups needing affordable analytics with a generous free tier",
"Teams requiring self-hosting for data privacy or compliance",
"Mobile app developers needing native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Marketing teams aggregating data from multiple ad platforms",
"Agencies managing hundreds of marketing data sources for clients",
"Organizations needing cross-platform marketing spend reporting",
"Teams requiring sophisticated marketing mix modeling"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Funnel.io and OpenPanel solve different problems. Here's how they compare:",
"items": [
{
"label": "Primary Use Case",
"openpanel": "Product analytics - track user behavior",
"competitor": "Marketing data aggregation - collect ad data",
"notes": "OpenPanel tracks how users interact with your product (clicks, events, conversions). Funnel.io aggregates marketing spend and performance data from ad platforms like Google Ads and Facebook Ads."
},
{
"label": "User Behavior Tracking",
"openpanel": "Yes - events, funnels, retention",
"competitor": "No - aggregates external platform data",
"notes": "OpenPanel provides SDKs to track user behavior on your website or app. Funnel.io does not track user behavior - it imports data from external marketing platforms via API connectors."
},
{
"label": "Self-Hosting & Open Source",
"openpanel": "Yes - MIT License, Docker deployment",
"competitor": "No - Cloud-only SaaS",
"notes": "OpenPanel is fully open source and can be self-hosted. Funnel.io is proprietary cloud-only software with no self-hosting option."
},
{
"label": "Marketing Platform Connectors",
"openpanel": "Limited - focused on product data",
"competitor": "500+ connectors to ad platforms",
"notes": "Funnel.io excels at connecting to 500+ marketing data sources (Google Ads, Facebook Ads, LinkedIn, etc.). OpenPanel focuses on tracking your own product data, not importing external marketing data."
},
{
"label": "Pricing Transparency",
"openpanel": "Public pricing, free tier",
"competitor": "Starts at $399/month, no free tier",
"notes": "OpenPanel offers transparent pricing with a free tier. Funnel.io starts at $399/month (Essentials) with enterprise plans reaching $1,999+/month."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "These platforms serve different purposes and have different feature sets optimized for their respective use cases.",
"groups": [
{
"group": "User Behavior Tracking",
"features": [
{
"name": "Event Tracking SDK",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not track user behavior - it imports data from external platforms"
},
{
"name": "Session Tracking",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io aggregates session data from Google Analytics, not direct tracking"
},
{
"name": "User Identification",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel identifies users in your product; Funnel.io works with aggregate marketing data"
},
{
"name": "Custom Event Properties",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel tracks custom events; Funnel.io imports predefined metrics from ad platforms"
},
{
"name": "Real-Time Event Tracking",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io syncs external data on schedules, not real-time user tracking"
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Funnel Analysis (User Behavior)",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel tracks conversion funnels in your product; Funnel.io reports on marketing funnels from ad platforms"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel tracks user retention over time"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel analyzes user cohorts based on behavior"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel creates profiles of individual users"
},
{
"name": "User Path/Journey Analysis",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel tracks user journeys through your product"
},
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not provide experimentation features"
}
]
},
{
"group": "Marketing Data Aggregation",
"features": [
{
"name": "Ad Platform Connectors",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io connects to 500+ marketing platforms (Google Ads, Facebook Ads, etc.)"
},
{
"name": "Marketing Spend Tracking",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io aggregates ad spend across all platforms"
},
{
"name": "Cross-Platform Marketing Reports",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io creates unified reports from multiple ad platforms"
},
{
"name": "Marketing ROI/ROAS Calculation",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io calculates marketing ROI across channels"
},
{
"name": "Marketing Mix Modeling",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io offers advanced MMM for enterprise customers"
},
{
"name": "Data Transformation Rules",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io provides data normalization and transformation"
}
]
},
{
"group": "Data Export & Integration",
"features": [
{
"name": "API Access",
"openpanel": true,
"competitor": true
},
{
"name": "Webhooks",
"openpanel": true,
"competitor": true
},
{
"name": "Data Warehouse Export",
"openpanel": true,
"competitor": true,
"notes": "Both export to BigQuery, Snowflake, etc."
},
{
"name": "Looker Studio Integration",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io has native Looker Studio connector"
},
{
"name": "Power BI Integration",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io has native Power BI connector"
},
{
"name": "Tableau Integration",
"openpanel": false,
"competitor": true,
"notes": "Funnel.io is a Tableau partner"
}
]
},
{
"group": "SDKs & Platforms",
"features": [
{
"name": "JavaScript SDK",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not provide tracking SDKs"
},
{
"name": "iOS SDK",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not track mobile apps directly"
},
{
"name": "Android SDK",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not track mobile apps directly"
},
{
"name": "React Native SDK",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io does not provide mobile SDKs"
},
{
"name": "Server-Side SDKs",
"openpanel": true,
"competitor": false,
"notes": "OpenPanel supports backend tracking"
}
]
},
{
"group": "Deployment & Hosting",
"features": [
{
"name": "Cloud Hosted",
"openpanel": true,
"competitor": true
},
{
"name": "Self-Hosted Option",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io is cloud-only with no self-hosting"
},
{
"name": "Open Source",
"openpanel": true,
"competitor": false,
"notes": "Funnel.io is proprietary closed-source"
},
{
"name": "EU Data Residency",
"openpanel": true,
"competitor": true,
"notes": "Both offer EU hosting options"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "These platforms use fundamentally different technical approaches because they solve different problems.",
"items": [
{
"label": "Deployment",
"openpanel": "Docker (self-hosted) or managed cloud",
"competitor": "Cloud SaaS only - no self-hosting",
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "No - Proprietary closed-source",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "Proprietary (Parquet-based storage)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Up to 2-3 years historical data import",
"notes": null
},
{
"label": "Integrations",
"openpanel": "Segment, webhooks, API, data warehouse export",
"competitor": "500+ marketing connectors, Looker Studio, Power BI, Tableau, BigQuery, Snowflake, Redshift",
"notes": null
},
{
"label": "Primary Data Source",
"openpanel": "Your website/app (via SDK tracking)",
"competitor": "External marketing platforms (via API connectors)",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel and Funnel.io have very different pricing models reflecting their different use cases.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. $0.00005 per event after free tier. All features included at every tier. No limits on users, dashboards, or data retention."
},
"competitor": {
"model": "Flexpoint-based, no free tier",
"description": "Free plan with limited connectors (100+ Starter connectors). Paid plans: Essentials ($399/month), Plus ($999/month), Enterprise ($1,999+/month). Pricing based on 'flexpoints' which depend on accounts connected and report types. Enterprise customers report spending $12,000-100,000+/year. Agency plans also available.",
"free_tier": "Free plan with 100+ Starter connectors and limited features",
"pricing_url": "https://funnel.io/pricing"
}
},
"migration": {
"title": "Migrating from Funnel.io to OpenPanel",
"intro": "Funnel.io and OpenPanel serve different purposes. You may need both tools rather than replacing one with the other.",
"difficulty": "not-applicable",
"estimated_time": "Varies - these tools serve different purposes",
"steps": [
{
"title": "Understand the Difference",
"description": "Funnel.io and OpenPanel serve different purposes. Funnel.io aggregates marketing data from ad platforms. OpenPanel tracks user behavior in your product. You may need both tools rather than replacing one with the other."
},
{
"title": "Install OpenPanel SDK",
"description": "If you need product analytics (user behavior tracking), add the OpenPanel SDK to your website or app. This gives you event tracking, funnels, retention analysis."
},
{
"title": "Keep Funnel.io for Marketing Data",
"description": "If you need cross-platform marketing reporting (aggregating Google Ads, Facebook Ads, etc.), you may want to keep Funnel.io. OpenPanel doesn't replace marketing data aggregation."
},
{
"title": "Connect Data Sources",
"description": "OpenPanel tracks your own product data. If you were using Funnel.io to import Google Analytics data, OpenPanel can replace that tracking directly with better product analytics features."
},
{
"title": "Set Up Product Analytics",
"description": "Configure funnels, retention analysis, and user identification in OpenPanel. These are product analytics features that Funnel.io does not provide."
}
],
"sdk_compatibility": {
"similar_api": false,
"notes": "These tools serve completely different purposes. Funnel.io imports data from external platforms via API connectors. OpenPanel tracks user behavior with client-side SDKs."
},
"historical_data": {
"can_import": false,
"notes": "Funnel.io and OpenPanel track different types of data. Funnel.io stores marketing platform data (ad spend, impressions, clicks from external sources). OpenPanel tracks user behavior within your product."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Funnel.io",
"intro": "Choose OpenPanel when you need to understand user behavior within your product. Funnel.io is for aggregating marketing data from external ad platforms.",
"items": [
{
"title": "Product Teams Needing User Behavior Analytics",
"description": "Funnel.io does not track user behavior - it imports data from external platforms. If you need to understand how users interact with your product (clicks, conversions, retention), OpenPanel provides the tracking SDKs and analytics Funnel.io lacks.",
"icon": "users"
},
{
"title": "Startups Wanting Affordable Analytics",
"description": "Funnel.io starts at $399/month with no free tier. OpenPanel offers a generous free tier (10,000 events/month) and transparent pricing, making it accessible for startups and small teams.",
"icon": "dollar-sign"
},
{
"title": "Teams Requiring Self-Hosting",
"description": "Funnel.io is cloud-only with no self-hosting option. If you need to host analytics on your own infrastructure for data privacy, compliance, or cost reasons, OpenPanel can be self-hosted via Docker.",
"icon": "server"
},
{
"title": "Open Source Requirements",
"description": "Funnel.io is proprietary closed-source software. If your organization requires open source tools for security audits or compliance, OpenPanel is fully open source under the MIT license.",
"icon": "code"
},
{
"title": "Mobile App Analytics",
"description": "Funnel.io does not provide mobile SDKs or track mobile app behavior. OpenPanel offers native iOS, Android, and React Native SDKs for tracking user behavior in mobile apps.",
"icon": "smartphone"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about the differences between Funnel.io and OpenPanel.",
"items": [
{
"question": "Is Funnel.io a product analytics tool?",
"answer": "No. Funnel.io is a marketing data integration platform that aggregates data from ad platforms (Google Ads, Facebook Ads, etc.) and exports it to BI tools. It does not track user behavior on your website or app. OpenPanel is a product analytics tool that tracks user behavior with SDKs."
},
{
"question": "Can Funnel.io replace OpenPanel?",
"answer": "No - they serve different purposes. Funnel.io aggregates marketing spend and campaign data from external platforms. OpenPanel tracks how users interact with your product. Most teams need both: OpenPanel for product analytics and something like Funnel.io for marketing reporting."
},
{
"question": "Does Funnel.io track user events on my website?",
"answer": "No. Funnel.io imports data from external platforms like Google Analytics, Google Ads, and Facebook Ads via API connectors. It does not provide tracking SDKs or directly track user behavior. For event tracking, you need a product analytics tool like OpenPanel."
},
{
"question": "Why is Funnel.io so expensive compared to OpenPanel?",
"answer": "Funnel.io's pricing (starting at $399/month) reflects its value proposition: maintaining 500+ API connectors to marketing platforms, handling data transformation, and providing BI tool integrations. OpenPanel tracks your own product data with lightweight SDKs, which has different cost structures."
},
{
"question": "Can I self-host Funnel.io?",
"answer": "No. Funnel.io is cloud-only SaaS with no self-hosting option. OpenPanel is open source (MIT license) and can be self-hosted via Docker for full data control."
},
{
"question": "Does Funnel.io have mobile SDKs?",
"answer": "No. Funnel.io does not provide tracking SDKs for any platform. It imports data from external sources via API connectors. OpenPanel provides native iOS, Android, and React Native SDKs for mobile app analytics."
},
{
"question": "Which tool should I use for conversion funnels?",
"answer": "It depends on what you're measuring. OpenPanel tracks user conversion funnels in your product (signup to purchase, onboarding completion). Funnel.io reports on marketing funnel metrics imported from ad platforms. They measure different things."
},
{
"question": "Can OpenPanel replace Funnel.io for marketing reporting?",
"answer": "Not directly. OpenPanel doesn't have connectors to import data from Google Ads, Facebook Ads, or other marketing platforms. If you need cross-platform marketing spend reporting, you'll still need a tool like Funnel.io or Supermetrics."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,546 @@
{
"slug": "goatcounter-alternative",
"page_type": "alternative",
"seo": {
"title": "GoatCounter Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs GoatCounter. Discover why teams choose OpenPanel as their GoatCounter alternative for deeper product analytics, user identification, and mobile SDKs while maintaining privacy and open source values.",
"noindex": false
},
"hero": {
"heading": "GoatCounter Alternative",
"subheading": "Love GoatCounter's simplicity and privacy focus? OpenPanel adds deeper product analytics - user identification, funnels, retention analysis, and mobile SDKs - while staying open source and cookie-free.",
"badges": [
"Open-source",
"Privacy-first",
"Product Analytics",
"Lightweight"
]
},
"competitor": {
"name": "GoatCounter",
"logo": "/logos/goatcounter.svg",
"url": "https://goatcounter.com",
"short_description": "Minimalist, privacy-focused, self-hosted web analytics created by solo developer Martin Tournoij.",
"founded": 2019,
"headquarters": "Netherlands"
},
"summary_comparison": {
"title": "OpenPanel vs GoatCounter: Which is right for you?",
"intro": "Both are privacy-focused open source analytics tools. GoatCounter is ultra-minimal for simple web stats. OpenPanel adds product analytics for user behavior tracking.",
"one_liner": "GoatCounter is minimal web analytics; OpenPanel adds product analytics with funnels, retention, and user identification.",
"best_for_openpanel": [
"SaaS products needing user-level analytics and retention tracking",
"Mobile app developers needing native iOS, Android, React Native SDKs",
"Teams needing funnel analysis and conversion tracking",
"High-volume analytics requiring ClickHouse performance at scale"
],
"best_for_competitor": [
"Personal blogs and small sites wanting simple stats",
"Developers wanting the simplest possible self-hosting (single binary + SQLite)",
"Privacy maximalists who want zero user identification",
"Projects wanting free hosted service with no usage limits"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and GoatCounter compare on key factors.",
"items": [
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. GoatCounter intentionally uses anonymous hashing without persistent user tracking to maximize privacy."
},
{
"label": "Funnel Analysis",
"openpanel": "Yes - Visual funnel builder",
"competitor": "No - Not available",
"notes": "OpenPanel provides funnel analysis to track conversion paths. GoatCounter focuses on simple page view and visitor statistics without conversion funnel features."
},
{
"label": "Mobile SDKs",
"openpanel": "iOS, Android, React Native",
"competitor": "Web only (JavaScript + tracking pixel)",
"notes": "OpenPanel offers native mobile SDKs for iOS, Android, and React Native. GoatCounter is designed for web analytics with JavaScript and tracking pixel options only."
},
{
"label": "Open Source License",
"openpanel": "MIT License",
"competitor": "EUPL 1.2 (copyleft)",
"notes": "OpenPanel uses the permissive MIT license. GoatCounter uses EUPL 1.2, a copyleft license requiring derivative works to use compatible licenses."
},
{
"label": "Free Hosted Service",
"openpanel": "10,000 events/month",
"competitor": "Unlimited (reasonable use)",
"notes": "GoatCounter offers free hosted service for personal sites and small-to-medium businesses with reasonable usage. OpenPanel offers 10,000 events/month free."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are open source and privacy-focused, but with different depths of capabilities.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources & Referrers",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter shows country-level location data"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "Screen Size",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter supports utm_campaign, utm_source parameters"
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter updates statistics every 10 seconds"
},
{
"name": "Session Tracking",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter uses rotating 4-hour salted hash for sessions"
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter supports events via data-goatcounter-click attribute"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter focuses on simple metrics without funnels"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter doesn't track user retention over time"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter intentionally doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter provides aggregate statistics only"
},
{
"name": "User Path/Journey Analysis",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter doesn't track user journeys"
},
{
"name": "User Identification",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter uses anonymous hashing, no persistent user IDs"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter is analytics-only, no experimentation"
},
{
"name": "Custom Properties on Events",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter supports title and referrer on events"
},
{
"name": "Public Dashboards",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter has unique public stats sharing feature"
},
{
"name": "CLI Dashboard",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter has terminal-based dashboard command"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": false,
"notes": "GoatCounter doesn't have automated email reports"
},
{
"name": "Tracking Pixel (No-JS)",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter supports JavaScript-free tracking via 1x1 GIF"
},
{
"name": "Log File Import",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter can import nginx, Apache, Caddy, CloudFront logs"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter designed to not require GDPR consent notices"
},
{
"name": "No Personal Data Storage",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter uses rotating 4-hour salted hashes for anonymization"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": true
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter supports CSV export and full API access"
},
{
"name": "Bot Filtering",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter ignores bots that identify themselves"
}
]
},
{
"group": "SDKs & Platforms",
"features": [
{
"name": "JavaScript/Browser",
"openpanel": true,
"competitor": true
},
{
"name": "iOS SDK",
"openpanel": true,
"competitor": false
},
{
"name": "Android SDK",
"openpanel": true,
"competitor": false
},
{
"name": "React Native SDK",
"openpanel": true,
"competitor": false
},
{
"name": "Server-Side API",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter has backend integration API"
},
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter has comprehensive /api/v0 endpoints"
}
]
},
{
"group": "Deployment",
"features": [
{
"name": "Cloud Hosted",
"openpanel": true,
"competitor": true
},
{
"name": "Docker Support",
"openpanel": true,
"competitor": true,
"notes": "GoatCounter available on DockerHub at arp242/goatcounter"
},
{
"name": "Single Binary Deployment",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter is a ~7MB statically compiled binary"
},
{
"name": "SQLite Support",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter can run on simple SQLite database"
},
{
"name": "PostgreSQL Support",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter supports PostgreSQL for larger sites"
},
{
"name": "Built-in TLS/ACME",
"openpanel": false,
"competitor": true,
"notes": "GoatCounter includes automatic Let's Encrypt certificates"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "~3.5 KB",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"Tracking Pixel (no-JS)",
"Backend API",
"Log file import (nginx, Apache, Caddy, CloudFront)"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Yes - EUPL 1.2 (copyleft)",
"notes": "OpenPanel uses MIT license. GoatCounter uses EUPL 1.2 (copyleft). GoatCounter has 5,200+ GitHub stars."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Single binary (~7MB) or Docker. SQLite or PostgreSQL. Built-in ACME/TLS support.",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "SQLite (default, recommended for most) or PostgreSQL (for load balancing)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Unlimited (self-hosted), unlimited (hosted free)",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Go (Golang)",
"notes": null
},
{
"label": "Performance",
"openpanel": "ClickHouse optimized for analytics queries",
"competitor": "~800 hits/second on $5/month VPS. 99.9% requests answered within ~2ms.",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "GoatCounter is donation-supported. OpenPanel offers both free cloud and self-hosting.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "Donation-supported or free self-hosting",
"description": "Hosted: Free for reasonable public usage (personal sites, small-to-medium businesses). Self-hosted: Completely free. Donations encouraged via GitHub Sponsors for sustainability. Not designed for high-volume enterprise use cases.",
"free_tier": "Free for reasonable use",
"pricing_url": null
}
},
"migration": {
"title": "Migrating from GoatCounter to OpenPanel",
"intro": "Both use lightweight scripts and simple event tracking, making migration straightforward.",
"difficulty": "easy",
"estimated_time": "30 minutes to 1 hour",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts (GoatCounter ~3.5KB, OpenPanel ~2.3KB gzipped), making the transition easy."
},
{
"title": "Map Custom Events",
"description": "GoatCounter click events using data-goatcounter-click attribute translate to OpenPanel's op.track() calls. Map your event names and any custom properties."
},
{
"title": "Add User Identification (New)",
"description": "Unlike GoatCounter which uses anonymous hashing, OpenPanel supports user identification. Add op.identify() calls to unlock user profiles, retention analysis, and cohort features."
},
{
"title": "Set Up Funnels and Analytics (New)",
"description": "GoatCounter doesn't have funnels or retention analysis. Set up these features in OpenPanel to gain deeper product insights you couldn't get before."
},
{
"title": "Remove GoatCounter Script",
"description": "Once verified, remove the GoatCounter tracking script. Both are cookie-free so no consent flow changes are needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use simple event tracking approaches."
},
"historical_data": {
"can_import": false,
"notes": "GoatCounter intentionally anonymizes data. Most teams start fresh with OpenPanel."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than GoatCounter",
"intro": "Choose OpenPanel when you need product analytics beyond simple web stats.",
"items": [
{
"title": "SaaS Products Needing User Identification",
"description": "GoatCounter uses anonymous hashing by design. If you need to track logged-in users, understand individual customer journeys, or analyze user-level retention, OpenPanel provides these capabilities while still respecting privacy.",
"icon": "user-check"
},
{
"title": "Mobile App Analytics",
"description": "GoatCounter is designed for web analytics with JavaScript and tracking pixels only. OpenPanel provides native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams Needing Funnel Analysis",
"description": "GoatCounter focuses on simple metrics like page views, visitors, and referrers without conversion funnels. If you need to track user conversion paths and identify drop-offs, OpenPanel's funnel analysis provides these insights.",
"icon": "filter"
},
{
"title": "Products Requiring Retention Analysis",
"description": "GoatCounter doesn't track user retention over time. If you need to understand how many users return after signup or measure engagement over weeks and months, OpenPanel's retention analysis delivers these metrics.",
"icon": "repeat"
},
{
"title": "High-Volume Analytics at Scale",
"description": "GoatCounter is an indie project optimized for personal sites and small-to-medium businesses. For enterprise-scale analytics with millions of events, OpenPanel's ClickHouse backend is designed for high-volume workloads.",
"icon": "trending-up"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from GoatCounter to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as GoatCounter?",
"answer": "Both are cookie-free by default and GDPR compliant. GoatCounter uses rotating 4-hour salted hashes for maximum anonymization. OpenPanel allows optional user identification for product analytics. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from GoatCounter to OpenPanel?",
"answer": "Teams typically switch when they need user identification, funnel analysis, retention tracking, or mobile SDKs. GoatCounter excels at simple, privacy-first web analytics for content sites and blogs. For products requiring deeper user behavior insights, OpenPanel provides these capabilities."
},
{
"question": "How does GoatCounter's pricing compare to OpenPanel?",
"answer": "GoatCounter is free for reasonable public use (personal sites, small-to-medium businesses) and completely free when self-hosted. It's donation-supported. OpenPanel offers 10,000 events/month free with paid tiers after that. Both have free self-hosting options."
},
{
"question": "Which has the smaller tracking script?",
"answer": "OpenPanel's script is slightly smaller at 2.3KB gzipped compared to GoatCounter's ~3.5KB. Both are significantly smaller than Google Analytics (45KB+) or Mixpanel. GoatCounter also offers a JavaScript-free tracking pixel option."
},
{
"question": "Can GoatCounter track mobile apps?",
"answer": "Not with native SDKs. GoatCounter is designed for web analytics using JavaScript or tracking pixels. It has a backend API for server-side tracking but no mobile SDKs. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "Does GoatCounter support funnels or retention analysis?",
"answer": "No. GoatCounter focuses on simple metrics: page views, visitors, referrers, browsers, locations, and campaigns. It's intentionally simple and doesn't include product analytics features like funnels, retention, or cohort analysis."
},
{
"question": "How does self-hosting compare?",
"answer": "GoatCounter is extremely easy to self-host: a single ~7MB statically compiled Go binary with SQLite as default database. It includes built-in TLS/ACME certificate generation. OpenPanel uses Docker with ClickHouse. GoatCounter is simpler; OpenPanel scales better."
},
{
"question": "What license does GoatCounter use?",
"answer": "GoatCounter uses EUPL 1.2 (European Union Public License), a copyleft license requiring derivative works to use compatible licenses. OpenPanel uses the permissive MIT license which allows any use including proprietary derivatives."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,465 @@
{
"slug": "google-analytics-alternative",
"page_type": "alternative",
"seo": {
"title": "Google Analytics alternative",
"description": "Compare OpenPanel with Google Analytics: privacy, simplicity, self-hosting, and features. OpenPanel offers cookie-free analytics with EU-only hosting and no data sent to Google.",
"noindex": false
},
"hero": {
"heading": "Google Analytics alternative",
"subheading": "OpenPanel is an open-source, privacy-first alternative to Google Analytics. Get both web analytics and product analytics in one tool, without cookies, consent banners, or sending your data to Google.",
"badges": [
"Open-source",
"Cookie-free",
"EU-only hosting",
"Self-hostable"
]
},
"competitor": {
"name": "Google Analytics",
"logo": "/logos/google-analytics.svg",
"url": "https://analytics.google.com",
"short_description": "Free web analytics platform from Google that tracks website traffic, user behavior, and conversions with deep integration into the Google ecosystem.",
"founded": 2005,
"headquarters": "Mountain View, CA"
},
"summary_comparison": {
"title": "OpenPanel vs Google Analytics: Which is right for you?",
"intro": "Both platforms help you understand website traffic and user behavior. The key differences are privacy approach, data ownership, and simplicity vs ecosystem integration.",
"one_liner": "OpenPanel is privacy-focused and independent; Google Analytics is free but sends your data to Google.",
"best_for_openpanel": [
"Privacy-conscious teams who want analytics without cookies or consent banners",
"Businesses that need EU-only data storage for GDPR compliance",
"Developers who want to self-host and own their data completely",
"Teams looking for both web analytics and product analytics in one tool"
],
"best_for_competitor": [
"Teams heavily invested in the Google Ads ecosystem",
"Organizations needing advanced attribution modeling for marketing",
"Large enterprises with dedicated analytics teams and complex reporting needs",
"Users who need the free tier and can accept the privacy tradeoffs"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Google Analytics compare on the factors that matter most.",
"items": [
{
"label": "Price",
"openpanel": "From $2.50/month (or free self-hosted)",
"competitor": "Free (360 starts at $50k/year)"
},
{
"label": "Cookies required",
"openpanel": "No (cookie-free by default)",
"competitor": "Yes (first-party cookies)"
},
{
"label": "Consent banner needed",
"openpanel": "No",
"competitor": "Yes (for GDPR/ePrivacy)"
},
{
"label": "Data location",
"openpanel": "EU-only (or your own servers)",
"competitor": "US (Google servers)"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel combines web analytics with product analytics. Google Analytics focuses on marketing and traffic analysis with deep Google integration.",
"groups": [
{
"group": "Web analytics",
"features": [
{
"name": "Page views & visitors",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Traffic sources",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Geographic data",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Device & browser stats",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "UTM tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time dashboard",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Product analytics",
"features": [
{
"name": "Custom event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": "GA4 funnels available via Explorations"
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": "GA4 uses User Properties"
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Revenue tracking",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": false,
"notes": "Google Optimize was shut down in 2023"
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": "GA4 uses Explorations for custom reports"
},
{
"name": "AI insights",
"openpanel": true,
"competitor": true,
"notes": "GA4 has machine learning predictions"
},
{
"name": "Attribution modeling",
"openpanel": false,
"competitor": true,
"notes": "GA4 has data-driven attribution"
},
{
"name": "Enhanced autocapture",
"openpanel": false,
"competitor": true,
"notes": "GA4 auto-tracks scrolls, clicks, downloads"
},
{
"name": "Notifications/Alerts",
"openpanel": true,
"competitor": true,
"notes": "OpenPanel supports webhooks, Slack, Discord"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Cookie-free tracking",
"openpanel": true,
"competitor": false,
"notes": "GA4 requires first-party cookies"
},
{
"name": "No consent banner needed",
"openpanel": true,
"competitor": false,
"notes": "GA4 requires consent under GDPR/ePrivacy"
},
{
"name": "EU data residency",
"openpanel": true,
"competitor": false,
"notes": "GA4 processes data on US servers"
},
{
"name": "IP anonymization",
"openpanel": true,
"competitor": true,
"notes": "GA4 does this by default"
},
{
"name": "Self-hosting option",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "DPA available",
"openpanel": "on request",
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": "GA4 360 needed for full BigQuery export"
},
{
"name": "Google Ads integration",
"openpanel": false,
"competitor": true,
"notes": "Native GA4 integration"
},
{
"name": "Google Search Console",
"openpanel": false,
"competitor": true,
"notes": "Native GA4 integration"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the SDKs and technical implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~30+ KB gzipped",
"notes": "OpenPanel's SDK is significantly lighter for better page performance"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Node.js",
"Python",
"Swift",
"Kotlin",
"React Native",
"Astro",
"Remix",
"Express"
],
"competitor": [
"JavaScript",
"iOS (via Firebase)",
"Android (via Firebase)",
"Flutter",
"Unity",
"AMP"
],
"notes": "GA4 mobile tracking requires Firebase SDK"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup script",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary Google infrastructure",
"notes": "OpenPanel gives you direct SQL access to your data"
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted) or plan-based",
"competitor": "2-14 months (free), up to 50 months (360)",
"notes": "GA4 has strict retention limits on the free tier"
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Google Analytics is free for most users, but comes with privacy tradeoffs and data limits. OpenPanel offers more control.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing starting at $2.50/month for 5,000 events. 100,000 events costs $20/month. Self-host for free with unlimited events. No limits on users, dashboards, or data retention."
},
"competitor": {
"model": "Freemium with enterprise tier",
"description": "GA4 is free with limits: data sampling at high volumes, 14-month max data retention, limited explorations. GA4 360 (enterprise) starts at $50,000/year for higher limits and support.",
"free_tier": "Yes (with significant limits)",
"pricing_url": "https://marketingplatform.google.com/about/analytics/"
}
},
"migration": {
"title": "Migrating from Google Analytics to OpenPanel",
"intro": "Switching from Google Analytics to OpenPanel is straightforward. You can run both in parallel during transition.",
"difficulty": "easy",
"estimated_time": "1-2 hours",
"steps": [
{
"title": "Install the OpenPanel script",
"description": "Add the lightweight OpenPanel script to your website. It's a single line of code, similar to the GA4 gtag but much smaller."
},
{
"title": "Set up event tracking",
"description": "Map your GA4 custom events to OpenPanel. The track() API is similar and most events translate directly."
},
{
"title": "Configure dashboards",
"description": "Set up your reports and dashboards in OpenPanel. The interface is simpler than GA4's Explorations."
},
{
"title": "Run in parallel",
"description": "Keep both tools running for a week or two to compare data and ensure everything is tracking correctly."
},
{
"title": "Remove Google Analytics",
"description": "Once verified, remove the GA4 script. You can also remove your cookie consent banner if it was only needed for analytics."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "OpenPanel uses a simple track() API. GA4 events like gtag('event', 'purchase', {...}) translate to op.track('purchase', {...})."
},
"historical_data": {
"can_import": false,
"notes": "Google Analytics does not provide easy data export. Historical data stays in GA4. Start fresh with OpenPanel for cleaner, privacy-compliant data."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Google Analytics",
"intro": "OpenPanel shines for teams that prioritize privacy, simplicity, and data ownership over the Google ecosystem.",
"items": [
{
"title": "GDPR-compliant websites",
"description": "No cookies, no consent banners, EU-only data storage. Meet privacy regulations without compromising on analytics.",
"icon": "shield"
},
{
"title": "Marketing without Google",
"description": "If you don't rely on Google Ads, you don't need Google Analytics. Get cleaner, faster analytics without sending data to Google.",
"icon": "chart"
},
{
"title": "Self-hosted requirements",
"description": "Deploy OpenPanel on your own infrastructure for complete data ownership. Perfect for regulated industries or security-conscious teams.",
"icon": "server"
},
{
"title": "Web + product analytics combined",
"description": "Get Plausible-style web analytics and product analytics (funnels, retention, cohorts) in one tool instead of multiple subscriptions.",
"icon": "layers"
},
{
"title": "Faster websites",
"description": "OpenPanel's 2.3 KB SDK vs GA4's 30+ KB means better Core Web Vitals, faster page loads, and improved SEO.",
"icon": "zap"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Google Analytics to OpenPanel.",
"items": [
{
"question": "Is Google Analytics free?",
"answer": "Yes, GA4 is free but comes with significant tradeoffs: your data goes to Google, cookies require consent banners, data retention is limited to 14 months, and high-traffic sites experience data sampling. GA4 360 (enterprise) costs $50,000+/year."
},
{
"question": "Why switch from Google Analytics?",
"answer": "Common reasons include: privacy concerns (data sent to Google), GDPR compliance (cookies require consent), complexity (GA4 has a steep learning curve), and data ownership (you can't self-host or fully export your data)."
},
{
"question": "Do I need a cookie consent banner with OpenPanel?",
"answer": "No. OpenPanel is cookie-free by default and doesn't collect personal data, so no consent banner is required for analytics. This improves user experience and conversion rates."
},
{
"question": "Is OpenPanel GDPR compliant?",
"answer": "Yes. OpenPanel is EU-based (Sweden), uses cookie-free tracking, hashes IP addresses with daily rotating salts, and stores data on EU servers. We also offer DPA agreements on request."
},
{
"question": "Can I import my Google Analytics data?",
"answer": "Google Analytics doesn't provide easy data export for migration. We recommend running OpenPanel in parallel with GA4 briefly, then starting fresh with OpenPanel for cleaner, privacy-compliant data."
},
{
"question": "How does OpenPanel track users without cookies?",
"answer": "OpenPanel uses a privacy-friendly approach: IP addresses and user agents are hashed together with a daily rotating salt. This allows accurate visitor counting (within a 24-hour window) without storing any personal data."
},
{
"question": "Does OpenPanel integrate with Google Ads?",
"answer": "No, OpenPanel doesn't have native Google Ads integration. If you rely heavily on Google Ads conversion tracking and attribution, GA4 remains the better choice for that specific use case."
},
{
"question": "How does the SDK size affect my website?",
"answer": "OpenPanel's JavaScript SDK is ~2.3 KB gzipped compared to GA4's 30+ KB. This means faster page loads, better Core Web Vitals scores, and potentially improved SEO rankings."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,430 @@
{
"slug": "heap-alternative",
"page_type": "alternative",
"seo": {
"title": "Heap Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Heap. Discover why teams choose OpenPanel as their Heap alternative for transparent pricing, self-hosting, open source freedom, and lightweight analytics without autocapture complexity.",
"noindex": false
},
"hero": {
"heading": "Heap alternative",
"subheading": "Looking for Heap's product analytics without the black-box pricing and vendor lock-in? OpenPanel offers transparent event-based pricing, full self-hosting, and MIT-licensed open source code—giving you control over your analytics.",
"badges": [
"Open-source",
"Transparent pricing",
"Self-hostable",
"No vendor lock-in"
]
},
"competitor": {
"name": "Heap",
"logo": "/logos/heap.svg",
"url": "https://heap.io",
"short_description": "Product analytics platform known for autocapture technology that automatically tracks all user interactions. Now part of Contentsquare.",
"founded": 2013,
"headquarters": "San Francisco, CA"
},
"summary_comparison": {
"title": "OpenPanel vs Heap: Which is right for you?",
"intro": "Both platforms provide product analytics, but with different philosophies. Heap's autocapture records everything automatically; OpenPanel uses explicit tracking for better control.",
"one_liner": "OpenPanel is transparent, self-hostable, and open source; Heap offers autocapture and retroactive analysis with opaque enterprise pricing.",
"best_for_openpanel": [
"Teams needing transparent, predictable pricing without sales calls",
"Organizations requiring self-hosting for data sovereignty",
"Open source requirements for transparency and auditability",
"Teams wanting controlled data collection without bloat",
"Startups avoiding vendor lock-in after Contentsquare acquisition"
],
"best_for_competitor": [
"Teams wanting autocapture to avoid manual event tracking",
"Organizations needing retroactive analysis for new events",
"Companies requiring visual event definition tools",
"Enterprise teams with budget for premium features",
"Teams needing session replay and heatmaps (add-ons)"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Heap compare on the factors that matter most.",
"items": [
{
"label": "Pricing transparency",
"openpanel": "Public, event-based pricing",
"competitor": "Opaque (requires sales call)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, completely free",
"competitor": "No (cloud only)"
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary)"
},
{
"label": "Autocapture",
"openpanel": "Manual event tracking",
"competitor": "Automatic capture"
},
{
"label": "Retroactive analysis",
"openpanel": "Tracked events only",
"competitor": "Full historical analysis"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel covers core product analytics, while Heap extends into autocapture and visual analytics tools.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Page views & sessions",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "Autocapture",
"openpanel": false,
"competitor": true,
"notes": "Heap automatically captures all interactions"
},
{
"name": "Retroactive analysis",
"openpanel": false,
"competitor": true,
"notes": "Heap can analyze historical data for new events"
},
{
"name": "Visual event definition",
"openpanel": false,
"competitor": true,
"notes": "Heap's no-code event creation"
},
{
"name": "A/B testing",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Session replay",
"openpanel": false,
"competitor": true,
"notes": "Heap offers as paid add-on"
},
{
"name": "Heatmaps",
"openpanel": false,
"competitor": true,
"notes": "Heap offers as paid add-on"
},
{
"name": "Path analysis",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Privacy & deployment",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "EU data residency",
"openpanel": "Via self-hosting",
"competitor": "Premier plan only",
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data warehouse export",
"openpanel": true,
"competitor": true,
"notes": "Heap Connect exports to major warehouses"
},
{
"name": "Segment integration",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "100+ integrations",
"openpanel": false,
"competitor": true,
"notes": null
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the SDKs and technical implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "Larger (autocapture overhead)",
"notes": "OpenPanel's lighter SDK means faster page loads"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python"
],
"competitor": [
"JavaScript",
"iOS",
"Android",
"React Native",
"Flutter"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary",
"notes": null
},
{
"label": "Tracking method",
"openpanel": "Explicit event tracking",
"competitor": "Autocapture everything",
"notes": "Different philosophies on data collection"
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers transparent pricing. Heap requires sales calls for anything beyond the free tier.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing starting at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Session-based, opaque",
"description": "Free tier: 10K sessions/month, 6 months data retention. Growth/Pro/Premier plans require custom quotes from sales. Reports suggest Growth plans start around $3,600/year.",
"free_tier": "Yes (10K sessions/month)",
"pricing_url": "https://heap.io/pricing"
}
},
"migration": {
"title": "Migrating from Heap to OpenPanel",
"intro": "Switching from Heap requires rethinking your tracking strategy since OpenPanel doesn't autocapture.",
"difficulty": "moderate",
"estimated_time": "2-8 hours depending on event complexity",
"steps": [
{
"title": "Audit your Heap events",
"description": "Review which events you actually use in Heap dashboards and funnels. Identify the essential events since OpenPanel won't autocapture everything."
},
{
"title": "Install OpenPanel SDK",
"description": "Replace Heap's snippet with OpenPanel's lightweight SDK. The SDK is smaller and won't autocapture."
},
{
"title": "Implement event tracking",
"description": "Unlike Heap's autocapture, OpenPanel requires explicit event tracking. Instrument the key events you identified using op.track() calls."
},
{
"title": "Set up user identification",
"description": "Replace heap.identify() with OpenPanel's identify() method. Both platforms support similar user identification patterns."
},
{
"title": "Recreate funnels and reports",
"description": "Build your conversion funnels, retention charts, and dashboards in OpenPanel."
}
],
"sdk_compatibility": {
"similar_api": false,
"notes": "Different tracking philosophies: Heap autocaptures everything, OpenPanel requires explicit tracking. Plan to instrument your key events."
},
"historical_data": {
"can_import": false,
"notes": "Heap's proprietary data format makes historical migration complex. Contact us if you need assistance."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Heap",
"intro": "OpenPanel shines for teams that value transparency, control, and avoiding vendor lock-in.",
"items": [
{
"title": "Teams needing transparent pricing",
"description": "Heap's pricing is opaque and requires sales calls. OpenPanel offers transparent event-based pricing so you always know what you'll pay.",
"icon": "dollar"
},
{
"title": "Self-hosting and data sovereignty",
"description": "Heap is cloud-only. OpenPanel can be fully self-hosted with Docker, keeping all data on your own infrastructure.",
"icon": "server"
},
{
"title": "Open source requirements",
"description": "Heap is completely proprietary. OpenPanel is fully open source under MIT license, allowing inspection and modification.",
"icon": "code"
},
{
"title": "Controlled data collection",
"description": "Heap's autocapture collects everything by default. OpenPanel gives you explicit control over what data is collected.",
"icon": "shield"
},
{
"title": "Avoiding vendor lock-in",
"description": "Heap was acquired by Contentsquare. OpenPanel's open source model prevents vendor lock-in and pricing uncertainty.",
"icon": "lock"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Heap to OpenPanel.",
"items": [
{
"question": "What is Heap's autocapture and why might I not want it?",
"answer": "Heap's autocapture automatically records every user interaction without manual tracking code. While convenient, it can lead to data bloat, higher costs, privacy concerns (capturing sensitive data accidentally), and difficulty managing what's tracked. OpenPanel's explicit tracking gives you full control over data collection."
},
{
"question": "Can I self-host Heap?",
"answer": "No. Heap is cloud-only with no self-hosting option. Your data always resides on Heap/Contentsquare's infrastructure. OpenPanel offers full self-hosting with Docker for complete data ownership."
},
{
"question": "Is Heap open source?",
"answer": "No. Heap is entirely proprietary with closed-source code. OpenPanel is fully open source under the MIT license."
},
{
"question": "Why is Heap's pricing not public?",
"answer": "Heap only shows its Free tier publicly. Growth, Pro, and Premier plans require contacting sales for custom quotes. Reports suggest Growth plans start around $3,600/year, with costs scaling significantly at higher volumes."
},
{
"question": "What happened to Heap? Was it acquired?",
"answer": "Yes. Contentsquare acquired Heap in September 2023. Heap is now part of Contentsquare's experience intelligence platform. This acquisition may affect Heap's product direction, pricing, and independence."
},
{
"question": "Does OpenPanel have retroactive analysis like Heap?",
"answer": "No. Heap's autocapture enables retroactive analysis. OpenPanel only analyzes events that were explicitly tracked. This is a trade-off: Heap offers flexibility but with data bloat; OpenPanel offers control but requires upfront planning."
},
{
"question": "Does OpenPanel have session replay?",
"answer": "No. Heap offers session replay as an add-on on Pro and Premier plans. OpenPanel focuses on product analytics without session replay or heatmaps."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,469 @@
{
"slug": "matomo-alternative",
"page_type": "alternative",
"seo": {
"title": "Matomo alternative",
"description": "Compare OpenPanel with Matomo: simpler setup, truly cookie-free tracking, and modern UI. Get web and product analytics without the complexity of self-hosting or premium plugin costs.",
"noindex": false
},
"hero": {
"heading": "Matomo alternative",
"subheading": "OpenPanel is a modern, open-source alternative to Matomo. Get powerful web and product analytics with a cleaner interface, truly cookie-free tracking by default, and no premium plugins required for essential features.",
"badges": [
"Open-source",
"Cookie-free",
"EU-only hosting",
"Self-hostable"
]
},
"competitor": {
"name": "Matomo",
"logo": "/logos/matomo.svg",
"url": "https://matomo.org",
"short_description": "Open-source web analytics platform offering self-hosted and cloud options with a focus on privacy and data ownership, used by over 1.4 million websites globally.",
"founded": 2007,
"headquarters": "Wellington, New Zealand"
},
"summary_comparison": {
"title": "OpenPanel vs Matomo: Which is right for you?",
"intro": "Both platforms are open-source and privacy-focused. The key differences are modern UI, true cookie-free tracking, SDK size, and feature bundling vs premium plugins.",
"one_liner": "OpenPanel is modern and simple with all features included; Matomo is mature and established but requires premium plugins for advanced features.",
"best_for_openpanel": [
"Teams that want modern UI/UX without legacy complexity",
"Developers who need truly cookie-free tracking without configuration",
"Companies that want funnels, cohorts, and retention without extra costs",
"Startups and SMBs looking for lighter SDKs and faster setup"
],
"best_for_competitor": [
"Organizations already invested in the Matomo ecosystem",
"Enterprises needing CNIL-approved consent-exempt analytics",
"Teams requiring heatmaps and session recordings",
"Large self-hosted deployments with existing PHP/MySQL infrastructure"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Matomo compare on the factors that matter most.",
"items": [
{
"label": "Price",
"openpanel": "From $2.50/month (or free self-hosted)",
"competitor": "Free self-hosted, Cloud from $19/month"
},
{
"label": "Cookies required",
"openpanel": "No (cookie-free by default)",
"competitor": "Yes by default (cookieless requires config)"
},
{
"label": "Consent banner needed",
"openpanel": "No",
"competitor": "Yes (unless configured for CNIL exemption)"
},
{
"label": "Data location",
"openpanel": "EU-only (or your own servers)",
"competitor": "Frankfurt (Cloud) or self-hosted"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "Yes (GPL-3.0)"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel includes all analytics features in one package. Matomo's advanced features require purchasing premium plugins separately.",
"groups": [
{
"group": "Web analytics",
"features": [
{
"name": "Page views & visitors",
"openpanel": true,
"competitor": true,
"notes": "Both offer unsampled data"
},
{
"name": "Traffic sources",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Geographic data",
"openpanel": true,
"competitor": true,
"notes": "Matomo offers city-level geolocation"
},
{
"name": "Device & browser stats",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "UTM/campaign tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time dashboard",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Product analytics",
"features": [
{
"name": "Custom event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": "premium",
"notes": "Matomo Funnels is a paid plugin"
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": "Matomo has Visitor Log"
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": "Via segmentation"
},
{
"name": "E-commerce tracking",
"openpanel": true,
"competitor": true,
"notes": "Both have e-commerce analytics"
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": "premium",
"notes": "Matomo A/B Testing is a paid plugin"
},
{
"name": "Heatmaps",
"openpanel": false,
"competitor": "premium",
"notes": "Matomo plugin costs extra"
},
{
"name": "Session recordings",
"openpanel": false,
"competitor": "premium",
"notes": "Matomo plugin costs extra"
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Form analytics",
"openpanel": false,
"competitor": "premium",
"notes": "Matomo Form Analytics is paid"
},
{
"name": "Tag Manager",
"openpanel": false,
"competitor": true,
"notes": "Matomo Tag Manager is free"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Cookie-free by default",
"openpanel": true,
"competitor": false,
"notes": "Matomo uses cookies unless configured otherwise"
},
{
"name": "No consent banner needed",
"openpanel": true,
"competitor": false,
"notes": "Matomo can achieve CNIL exemption with config"
},
{
"name": "IP anonymization",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "GDPR compliance",
"openpanel": true,
"competitor": true,
"notes": "Both are GDPR compliant"
},
{
"name": "Self-hosting option",
"openpanel": true,
"competitor": true,
"notes": "Both can be self-hosted"
},
{
"name": "EU data hosting",
"openpanel": true,
"competitor": true,
"notes": "Matomo Cloud in Frankfurt, Germany"
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Matomo has extensive API"
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": "Both support data export"
},
{
"name": "WordPress plugin",
"openpanel": true,
"competitor": true,
"notes": "Matomo has dedicated WordPress version"
},
{
"name": "E-commerce platforms",
"openpanel": true,
"competitor": true,
"notes": "Matomo: WooCommerce, Shopify, Magento, PrestaShop"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the SDKs and technical implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~20 KB gzipped (60 KB uncompressed)",
"notes": "OpenPanel's SDK is significantly lighter"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Node.js",
"Python",
"Swift",
"Kotlin",
"React Native",
"Astro",
"Remix",
"Express"
],
"competitor": [
"JavaScript",
"PHP",
"iOS",
"Android",
"React Native",
"Flutter",
"Java",
"Python",
"C#",
"WordPress"
],
"notes": "Matomo has more native integrations for CMS platforms"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "Yes (GPL-3.0), premium plugins are proprietary",
"notes": "Matomo core is open, premium features are paid"
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup script",
"competitor": "PHP/MySQL stack, more complex setup",
"notes": "OpenPanel has simpler Docker-based deployment"
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "MySQL/MariaDB",
"notes": "ClickHouse offers better performance for analytics queries"
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted) or plan-based",
"competitor": "Unlimited (configurable), Cloud has plan-based raw data limits",
"notes": "Both offer flexible retention policies"
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Both offer free self-hosted options. Cloud pricing differs, and Matomo's premium plugins add significant costs.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing starting at $2.50/month for 5,000 events. 100,000 events costs $20/month. Self-host for free with unlimited events. All features included in every plan."
},
"competitor": {
"model": "Hit-based (Cloud) plus premium plugins",
"description": "On-Premise: Free (core features), but premium plugins like Heatmaps ($229/year), A/B Testing ($229/year), Funnels ($229/year) add up. Cloud: Starts at $19/month for 50,000 hits, scaling to $16,900/month for 100M hits. Premium Bundle saves up to 45% on plugins.",
"free_tier": "Yes (On-Premise is free, limited features)",
"pricing_url": "https://matomo.org/pricing/"
}
},
"migration": {
"title": "Migrating from Matomo to OpenPanel",
"intro": "Switching from Matomo to OpenPanel is straightforward. Both use event-based tracking, and you can run both tools in parallel during transition.",
"difficulty": "easy",
"estimated_time": "1-3 hours",
"steps": [
{
"title": "Install the OpenPanel SDK",
"description": "Add the lightweight OpenPanel SDK to your app. At 2.3 KB, it's much smaller than Matomo's 20 KB tracker."
},
{
"title": "Map your tracked events",
"description": "Review your Matomo tracking and map events to OpenPanel. Event tracking syntax is similar: _paq.push(['trackEvent', ...]) becomes op.track('event', ...)."
},
{
"title": "Configure user identification",
"description": "Set up user identification in OpenPanel. Replace Matomo's setUserId with OpenPanel's identify method."
},
{
"title": "Set up your dashboards",
"description": "Create key reports in OpenPanel. You'll get funnels and cohorts included without needing premium plugins."
},
{
"title": "Remove Matomo consent banner",
"description": "Since OpenPanel is cookie-free, you can remove the cookie consent banner you needed for Matomo (unless required for other tools)."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking. Matomo's _paq.push(['trackEvent', 'category', 'action']) becomes op.track('action', {category: 'category'})."
},
"historical_data": {
"can_import": false,
"notes": "Matomo data can be exported but there's no direct import path. Most teams start fresh with OpenPanel."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Matomo",
"intro": "OpenPanel shines for teams that want modern analytics without managing PHP infrastructure or paying for premium plugins.",
"items": [
{
"title": "Modern product teams",
"description": "Get a clean, modern interface designed for today's workflows. No legacy UI quirks or PHP-era design patterns.",
"icon": "sparkles"
},
{
"title": "All features without extra costs",
"description": "Funnels, cohorts, and A/B testing are included. With Matomo, these are premium plugins costing $229/year each.",
"icon": "package"
},
{
"title": "True cookie-free tracking",
"description": "OpenPanel is cookie-free by default. Matomo requires configuration changes and still needs consent in some jurisdictions.",
"icon": "shield"
},
{
"title": "Simpler self-hosting",
"description": "Deploy with Docker in minutes. No PHP/MySQL stack to manage, no plugin compatibility issues to debug.",
"icon": "server"
},
{
"title": "Faster websites",
"description": "OpenPanel's 2.3 KB SDK vs Matomo's 20 KB tracker means better performance and improved Core Web Vitals.",
"icon": "zap"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Matomo to OpenPanel.",
"items": [
{
"question": "Is Matomo free?",
"answer": "Matomo On-Premise (self-hosted) is free and open-source. However, many important features like Heatmaps, Session Recordings, A/B Testing, Funnels, and Form Analytics require purchasing premium plugins ($33-549/year each). Matomo Cloud starts at $19/month for 50,000 hits."
},
{
"question": "Why switch from Matomo?",
"answer": "Common reasons include: premium plugins add up quickly for essential features, the PHP/MySQL stack requires maintenance, the UI feels dated compared to modern tools, and configuring true cookieless tracking is complex. OpenPanel offers a simpler experience with all features included."
},
{
"question": "Do I need a cookie consent banner with Matomo?",
"answer": "By default, yes. Matomo uses first-party cookies and requires consent under GDPR. It can be configured for CNIL exemption (consent-free) in France and some EU countries, but this requires specific settings and limits some features. OpenPanel is cookie-free by default."
},
{
"question": "Can Matomo work without cookies?",
"answer": "Yes, but it requires configuration. You need to enable cookieless tracking, anonymize IPs, and disable features like User ID tracking. Even then, you may still need consent in some jurisdictions. OpenPanel's cookieless approach works by default without compromises."
},
{
"question": "What Matomo features will I lose?",
"answer": "OpenPanel doesn't have heatmaps, session recordings, form analytics, or a tag manager. If you rely heavily on these visual UX tools, Matomo may still be the better fit. However, you'll gain simpler setup and all core analytics features included."
},
{
"question": "Is Matomo GDPR compliant?",
"answer": "Yes, Matomo is GDPR compliant and is used by the European Commission. Matomo Cloud data is stored in Frankfurt, Germany. However, GDPR compliance doesn't automatically mean you can skip consent - that depends on your specific configuration and jurisdiction."
},
{
"question": "How does self-hosting compare?",
"answer": "Matomo requires PHP 7.2.5+ and MySQL/MariaDB, with additional configuration for performance at scale. OpenPanel uses Docker with ClickHouse for analytics queries, offering simpler deployment and better query performance for most use cases."
},
{
"question": "Is OpenPanel as mature as Matomo?",
"answer": "Matomo has been around since 2007 and is used by 1.4+ million websites. OpenPanel is newer but offers modern architecture, simpler setup, and all features included. For most analytics needs, OpenPanel provides equivalent or better functionality with less complexity."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,495 @@
{
"slug": "microsoft-clarity-alternative",
"page_type": "alternative",
"seo": {
"title": "Microsoft Clarity Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Microsoft Clarity. Discover why teams choose OpenPanel as their Clarity alternative for product analytics, user identification, retention analysis, and self-hosting capabilities.",
"noindex": false
},
"hero": {
"heading": "Microsoft Clarity Alternative",
"subheading": "Love Clarity's free heatmaps and session recordings? OpenPanel adds what Clarity lacks - product analytics, user identification, retention analysis, cohorts, and self-hosting - while staying privacy-friendly and open source.",
"badges": [
"Open-source",
"Product Analytics",
"Self-hostable",
"Retention Analysis"
]
},
"competitor": {
"name": "Microsoft Clarity",
"logo": "/logos/microsoft-clarity.svg",
"url": "https://clarity.microsoft.com",
"short_description": "Free behavioral analytics tool from Microsoft offering session recordings, heatmaps, and insights.",
"founded": 2020,
"headquarters": "Redmond, Washington, USA"
},
"summary_comparison": {
"title": "OpenPanel vs Microsoft Clarity: Which is right for you?",
"intro": "Clarity focuses on behavioral analytics (session recordings, heatmaps). OpenPanel focuses on product analytics (events, retention, cohorts). Different tools for different needs.",
"one_liner": "Clarity excels at behavioral observation (recordings, heatmaps); OpenPanel excels at product analytics (retention, cohorts, funnels).",
"best_for_openpanel": [
"SaaS products needing retention and cohort analysis",
"Teams requiring self-hosting for data sovereignty",
"Products needing user identification and profiles",
"Teams wanting A/B testing capabilities"
],
"best_for_competitor": [
"Teams needing session recordings and heatmaps (completely free)",
"Visual debugging of user frustration (rage clicks, dead clicks)",
"Organizations comfortable with Microsoft cloud hosting",
"Teams wanting AI-powered session insights (Copilot)"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Microsoft Clarity compare on key factors.",
"items": [
{
"label": "Analytics Focus",
"openpanel": "Product Analytics",
"competitor": "Behavioral Analytics",
"notes": "OpenPanel focuses on product analytics - funnels, retention, cohorts, and user journeys. Clarity focuses on behavioral analytics - session recordings and heatmaps. Different tools for different needs."
},
{
"label": "Self-Hosting",
"openpanel": "Yes - Full Docker deployment",
"competitor": "No - Cloud only",
"notes": "OpenPanel can be self-hosted with Docker, giving you complete data ownership. Microsoft Clarity is cloud-only with data stored on Microsoft Azure servers."
},
{
"label": "Session Recordings",
"openpanel": "No",
"competitor": "Yes - Unlimited free recordings",
"notes": "Clarity offers unlimited session recordings with visual playback of user sessions. OpenPanel focuses on event-based analytics rather than session replay."
},
{
"label": "Retention & Cohort Analysis",
"openpanel": "Yes - Built-in",
"competitor": "No",
"notes": "OpenPanel provides retention analysis and cohort tracking to understand user behavior over time. Clarity doesn't offer these product analytics features."
},
{
"label": "Pricing",
"openpanel": "Free tier + paid plans",
"competitor": "100% Free forever",
"notes": "Microsoft Clarity is completely free with no paid tiers, no traffic limits, and no restrictions. OpenPanel has a free tier with 10,000 events/month."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Clarity and OpenPanel serve different purposes - behavioral vs product analytics.",
"groups": [
{
"group": "Behavioral Analytics",
"features": [
{
"name": "Session Recordings",
"openpanel": false,
"competitor": true,
"notes": "Clarity offers unlimited session recordings with 30-day retention"
},
{
"name": "Click Heatmaps",
"openpanel": false,
"competitor": true
},
{
"name": "Scroll Heatmaps",
"openpanel": false,
"competitor": true
},
{
"name": "Rage Click Detection",
"openpanel": false,
"competitor": true,
"notes": "Clarity auto-detects frustration signals like rage clicks"
},
{
"name": "Dead Click Detection",
"openpanel": false,
"competitor": true
},
{
"name": "JavaScript Error Tracking",
"openpanel": false,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Clarity calls these Smart Events"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true,
"notes": "Clarity added funnels in 2024"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Clarity focuses on session-level data, not retention over time"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Clarity has custom identifiers but not full user profiles"
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": false,
"notes": "Clarity shows session journeys but not aggregate user paths"
},
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false
}
]
},
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true,
"notes": "Clarity offers live session viewing"
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true,
"notes": "Both require consent for full tracking"
},
{
"name": "CCPA Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "Data Masking",
"openpanel": true,
"competitor": true,
"notes": "Clarity auto-masks sensitive content in recordings"
},
{
"name": "Self-Hostable",
"openpanel": true,
"competitor": false,
"notes": "Clarity data stored on Microsoft Azure"
},
{
"name": "Cookie-Free Option",
"openpanel": true,
"competitor": false,
"notes": "Clarity uses first-party cookies for session tracking"
},
{
"name": "Open Source",
"openpanel": true,
"competitor": "partial",
"notes": "Clarity tracking code is open source on GitHub"
}
]
},
{
"group": "Integrations & SDKs",
"features": [
{
"name": "JavaScript SDK",
"openpanel": true,
"competitor": true
},
{
"name": "React/Next.js",
"openpanel": true,
"competitor": true
},
{
"name": "iOS SDK",
"openpanel": true,
"competitor": true,
"notes": "Clarity iOS SDK launched July 2024"
},
{
"name": "Android SDK",
"openpanel": true,
"competitor": true
},
{
"name": "Flutter SDK",
"openpanel": false,
"competitor": true,
"notes": "Clarity Flutter SDK launched June 2025"
},
{
"name": "React Native SDK",
"openpanel": true,
"competitor": true
},
{
"name": "Google Analytics Integration",
"openpanel": false,
"competitor": true,
"notes": "Clarity has native GA4 integration"
},
{
"name": "REST API",
"openpanel": true,
"competitor": true
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "Lightweight async script, mobile SDKs ~400-900 KB",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript",
"React",
"Next.js",
"iOS",
"Android",
"Flutter",
"React Native",
"Cordova",
"Ionic",
"WordPress",
"Shopify",
"Wix"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Partial - Tracking code only",
"notes": "Clarity tracking code is open source on GitHub. Backend is proprietary."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Not available - Cloud only (Microsoft Azure)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "Microsoft Azure (proprietary)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "30 days recordings (13 months if labeled), 13 months heatmaps",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "TypeScript (tracking code), proprietary backend",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Microsoft Clarity is 100% free. OpenPanel offers free tier with paid plans.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier."
},
"competitor": {
"model": "100% Free forever",
"description": "Unlimited sessions, unlimited heatmaps, up to 100,000 sessions per day, all features included. Session recordings, heatmaps, insights, Copilot AI, mobile SDKs, GA integration - all free. Microsoft offers it as a free tool to compete with Hotjar and drive Microsoft ecosystem adoption.",
"free_tier": "Unlimited - no traffic limits",
"pricing_url": null
}
},
"migration": {
"title": "Migrating from Microsoft Clarity to OpenPanel",
"intro": "Clarity and OpenPanel serve different purposes. Many teams use both.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Understand the Difference",
"description": "Clarity and OpenPanel serve different purposes. Clarity is for behavioral analytics (watching sessions). OpenPanel is for product analytics (tracking user actions over time). Many teams use both."
},
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. If you're using Clarity's Smart Events, map them to OpenPanel events."
},
{
"title": "Set Up User Identification",
"description": "Unlike Clarity, OpenPanel tracks users across sessions. Add op.identify() calls to enable retention analysis, cohorts, and user profiles."
},
{
"title": "Configure Funnels and Retention",
"description": "Set up funnels in OpenPanel. Unlike Clarity's session-based funnels, OpenPanel tracks conversions over time across multiple sessions."
},
{
"title": "Consider Keeping Both",
"description": "Since Clarity is free, consider keeping it for session recordings and heatmaps while using OpenPanel for product analytics. They complement each other."
}
],
"sdk_compatibility": {
"similar_api": false,
"notes": "These tools serve different purposes. Clarity focuses on session recordings; OpenPanel focuses on event-based analytics."
},
"historical_data": {
"can_import": false,
"notes": "Most teams use both tools together since they serve different purposes."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Microsoft Clarity",
"intro": "Choose OpenPanel when you need product analytics beyond behavioral observation.",
"items": [
{
"title": "SaaS Products Needing Retention Analytics",
"description": "Clarity shows individual session recordings but doesn't track retention over time. If you need to understand how users return to your product week over week, OpenPanel's retention analysis provides these insights.",
"icon": "repeat"
},
{
"title": "Teams Requiring Self-Hosting",
"description": "Clarity is cloud-only with data stored on Microsoft Azure. If data sovereignty, compliance requirements, or privacy policies require self-hosting, OpenPanel can be deployed on your own infrastructure.",
"icon": "server"
},
{
"title": "Products Needing User Identification",
"description": "Clarity has custom identifiers but doesn't build comprehensive user profiles. OpenPanel lets you track individual users across sessions and analyze their complete journey with your product.",
"icon": "user-check"
},
{
"title": "Teams Wanting A/B Testing",
"description": "Clarity focuses on observation (watching what users do) not experimentation. OpenPanel includes A/B testing capabilities to measure the impact of changes.",
"icon": "git-branch"
},
{
"title": "Combining Both Tools",
"description": "Since Clarity is free, many teams use both: Clarity for visual session recordings and heatmaps, OpenPanel for product analytics, funnels, retention, and cohorts. They complement each other well.",
"icon": "layers"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about Microsoft Clarity and OpenPanel.",
"items": [
{
"question": "Is Microsoft Clarity really free?",
"answer": "Yes, Microsoft Clarity is 100% free forever with no paid tiers, no traffic limits, and no forced upgrades. Microsoft offers it as a free tool to compete with Hotjar and drive adoption of the Microsoft ecosystem."
},
{
"question": "Why would I choose OpenPanel over a free tool like Clarity?",
"answer": "Clarity and OpenPanel solve different problems. Clarity is for behavioral analytics - watching session recordings and heatmaps. OpenPanel is for product analytics - tracking events, analyzing retention, building cohorts, and identifying users. If you need product analytics features, OpenPanel provides them while Clarity doesn't."
},
{
"question": "Can I self-host Microsoft Clarity?",
"answer": "No. Microsoft Clarity is cloud-only with data stored on Microsoft Azure servers. If you need self-hosting for data sovereignty or compliance, OpenPanel offers full Docker-based self-hosting."
},
{
"question": "Does Clarity have retention and cohort analysis?",
"answer": "No. Clarity focuses on session-level behavioral analytics (recordings, heatmaps, rage clicks). It doesn't provide retention analysis or cohort tracking over time. OpenPanel includes these product analytics features."
},
{
"question": "How long does Clarity keep my data?",
"answer": "Clarity retains session recordings for 30 days (13 months if labeled or favorited). Heatmap data is retained for 13 months. OpenPanel's self-hosted option offers unlimited retention."
},
{
"question": "Does Clarity have A/B testing?",
"answer": "No. Clarity is an observation tool - it shows you what users do but doesn't help you experiment with changes. OpenPanel includes built-in A/B testing capabilities."
},
{
"question": "Should I use Clarity and OpenPanel together?",
"answer": "Many teams do! Since Clarity is free, you can use it for session recordings and heatmaps while using OpenPanel for product analytics, retention, cohorts, and user profiles. The tools complement each other."
},
{
"question": "Is Clarity open source?",
"answer": "Partially. The Clarity tracking code is open source on GitHub, but the backend and dashboard are proprietary Microsoft services. OpenPanel is fully open source with MIT license."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,473 @@
{
"slug": "mixpanel-alternative",
"page_type": "alternative",
"seo": {
"title": "The best Mixpanel alternative",
"description": "Compare OpenPanel with Mixpanel: pricing, privacy, self-hosting, and features. OpenPanel offers similar product analytics at a fraction of the cost with EU-only hosting.",
"noindex": false
},
"hero": {
"heading": "Mixpanel alternative",
"subheading": "OpenPanel is an open-source, privacy-first alternative to Mixpanel. Get powerful product analytics—events, funnels, retention, and user profiles—without event-based pricing that scales to thousands per month or sending your data to US servers.",
"badges": [
"Open-source",
"EU-only hosting",
"Self-hostable",
"From $2.50/month"
]
},
"competitor": {
"name": "Mixpanel",
"logo": "/logos/mixpanel.svg",
"url": "https://mixpanel.com",
"short_description": "Enterprise product analytics platform for tracking user behavior across web and mobile applications.",
"founded": 2009,
"headquarters": "San Francisco, CA"
},
"summary_comparison": {
"title": "OpenPanel vs Mixpanel: Which is right for you?",
"intro": "Both platforms help you understand how users interact with your product. The key differences are pricing structure, data privacy approach, and complexity level.",
"one_liner": "OpenPanel is simpler, more affordable, and privacy-focused; Mixpanel is more powerful for enterprise teams with complex analytics needs.",
"best_for_openpanel": [
"Startups and medium-sized businesses who want powerful analytics without enterprise pricing",
"Privacy-conscious teams requiring EU-only data storage",
"Developers who want to self-host and own their data",
"Teams looking for both web and product analytics in one tool"
],
"best_for_competitor": [
"Enterprise teams needing advanced experimentation and feature flags",
"Organizations requiring session replay across web and mobile",
"Companies with complex data warehouse integration needs",
"Teams that need Metric Trees for organizational alignment"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Mixpanel compare on the factors that matter most.",
"items": [
{
"label": "Starting price",
"openpanel": "$2.50/month (5k events)",
"competitor": "$0 (1M events free, then $20+/month)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, completely free",
"competitor": "No"
},
{
"label": "Data location",
"openpanel": "EU-only (or your own servers)",
"competitor": "US default, EU/India optional"
},
{
"label": "Cookies",
"openpanel": "Cookie-free by default",
"competitor": "Uses cookies by default"
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel covers the core analytics most teams need, while Mixpanel extends into enterprise-grade experimentation and session replay.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": "Mixpanel offers more advanced multi-path funnels"
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": true,
"notes": "Mixpanel has more advanced cohort builder"
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Web analytics",
"features": [
{
"name": "Page views & visitors",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Traffic sources",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Geographic data",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Device & browser stats",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "UTM tracking",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Advanced features",
"features": [
{
"name": "A/B testing",
"openpanel": true,
"competitor": true,
"notes": "Mixpanel has more advanced experimentation with Experimentation 2.0"
},
{
"name": "Feature flags",
"openpanel": false,
"competitor": true,
"notes": "Mixpanel offers native feature flags (Enterprise)"
},
{
"name": "Session replay",
"openpanel": false,
"competitor": true,
"notes": "Mixpanel supports web, iOS, and Android"
},
{
"name": "Revenue tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "AI insights",
"openpanel": true,
"competitor": true,
"notes": "Both offer AI-powered features"
},
{
"name": "Metric Trees",
"openpanel": false,
"competitor": true,
"notes": "Mixpanel's unique feature for mapping metrics to outcomes"
},
{
"name": "Notifications/Alerts",
"openpanel": true,
"competitor": true,
"notes": "OpenPanel supports webhooks, Slack, Discord"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "EU data residency",
"openpanel": true,
"competitor": true,
"notes": "OpenPanel is EU-only; Mixpanel offers EU as an option"
},
{
"name": "Cookie-free tracking",
"openpanel": true,
"competitor": false,
"notes": "Mixpanel uses cookies by default"
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "DPA available",
"openpanel": "on request",
"competitor": true,
"notes": null
},
{
"name": "SOC 2 Type II",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Warehouse connectors",
"openpanel": false,
"competitor": true,
"notes": "Mixpanel has extensive warehouse integration"
},
{
"name": "Segment integration",
"openpanel": false,
"competitor": true,
"notes": null
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the SDKs and technical implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "~20+ KB gzipped",
"notes": "OpenPanel's lighter SDK means faster page loads"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"Node.js",
"Python",
"Swift",
"Kotlin",
"React Native",
"Astro",
"Remix",
"Express"
],
"competitor": [
"JavaScript",
"React Native",
"iOS (Swift/Obj-C)",
"Android",
"Flutter",
"Unity",
"Python",
"Node.js",
"Ruby",
"PHP",
"Go",
"Java"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (AGPL-3.0)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup script",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary (Arb)",
"notes": "OpenPanel gives you direct SQL access to your data"
},
{
"label": "Autocapture",
"openpanel": "Manual events + auto pageviews",
"competitor": "Full autocapture available",
"notes": "Mixpanel can automatically capture clicks, inputs, etc."
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers predictable, affordable pricing. Mixpanel's pricing can scale significantly as your usage grows.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing starting at $2.50/month for 5,000 events. 100,000 events costs $20/month. Self-host for free with unlimited events. No limits on users, dashboards, or features at any tier."
},
"competitor": {
"model": "Event-based, tiered",
"description": "Free tier includes 1M events/month with limited features. Growth plans start at $20/month and scale with usage. Enterprise plans start around $1,167/month with advanced features like session replay and feature flags.",
"free_tier": "Yes (1M events/month)",
"pricing_url": "https://mixpanel.com/pricing"
}
},
"migration": {
"title": "Migrating from Mixpanel to OpenPanel",
"intro": "Switching from Mixpanel to OpenPanel is straightforward thanks to similar API patterns and our built-in import tool.",
"difficulty": "easy",
"estimated_time": "1-2 hours",
"steps": [
{
"title": "Export your Mixpanel data",
"description": "Use Mixpanel's data export API to extract your historical events if you want to preserve them."
},
{
"title": "Import into OpenPanel",
"description": "OpenPanel has a built-in Mixpanel importer. Upload your exported data to maintain historical context."
},
{
"title": "Install the OpenPanel SDK",
"description": "Replace the Mixpanel SDK with OpenPanel's lightweight tracker. The API is similar—track(), identify(), and setGlobalProperties() work the same way."
},
{
"title": "Update your event calls",
"description": "Most Mixpanel event calls translate directly. Review your implementation and update any Mixpanel-specific features."
},
{
"title": "Verify and go live",
"description": "Run both tools in parallel briefly to validate data consistency, then switch fully to OpenPanel."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "OpenPanel uses similar method names: track(), identify(), setGlobalProperties(). Most implementations translate with minimal changes."
},
"historical_data": {
"can_import": true,
"notes": "OpenPanel has a built-in Mixpanel importer. Contact us if you need assistance with large data migrations."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Mixpanel",
"intro": "OpenPanel shines for teams that value simplicity, privacy, and cost-effectiveness over enterprise complexity.",
"items": [
{
"title": "Startups watching their budget",
"description": "Start at $2.50/month instead of dealing with Mixpanel's pricing that can jump to hundreds or thousands as you scale.",
"icon": "dollar"
},
{
"title": "Privacy-first products",
"description": "Cookie-free tracking and EU-only hosting by default. No need to configure data residency or worry about US data transfers.",
"icon": "shield"
},
{
"title": "Self-hosted requirements",
"description": "Deploy OpenPanel on your own infrastructure for complete data ownership. Perfect for regulated industries or security-conscious teams.",
"icon": "server"
},
{
"title": "Web + product analytics combined",
"description": "Get Plausible-style web analytics and Mixpanel-style product analytics in one tool, not two separate subscriptions.",
"icon": "chart"
},
{
"title": "Developer-led teams",
"description": "Open source, tiny SDK, direct database access. Built by developers, for developers who want control.",
"icon": "code"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Mixpanel to OpenPanel.",
"items": [
{
"question": "Does OpenPanel have all the features I use in Mixpanel?",
"answer": "OpenPanel covers the core features most teams actually use: event tracking, funnels, retention, cohorts, user profiles, and A/B testing. If you rely heavily on Mixpanel's session replay, feature flags, or Metric Trees, those aren't available in OpenPanel yet."
},
{
"question": "Can I import my historical Mixpanel data?",
"answer": "Yes! OpenPanel has a built-in Mixpanel importer. You can export your data from Mixpanel and import it directly into OpenPanel to maintain historical context."
},
{
"question": "How does pricing compare at scale?",
"answer": "OpenPanel is significantly cheaper at most scales. For example, 100k events costs $20/month on OpenPanel. On Mixpanel, once you exceed the free tier limits, costs can climb quickly into hundreds per month. Self-hosting OpenPanel is free with no event limits."
},
{
"question": "Is OpenPanel GDPR compliant?",
"answer": "Yes. OpenPanel is EU-based (Sweden), uses cookie-free tracking by default, and stores data in EU servers. We also offer DPA agreements on request."
},
{
"question": "Can I self-host OpenPanel?",
"answer": "Yes. OpenPanel is fully open source and can be self-hosted with a simple Docker setup script. Self-hosting is completely free with unlimited events."
},
{
"question": "How does the SDK size compare?",
"answer": "OpenPanel's JavaScript SDK is ~2.3 KB gzipped compared to Mixpanel's 20+ KB. This means faster page loads and better Core Web Vitals scores."
},
{
"question": "Does OpenPanel support mobile apps?",
"answer": "Yes. OpenPanel has SDKs for Swift (iOS), Kotlin (Android), and React Native. While not as mature as Mixpanel's mobile SDKs, they cover the core tracking needs."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,426 @@
{
"slug": "mouseflow-alternative",
"page_type": "alternative",
"seo": {
"title": "Mouseflow Alternative",
"description": "Compare OpenPanel with Mouseflow: pricing, features, and deployment. OpenPanel offers product analytics with mobile SDKs; Mouseflow excels at visual website optimization.",
"noindex": false
},
"hero": {
"heading": "Mouseflow alternative",
"subheading": "Need product analytics beyond heatmaps? OpenPanel provides event-based analytics, mobile SDKs, and self-hosting—fully open source with transparent pricing.",
"badges": [
"Open-source",
"Self-hostable",
"Mobile SDKs",
"Event-based analytics"
]
},
"competitor": {
"name": "Mouseflow",
"logo": "/logos/mouseflow.svg",
"url": "https://mouseflow.com",
"short_description": "Behavior analytics platform with session replay, heatmaps, friction detection, and form analytics for website optimization.",
"founded": 2009,
"headquarters": "Copenhagen, Denmark"
},
"summary_comparison": {
"title": "OpenPanel vs Mouseflow: Which is right for you?",
"intro": "Mouseflow excels at visual website optimization with heatmaps and session replay. OpenPanel focuses on product analytics with mobile support.",
"one_liner": "OpenPanel is for product analytics with mobile SDKs and self-hosting; Mouseflow is for visual website optimization with heatmaps.",
"best_for_openpanel": [
"Teams needing mobile app analytics with native SDKs",
"Product analytics focus (funnels, retention, cohorts)",
"Organizations requiring self-hosting for data ownership",
"Open source requirements for transparency",
"Teams tracking user-level behavior across platforms"
],
"best_for_competitor": [
"UX designers needing visual behavior analytics",
"Website conversion rate optimization teams",
"Teams requiring comprehensive heatmaps and session replay",
"Form analytics and feedback survey needs",
"Visual optimization without mobile app requirements"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Mouseflow compare on the factors that matter most.",
"items": [
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, with Docker",
"competitor": "No (cloud only)"
},
{
"label": "Mobile SDKs",
"openpanel": "iOS, Android, RN, Flutter",
"competitor": "Web only"
},
{
"label": "Heatmaps",
"openpanel": "Not available",
"competitor": "7 types of heatmaps"
},
{
"label": "Data model",
"openpanel": "Event-based",
"competitor": "Session-based"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel focuses on product analytics; Mouseflow focuses on visual website behavior.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": "Limited",
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": "Limited",
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Visual analytics",
"features": [
{
"name": "Session replay",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Click heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Scroll heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Movement heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Form analytics",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Friction score",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Rage click detection",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Feedback & surveys",
"features": [
{
"name": "On-site surveys",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "NPS surveys",
"openpanel": false,
"competitor": true,
"notes": null
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cookie-free option",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "EU data residency",
"openpanel": "Via self-hosting",
"competitor": true,
"notes": null
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": "Growth plan+",
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Mobile SDKs",
"openpanel": true,
"competitor": false,
"notes": "Mouseflow is web only"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "Larger (includes recording)",
"notes": null
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Flutter"
],
"competitor": [
"JavaScript (web only)"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "Proprietary cloud",
"notes": null
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted)",
"competitor": "1-12 months depending on plan",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers event-based pricing with free self-hosting. Mouseflow uses session-based pricing.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Session-based",
"description": "Free: 500 sessions/month. Starter: $31/month for 5,000 sessions. Growth: $109/month for 15,000 sessions. Business: $219/month for 50,000 sessions. All features included on all plans.",
"free_tier": "Yes (500 sessions/month)",
"pricing_url": "https://mouseflow.com/pricing"
}
},
"migration": {
"title": "Migrating from Mouseflow to OpenPanel",
"intro": "Moving from Mouseflow involves transitioning from visual behavior analytics to event-based product analytics.",
"difficulty": "moderate",
"estimated_time": "2-4 hours",
"steps": [
{
"title": "Understand feature differences",
"description": "Mouseflow excels at visual behavior analytics. If you rely on heatmaps and session replay, consider complementary tools like Microsoft Clarity."
},
{
"title": "Create OpenPanel account or self-host",
"description": "Sign up for OpenPanel cloud or deploy self-hosted using Docker. Configure your project settings."
},
{
"title": "Install OpenPanel SDK",
"description": "Replace the Mouseflow snippet with OpenPanel's SDK. For mobile apps, install native SDKs."
},
{
"title": "Map events and properties",
"description": "Convert Mouseflow's implicit tracking to OpenPanel's explicit event tracking. Set up user identification."
},
{
"title": "Build analytics dashboards",
"description": "Create funnels, retention charts, and cohort analyses in OpenPanel."
}
],
"sdk_compatibility": {
"similar_api": false,
"notes": "Different tracking philosophies: Mouseflow is session-based, OpenPanel is event-based."
},
"historical_data": {
"can_import": false,
"notes": "Historical session recordings from Mouseflow cannot be migrated."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Mouseflow",
"intro": "OpenPanel excels when you need product analytics with mobile support and data ownership.",
"items": [
{
"title": "Mobile app analytics",
"description": "Mouseflow is web-only. OpenPanel provides native SDKs for iOS, Android, React Native, and Flutter.",
"icon": "smartphone"
},
{
"title": "Product analytics & user tracking",
"description": "Track user behavior across platforms with funnels, retention analysis, cohorts, and user identification.",
"icon": "chart"
},
{
"title": "Data ownership & self-hosting",
"description": "Complete data control with self-hosting. Mouseflow is cloud-only.",
"icon": "server"
},
{
"title": "Open source requirements",
"description": "Full transparency and customization with MIT license. Mouseflow is proprietary.",
"icon": "code"
},
{
"title": "Unlimited data retention",
"description": "Self-hosted OpenPanel has unlimited retention. Mouseflow limits data retention.",
"icon": "database"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Mouseflow to OpenPanel.",
"items": [
{
"question": "Can OpenPanel replace Mouseflow's heatmaps and session replay?",
"answer": "No, OpenPanel does not provide heatmaps. If you need visual behavior analytics, consider using Mouseflow alongside OpenPanel, or explore alternatives like Hotjar or Microsoft Clarity."
},
{
"question": "Does Mouseflow work with mobile apps?",
"answer": "No, Mouseflow is web-only. OpenPanel provides native SDKs for iOS, Android, React Native, and Flutter for mobile app analytics."
},
{
"question": "Which tool is better for e-commerce?",
"answer": "It depends on needs. Mouseflow excels at visual checkout optimization. OpenPanel is better for tracking customer journeys and retention. Many e-commerce teams use both."
},
{
"question": "Can I self-host Mouseflow?",
"answer": "No, Mouseflow is cloud-only. OpenPanel offers both cloud hosting and self-hosted deployment via Docker."
},
{
"question": "How does pricing compare?",
"answer": "Mouseflow uses session-based pricing starting at $31/month for 5,000 sessions. OpenPanel uses event-based pricing with 10,000 free events/month. OpenPanel's self-hosted option is completely free."
},
{
"question": "Can I use both tools together?",
"answer": "Yes, and this is often recommended. Use Mouseflow for visual behavior analytics and OpenPanel for product analytics. The tools serve complementary purposes."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,472 @@
{
"slug": "pirsch-analytics-alternative",
"page_type": "alternative",
"seo": {
"title": "Pirsch Analytics Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Pirsch Analytics. Discover why teams choose OpenPanel as their Pirsch alternative for product analytics, user identification, and free self-hosting without enterprise pricing.",
"noindex": false
},
"hero": {
"heading": "Pirsch Alternative",
"subheading": "Love Pirsch's German privacy focus and developer-friendly approach? OpenPanel adds product analytics capabilities - funnels, cohorts, retention, and user identification - plus free self-hosting without enterprise pricing.",
"badges": [
"Open-source",
"Privacy-first",
"Free Self-Hosting",
"Product Analytics"
]
},
"competitor": {
"name": "Pirsch Analytics",
"logo": "/logos/pirsch.svg",
"url": "https://pirsch.io",
"short_description": "Privacy-focused web analytics with strong German hosting, developer-friendly features, and agency-focused capabilities.",
"founded": 2020,
"headquarters": "Rheda-Wiedenbruck, Germany"
},
"summary_comparison": {
"title": "OpenPanel vs Pirsch: Which is right for you?",
"intro": "Both are privacy-focused analytics tools. Pirsch focuses on affordable web analytics with agency features. OpenPanel adds product analytics with user identification.",
"one_liner": "Pirsch excels at affordable web analytics with excellent white-labeling; OpenPanel adds product analytics with free self-hosting.",
"best_for_openpanel": [
"SaaS products needing user-level analytics and retention tracking",
"Teams wanting free self-hosting without Enterprise license fees",
"Startups needing a permanent free tier (10K events/month)",
"Mobile app developers needing native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Agencies managing many client websites with white-labeling needs",
"Developers preferring Go/backend server-side integration",
"European businesses prioritizing German-hosted data",
"Teams wanting affordable unlimited-website plans ($12/month)"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Pirsch compare on key factors.",
"items": [
{
"label": "Analytics Depth",
"openpanel": "Web + Product Analytics",
"competitor": "Web Analytics + Basic Funnels",
"notes": "OpenPanel combines web analytics with full product analytics including retention, cohorts, and user profiles. Pirsch focuses on web analytics with funnels and A/B testing on higher tiers."
},
{
"label": "Free Self-Hosting",
"openpanel": "Free Docker deployment",
"competitor": "Enterprise license required",
"notes": "OpenPanel offers free self-hosting in a single Docker container. Pirsch requires an Enterprise license with custom pricing for on-premise deployment."
},
{
"label": "Free Tier",
"openpanel": "10,000 events/month free",
"competitor": "30-day trial only",
"notes": "OpenPanel offers a generous free tier. Pirsch has no free tier - just a 30-day trial before requiring a $6/month minimum subscription."
},
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous fingerprinting only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Pirsch uses daily fingerprinting and doesn't track individuals."
},
{
"label": "Server-Side Integration",
"openpanel": "Yes - Multiple backends",
"competitor": "Yes - Excellent Go/backend focus",
"notes": "Both offer strong server-side integration. Pirsch was originally built as a Go library for backend tracking, avoiding ad blockers."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are developer-friendly with privacy focus, but different in depth and pricing.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true,
"notes": "Both track referrers and UTM parameters"
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Pirsch supports events with custom metadata"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true,
"notes": "Pirsch funnels require Plus plan ($12/month)"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Pirsch's anonymous model doesn't support retention"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Pirsch doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "Pirsch provides aggregate data only"
},
{
"name": "Session Replay",
"openpanel": false,
"competitor": true,
"notes": "Pirsch has session analysis (not full replay)"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": true,
"notes": "Pirsch A/B testing requires Plus plan"
},
{
"name": "Conversion Goals",
"openpanel": true,
"competitor": true,
"notes": "Both support conversion tracking"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": true,
"notes": "Both offer scheduled email reports"
},
{
"name": "Dashboard Sharing",
"openpanel": true,
"competitor": true,
"notes": "Both support public and private sharing"
},
{
"name": "Google Analytics Import",
"openpanel": false,
"competitor": true,
"notes": "Pirsch has a GA import tool"
},
{
"name": "URL Shortener",
"openpanel": false,
"competitor": true,
"notes": "Pirsch has built-in URL shortener with tracking"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true,
"notes": "Both are cookieless by default"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true,
"notes": "Pirsch is hosted in Germany with strict EU compliance"
},
{
"name": "Schrems II Compliant",
"openpanel": true,
"competitor": true,
"notes": "Pirsch emphasizes Schrems II compliance"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": true,
"notes": "Pirsch self-hosting requires Enterprise license"
},
{
"name": "Open Source Core",
"openpanel": true,
"competitor": true,
"notes": "Both have open source cores (Pirsch MIT, OpenPanel open source)"
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Pirsch has comprehensive RESTful API"
},
{
"name": "Google Search Console",
"openpanel": false,
"competitor": true,
"notes": "Pirsch has GSC integration in dashboard"
},
{
"name": "WordPress Plugin",
"openpanel": true,
"competitor": true,
"notes": "Both have WordPress plugins"
},
{
"name": "Server-Side SDKs",
"openpanel": true,
"competitor": true,
"notes": "Pirsch: Go, Laravel. OpenPanel: Node, Python, PHP, Go, Rust"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "~4 KB (about 30x smaller than GA)",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript",
"Go (native)",
"Laravel/PHP",
"WordPress",
"Drupal",
"Caddy",
"Various backend integrations"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Partial - Core MIT, SaaS proprietary",
"notes": "Pirsch core is open source under MIT license. SaaS features are proprietary."
},
{
"label": "Self Hosting",
"openpanel": "Docker (free single-container setup)",
"competitor": "Enterprise license required (custom pricing)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "ClickHouse",
"notes": "Both use ClickHouse for analytics queries"
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Unlimited on all plans",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Go (Golang)",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Pirsch offers affordable web analytics. OpenPanel adds a permanent free tier with all features.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "Pageview-based with 30-day trial",
"description": "Standard: $6/month for 10K pageviews, 50 websites. Plus: $12/month - unlimited websites, funnels, A/B testing. Enterprise: Custom pricing for on-premise and SSO. No free tier, just 30-day trial.",
"free_tier": "No free tier (30-day trial only)",
"pricing_url": "https://pirsch.io/pricing"
}
},
"migration": {
"title": "Migrating from Pirsch to OpenPanel",
"intro": "Both use lightweight scripts and similar event tracking, making migration straightforward.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts and server-side options."
},
{
"title": "Map Events",
"description": "Pirsch events with metadata translate directly to OpenPanel's op.track() calls."
},
{
"title": "Set Up User Identification (New)",
"description": "Unlike Pirsch, OpenPanel can identify users. Add op.identify() calls to unlock retention, cohorts, and user profiles."
},
{
"title": "Configure Product Analytics (New)",
"description": "Set up retention reports, cohorts, and user journey analysis. Pirsch has basic funnels but not these features."
},
{
"title": "Remove Pirsch Script",
"description": "Once verified, remove the Pirsch tracking script. Both are cookie-free so no consent changes needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with simple APIs."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Pirsch",
"intro": "Choose OpenPanel when you need user-level analytics, free self-hosting, or a permanent free tier.",
"items": [
{
"title": "SaaS Products Needing User Analytics",
"description": "Pirsch shows aggregate website traffic and basic funnels. If you need to understand individual user journeys, retention, and behavior within your product, OpenPanel adds these capabilities while staying privacy-friendly.",
"icon": "users"
},
{
"title": "Teams Who Want Free Self-Hosting",
"description": "Pirsch requires an Enterprise license with custom pricing for on-premise deployment. OpenPanel provides free self-hosting in a single Docker container with no restrictions.",
"icon": "server"
},
{
"title": "Startups Needing a Free Tier",
"description": "Pirsch has no free option - just a 30-day trial before requiring a $6/month subscription. OpenPanel offers 10,000 free events monthly, perfect for early-stage products.",
"icon": "trending-up"
},
{
"title": "Mobile App Analytics",
"description": "Pirsch is designed for websites with a backend focus. OpenPanel offers native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams Needing Cohort & Retention Analysis",
"description": "Pirsch's anonymous fingerprinting model doesn't support retention or cohort analysis. If understanding user behavior over time matters, OpenPanel provides these capabilities.",
"icon": "bar-chart"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Pirsch to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Pirsch?",
"answer": "Yes! Both are cookie-free by default and don't require consent banners. The key difference is that OpenPanel allows optional user identification for product analytics, while Pirsch uses anonymous fingerprinting. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Pirsch to OpenPanel?",
"answer": "Teams typically switch when they need: 1) Full product analytics (retention, cohorts, user profiles), 2) Free self-hosting without Enterprise pricing, 3) A permanent free tier, or 4) Native mobile SDKs. Pirsch excels at affordable web analytics but has limitations for product analytics."
},
{
"question": "Does Pirsch have a free tier?",
"answer": "No. Pirsch offers a 30-day free trial, then requires a minimum $6/month subscription. OpenPanel provides 10,000 free events monthly with no time limit."
},
{
"question": "Can I self-host Pirsch for free?",
"answer": "No. Pirsch self-hosting requires an Enterprise license with custom pricing. While the core library is open source (MIT), running the full SaaS requires a license. OpenPanel offers free self-hosting in a single Docker container."
},
{
"question": "Which has the smaller tracking script?",
"answer": "OpenPanel's script is 2.3KB, while Pirsch's is about 4KB. Both are significantly smaller than Google Analytics (50KB+). Pirsch also emphasizes server-side integration which adds zero client-side weight."
},
{
"question": "Can Pirsch track mobile apps?",
"answer": "Not natively. Pirsch is designed for web analytics with a backend/server-side focus. You could use their API, but there are no mobile-specific SDKs. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "What will I lose switching from Pirsch?",
"answer": "Pirsch has a built-in URL shortener with tracking, Google Search Console integration in the dashboard, excellent white labeling options, and strong Go/backend integration. However, you'll gain full product analytics, free self-hosting, and mobile SDKs that Pirsch doesn't offer."
},
{
"question": "Is Pirsch or OpenPanel better for agencies?",
"answer": "Pirsch has excellent agency features: extensive white labeling, custom domains, team management, and client access links. Their Plus plan at $12/month with unlimited websites is very affordable. However, if your clients need product analytics or you want free self-hosting, OpenPanel provides more value."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,473 @@
{
"slug": "plausible-alternative",
"page_type": "alternative",
"seo": {
"title": "Plausible Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Plausible Analytics. Discover why teams choose OpenPanel as their Plausible alternative for product analytics, user identification, and deeper insights while maintaining privacy.",
"noindex": false
},
"hero": {
"heading": "Plausible Alternative",
"subheading": "Love Plausible's simplicity and privacy focus? OpenPanel adds product analytics capabilities - funnels, cohorts, retention, and user identification - while staying lightweight and cookie-free by default.",
"badges": [
"Open-source",
"Privacy-first",
"Product Analytics",
"Cookie-free"
]
},
"competitor": {
"name": "Plausible Analytics",
"logo": "/logos/plausible.svg",
"url": "https://plausible.io",
"short_description": "Privacy-focused, lightweight Google Analytics alternative for websites with EU-based hosting and simple dashboard.",
"founded": 2018,
"headquarters": "Tartu, Estonia"
},
"summary_comparison": {
"title": "OpenPanel vs Plausible: Which is right for you?",
"intro": "Both are privacy-focused analytics platforms. Plausible focuses on simple web traffic metrics. OpenPanel adds product analytics with user identification.",
"one_liner": "Plausible excels at simple web analytics; OpenPanel adds product analytics, user identification, and simpler self-hosting.",
"best_for_openpanel": [
"SaaS products needing user-level analytics and retention tracking",
"Teams outgrowing simple web analytics needing product features",
"Apps requiring user identification for logged-in users",
"Mobile app developers needing native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Simple content sites and blogs wanting traffic stats only",
"Teams valuing the sub-1KB script size above all else",
"Users wanting Google Search Console integration in dashboard",
"Organizations prioritizing Germany/EU-only data hosting"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Plausible compare on key factors.",
"items": [
{
"label": "Analytics Depth",
"openpanel": "Web + Product Analytics",
"competitor": "Web Analytics Only",
"notes": "OpenPanel combines web analytics with product analytics - funnels, retention, cohorts, and user profiles. Plausible focuses purely on website traffic metrics."
},
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Plausible intentionally doesn't track individuals - all data is anonymous and aggregate."
},
{
"label": "SDK Size",
"openpanel": "2.3 KB",
"competitor": "< 1 KB",
"notes": "Plausible's script is extremely lightweight at under 1KB. OpenPanel's 2.3KB SDK is still very light but includes more functionality."
},
{
"label": "Cookie-Free",
"openpanel": "Yes (by default)",
"competitor": "Yes (by default)",
"notes": "Both platforms are cookie-free by default and don't require consent banners under GDPR for basic analytics."
},
{
"label": "Self-Hosting Complexity",
"openpanel": "Single Docker container",
"competitor": "Docker with PostgreSQL + ClickHouse",
"notes": "OpenPanel requires just Docker. Plausible Community Edition needs both PostgreSQL and ClickHouse databases configured."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are privacy-focused, but with different capabilities and depths.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "Both offer country, region, and city-level data"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Plausible calls these 'Goals'"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true,
"notes": "Plausible added funnels (2-8 steps) in 2022"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Plausible focuses on aggregate metrics, not user retention"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Plausible intentionally doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "Plausible's anonymous model doesn't support cohorts"
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": false,
"notes": "Plausible shows entry/exit pages but not user journeys"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Plausible is analytics-only, no experimentation"
},
{
"name": "Revenue Tracking",
"openpanel": true,
"competitor": true,
"notes": "Plausible added revenue goals for e-commerce"
},
{
"name": "Custom Properties",
"openpanel": true,
"competitor": true,
"notes": "Both support custom dimensions/properties"
},
{
"name": "Email/Slack Reports",
"openpanel": true,
"competitor": true,
"notes": "Both offer scheduled reports and alerts"
},
{
"name": "Google Search Console",
"openpanel": false,
"competitor": true,
"notes": "Plausible has native GSC integration"
},
{
"name": "Google Analytics Import",
"openpanel": false,
"competitor": true,
"notes": "Plausible can import historical GA data"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true,
"notes": "Both are cookieless by default"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "EU Data Hosting",
"openpanel": true,
"competitor": true,
"notes": "Plausible hosted in Falkenstein, Germany (Hetzner)"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": true,
"notes": "Plausible Community Edition is free and open-source"
},
{
"name": "IP Anonymization",
"openpanel": true,
"competitor": true,
"notes": "Plausible hashes IPs for counting, never stores them"
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Plausible has Stats API and Events API"
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true,
"notes": "CSV export available on both"
},
{
"name": "WordPress Plugin",
"openpanel": true,
"competitor": true,
"notes": "Plausible has official WordPress plugin"
},
{
"name": "NPM Package",
"openpanel": true,
"competitor": true,
"notes": "plausible-tracker package available"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "< 1 KB (gzipped), modular extensions available",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"React (via npm)",
"Next.js",
"Vue",
"WordPress",
"Ghost",
"Wix",
"Squarespace",
"Webflow"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Yes - AGPL-3.0",
"notes": "Both are open source. Plausible is AGPL-3.0 licensed."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Docker Compose with PostgreSQL + ClickHouse (2GB RAM minimum)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "PostgreSQL (user data) + ClickHouse (analytics data)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "Unlimited on cloud, configurable for self-hosted",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Elixir",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Plausible has no free tier for cloud. OpenPanel offers free cloud and self-hosting.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "Pageview-based with 30-day trial",
"description": "10K pageviews: $9/month. 100K: ~$19/month. 1M: ~$69/month. 10M: ~$299/month. All features included. Annual billing saves 2 months. No free tier for cloud (except self-hosted).",
"free_tier": "No free tier (30-day trial only)",
"pricing_url": "https://plausible.io/pricing"
}
},
"migration": {
"title": "Migrating from Plausible to OpenPanel",
"intro": "Both use lightweight scripts and similar event tracking, making migration straightforward.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts, so the transition is minimal."
},
{
"title": "Map Your Goals to Events",
"description": "Plausible 'Goals' become OpenPanel events. Custom events translate directly - plausible('signup') becomes op.track('signup')."
},
{
"title": "Set Up User Identification (New)",
"description": "Unlike Plausible, OpenPanel can identify users. Add op.identify() calls to unlock retention, cohorts, and user profiles."
},
{
"title": "Configure Funnels and Dashboards",
"description": "Recreate your Plausible funnels in OpenPanel. You'll now have access to additional product analytics features."
},
{
"title": "Remove Plausible Script",
"description": "Once verified, remove the Plausible tracking script. Both are cookie-free so no consent changes needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with similar APIs."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Plausible",
"intro": "Choose OpenPanel when you need product analytics beyond simple web traffic.",
"items": [
{
"title": "SaaS Products Needing User Analytics",
"description": "Plausible shows aggregate website traffic. If you need to understand individual user journeys, retention, and behavior within your product, OpenPanel adds these capabilities while staying privacy-friendly.",
"icon": "users"
},
{
"title": "Teams Outgrowing Simple Web Analytics",
"description": "Started with Plausible for its simplicity but now need funnels with more steps, cohort analysis, or A/B testing? OpenPanel provides these without the complexity of enterprise tools.",
"icon": "trending-up"
},
{
"title": "Apps Requiring User Identification",
"description": "Plausible intentionally doesn't identify users. If you need to track logged-in users, analyze customer segments, or measure retention, OpenPanel lets you do this while respecting privacy.",
"icon": "user-check"
},
{
"title": "Mobile App Analytics",
"description": "Plausible is primarily designed for websites. OpenPanel offers native SDKs for iOS, Android, and React Native with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Simpler Self-Hosting",
"description": "Plausible CE requires PostgreSQL and ClickHouse. OpenPanel runs in a single Docker container, making self-hosting more straightforward.",
"icon": "server"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Plausible to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Plausible?",
"answer": "Yes! Both are cookie-free by default and don't require consent banners. The key difference is that OpenPanel allows optional user identification for product analytics, while Plausible is strictly anonymous. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Plausible to OpenPanel?",
"answer": "Teams typically switch when they need product analytics capabilities: user identification, retention analysis, cohort analysis, and detailed funnel tracking. Plausible excels at simple web analytics, but if you're building a product and need to understand user behavior, OpenPanel provides these features while maintaining privacy."
},
{
"question": "Does Plausible have a free tier?",
"answer": "No, Plausible Cloud requires a paid subscription starting at $9/month. They offer a 30-day free trial. The self-hosted Community Edition is free but requires you to manage PostgreSQL and ClickHouse infrastructure. OpenPanel offers a free cloud tier with 10,000 events/month."
},
{
"question": "Which has the smaller tracking script?",
"answer": "Plausible wins here with a sub-1KB script. OpenPanel's 2.3KB script is still very lightweight but includes more functionality for product analytics. Both are significantly smaller than Google Analytics (45KB+) or Mixpanel."
},
{
"question": "Can Plausible track mobile apps?",
"answer": "Not officially. Plausible is designed for web analytics and doesn't provide native mobile SDKs. You can send events via their API, but there are no mobile-specific metrics. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "What will I lose switching from Plausible?",
"answer": "Plausible's Google Search Console integration and GA import tool are features OpenPanel doesn't have. If you rely heavily on these, consider your needs. However, you'll gain product analytics capabilities that Plausible doesn't offer."
},
{
"question": "How does self-hosting compare?",
"answer": "Plausible CE requires Docker Compose with PostgreSQL and ClickHouse (2GB RAM minimum). OpenPanel runs in a single Docker container with simpler setup. Both use ClickHouse for analytics queries."
},
{
"question": "Is Plausible or OpenPanel better for blogs/content sites?",
"answer": "For simple content sites where you just need traffic stats, Plausible's simplicity is excellent. If you're running a SaaS, e-commerce, or any product where understanding user behavior matters, OpenPanel's product analytics features provide more value."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,458 @@
{
"slug": "posthog-alternative",
"page_type": "alternative",
"seo": {
"title": "PostHog Alternative: Why Teams Switch to OpenPanel",
"description": "Compare OpenPanel vs PostHog. Discover why teams choose OpenPanel as their PostHog alternative for simpler analytics with better privacy, lighter SDK, and no complex pricing tiers.",
"noindex": false
},
"hero": {
"heading": "PostHog Alternative",
"subheading": "Get powerful product analytics without the complexity. OpenPanel delivers essential insights with a lighter footprint, true cookie-free tracking, and transparent pricing - no enterprise sales calls required.",
"badges": [
"Open-source",
"Cookie-free",
"Lightweight SDK",
"Simple Pricing"
]
},
"competitor": {
"name": "PostHog",
"logo": "/logos/posthog.svg",
"url": "https://posthog.com",
"short_description": "All-in-one product analytics platform for developers with features like analytics, feature flags, session replay, and surveys.",
"founded": 2020,
"headquarters": "San Francisco, California, USA"
},
"summary_comparison": {
"title": "OpenPanel vs PostHog: Which is right for you?",
"intro": "Both are open-source analytics platforms. PostHog is an all-in-one platform with many products. OpenPanel focuses on analytics with simplicity.",
"one_liner": "PostHog is an all-in-one platform with 10+ products; OpenPanel focuses on analytics with a lighter footprint.",
"best_for_openpanel": [
"Teams wanting focused analytics without feature flags, session replay, or surveys",
"Privacy-conscious products needing cookie-free tracking by default",
"Performance-conscious applications (2.3KB SDK vs 52KB+)",
"Teams preferring simple Docker deployment over multi-service architecture"
],
"best_for_competitor": [
"Teams needing all-in-one platform (analytics, feature flags, session replay, surveys)",
"Developers wanting SQL access (HogQL) for custom queries",
"Y Combinator companies leveraging PostHog's ecosystem",
"Teams requiring extensive CDP capabilities with 60+ connectors"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and PostHog compare on key factors.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB",
"competitor": "52+ KB",
"notes": "OpenPanel's SDK is over 20x smaller than PostHog's core library, resulting in faster page loads and better Core Web Vitals."
},
{
"label": "Cookie-Free by Default",
"openpanel": "Yes",
"competitor": "Requires Configuration",
"notes": "OpenPanel is truly cookie-free out of the box. PostHog requires specific configuration for cookieless tracking with reduced functionality."
},
{
"label": "Pricing Complexity",
"openpanel": "Simple Event-Based",
"competitor": "Multi-Product Metering",
"notes": "OpenPanel has straightforward pricing. PostHog bills separately for events, recordings, feature flags, surveys, and more - each with different tiers."
},
{
"label": "Self-Hosting Complexity",
"openpanel": "Simple Docker Setup",
"competitor": "ClickHouse + Kafka + Redis + PostgreSQL",
"notes": "OpenPanel self-hosting requires just Docker. PostHog needs multiple services including ClickHouse, Kafka, Redis, and PostgreSQL."
},
{
"label": "Focus",
"openpanel": "Analytics-First",
"competitor": "All-in-One Platform",
"notes": "OpenPanel focuses on doing analytics exceptionally well. PostHog bundles 10+ products which can create complexity for teams just needing analytics."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "PostHog is an all-in-one platform. OpenPanel focuses purely on analytics.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": true
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": true
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": true
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": true
},
{
"name": "Feature Flags",
"openpanel": false,
"competitor": true,
"notes": "PostHog includes feature flags; OpenPanel focuses on analytics"
},
{
"name": "Session Replay",
"openpanel": false,
"competitor": true,
"notes": "PostHog includes session replay for web, Android (beta), iOS (alpha)"
},
{
"name": "Surveys",
"openpanel": false,
"competitor": true,
"notes": "PostHog includes in-app surveys; OpenPanel integrates with survey tools"
},
{
"name": "Custom Dashboards",
"openpanel": true,
"competitor": true
},
{
"name": "SQL Query Access",
"openpanel": true,
"competitor": true,
"notes": "PostHog offers HogQL, their SQL variant"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": false,
"notes": "PostHog uses cookies by default, cookieless requires configuration"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": false,
"notes": "PostHog's default tracking requires consent banners under GDPR"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "EU Data Hosting Option",
"openpanel": true,
"competitor": true,
"notes": "PostHog offers EU Cloud hosted in Frankfurt"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": true
},
{
"name": "IP Anonymization",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Integrations & Export",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true
},
{
"name": "Webhook Support",
"openpanel": true,
"competitor": true
},
{
"name": "Data Warehouse Sync",
"openpanel": true,
"competitor": true,
"notes": "PostHog has extensive CDP capabilities with 60+ connectors"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "52+ KB core library (gzipped), lazy-loads additional features",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript/TypeScript",
"React",
"Next.js",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Ruby",
"Java",
"Flutter",
"Rust"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Yes - MIT License",
"notes": "Both are open source. PostHog is MIT licensed."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Docker with multiple services (ClickHouse, Kafka, Redis, PostgreSQL) or Kubernetes",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "ClickHouse",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "7 years (paid plans), 1 year (free plan), 3 months for recordings",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "PostHog has generous free tiers but complex multi-product pricing. OpenPanel offers simpler event-based pricing.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier."
},
"competitor": {
"model": "Multi-product usage-based",
"description": "1 million events/month (product analytics), 5,000 recordings/month, 1 million feature flag requests/month, 1,500 survey responses/month free. $0.00005/event (anonymous), $0.000248/event (identified), $0.005/recording, $0.0001/flag request. Add-ons like HIPAA ($250/mo) available. 90%+ of customers use free tier.",
"free_tier": "1M events/month (analytics), 5K recordings/month",
"pricing_url": "https://posthog.com/pricing"
}
},
"migration": {
"title": "Migrating from PostHog to OpenPanel",
"intro": "Both use event-based tracking, making migration straightforward for analytics.",
"difficulty": "easy",
"estimated_time": "1-4 hours for basic setup, longer if migrating feature flags or session replay workflows",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the lightweight OpenPanel SDK to your application. At 2.3KB, it's significantly smaller than PostHog's library."
},
{
"title": "Map Your Events",
"description": "Both platforms use event-based tracking. Map your PostHog event names to OpenPanel - most can remain the same."
},
{
"title": "Configure User Identification",
"description": "Replace PostHog's identify() calls with OpenPanel's identification methods. The API is similar."
},
{
"title": "Set Up Dashboards",
"description": "Recreate your key dashboards in OpenPanel. Import historical data if needed using our migration tools."
},
{
"title": "Verify & Go Live",
"description": "Run both platforms in parallel briefly to verify data accuracy, then disable PostHog tracking."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with similar APIs."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than PostHog",
"intro": "Choose OpenPanel when you want analytics without the complexity of an all-in-one platform.",
"items": [
{
"title": "Teams Who Want Analytics Without Feature Bloat",
"description": "If you need product analytics but don't use PostHog's feature flags, session replay, surveys, or experiments, OpenPanel gives you exactly what you need without the overhead.",
"icon": "target"
},
{
"title": "Privacy-First Products",
"description": "OpenPanel is cookie-free by default with no configuration needed. PostHog requires explicit setup for cookieless tracking and loses some functionality in that mode.",
"icon": "shield"
},
{
"title": "Performance-Conscious Applications",
"description": "OpenPanel's 2.3KB SDK vs PostHog's 52KB+ library means faster page loads and better Core Web Vitals - critical for SEO and user experience.",
"icon": "zap"
},
{
"title": "Simple Self-Hosting Needs",
"description": "OpenPanel runs in a single Docker container. PostHog requires ClickHouse, Kafka, Redis, and PostgreSQL - significantly more infrastructure to manage.",
"icon": "server"
},
{
"title": "Predictable Budgeting",
"description": "OpenPanel's simple event-based pricing is easy to predict. PostHog's multi-product metering across events, recordings, flags, and surveys can lead to unexpected costs.",
"icon": "dollar-sign"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from PostHog to OpenPanel.",
"items": [
{
"question": "Is OpenPanel really free?",
"answer": "Yes! OpenPanel offers a generous free tier with 10,000 events per month. Self-hosting is completely free with no limits. PostHog also has generous free tiers (1M events, 5K recordings) but costs can scale quickly with usage."
},
{
"question": "Why switch from PostHog to OpenPanel?",
"answer": "Teams switch for several reasons: simpler pricing without multi-product metering, smaller SDK size (2.3KB vs 52KB+), true cookie-free tracking by default, easier self-hosting, and a focused analytics experience without feature bloat."
},
{
"question": "What features will I lose switching from PostHog?",
"answer": "PostHog includes feature flags, session replay, surveys, and A/B experiments in their platform. If you actively use these, you'd need separate tools. If you primarily use PostHog for analytics, OpenPanel provides everything you need with less complexity."
},
{
"question": "How does OpenPanel compare on privacy?",
"answer": "OpenPanel is cookie-free by default - no configuration needed. PostHog uses cookies by default and requires specific setup for cookieless mode, which disables some features like cross-session user identification."
},
{
"question": "Can I self-host OpenPanel?",
"answer": "Yes! OpenPanel runs in a simple Docker container with ClickHouse. PostHog self-hosting requires multiple services (ClickHouse, Kafka, Redis, PostgreSQL) and has official limitations of around 100k events/month for single-server hobby deployments."
},
{
"question": "Is PostHog more feature-rich than OpenPanel?",
"answer": "PostHog offers more products (10+ including feature flags, session replay, surveys, A/B testing, data warehouse). However, this comes with added complexity. OpenPanel focuses on doing analytics exceptionally well with a simpler, more focused experience."
},
{
"question": "How do SDK sizes compare?",
"answer": "OpenPanel's SDK is 2.3KB gzipped. PostHog's core library is 52KB+ gzipped, though they lazy-load additional features like session replay. The difference impacts page load times and Core Web Vitals."
},
{
"question": "Which is better for startups?",
"answer": "Both offer generous free tiers. PostHog provides more features out of the box (feature flags, etc.) but with more complexity. OpenPanel is simpler to set up and understand, making it ideal for teams that want focused analytics without the overhead of an all-in-one platform."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,476 @@
{
"slug": "simple-analytics-alternative",
"page_type": "alternative",
"seo": {
"title": "Simple Analytics Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Simple Analytics. Discover why teams choose OpenPanel as their Simple Analytics alternative for product analytics, user identification, and self-hosting while maintaining privacy-first principles.",
"noindex": false
},
"hero": {
"heading": "Simple Analytics Alternative",
"subheading": "Love Simple Analytics' privacy focus and clean dashboard? OpenPanel adds product analytics capabilities - funnels, cohorts, retention, and user identification - plus self-hosting options and longer data retention on the free tier.",
"badges": [
"Open-source",
"Privacy-first",
"Self-hostable",
"Product Analytics"
]
},
"competitor": {
"name": "Simple Analytics",
"logo": "/logos/simple-analytics.svg",
"url": "https://simpleanalytics.com",
"short_description": "Privacy-focused web analytics with AI assistant, clean design, and Netherlands-based hosting.",
"founded": 2018,
"headquarters": "Amsterdam, Netherlands"
},
"summary_comparison": {
"title": "OpenPanel vs Simple Analytics: Which is right for you?",
"intro": "Both are privacy-focused analytics platforms. Simple Analytics focuses on simple web traffic metrics. OpenPanel adds product analytics with user identification and self-hosting.",
"one_liner": "Simple Analytics excels at simple web stats with AI assistant; OpenPanel adds product analytics, self-hosting, and longer free-tier retention.",
"best_for_openpanel": [
"SaaS products needing user-level analytics and retention tracking",
"Teams wanting self-hosting for complete data control",
"Projects needing longer free-tier data retention (vs 30 days)",
"Mobile app developers needing native iOS, Android, React Native SDKs"
],
"best_for_competitor": [
"Simple content sites and blogs wanting traffic stats only",
"Teams valuing the AI assistant for conversational analytics queries",
"Users wanting Mini Websites feature to see exact referring pages",
"Organizations prioritizing Netherlands/EU-only data hosting"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Simple Analytics compare on key factors.",
"items": [
{
"label": "Analytics Depth",
"openpanel": "Web + Product Analytics",
"competitor": "Web Analytics Only",
"notes": "OpenPanel combines web analytics with product analytics including funnels, retention, cohorts, and user profiles. Simple Analytics focuses on simple website traffic metrics with basic goals tracking."
},
{
"label": "Self-Hosting",
"openpanel": "Full self-hosting available",
"competitor": "Cloud-only (no self-host option)",
"notes": "OpenPanel offers full self-hosting in a single Docker container. Simple Analytics is cloud-only with no self-hosting option available."
},
{
"label": "Free Tier Data Retention",
"openpanel": "Full data retention",
"competitor": "30-day retention only",
"notes": "OpenPanel's free tier includes full data retention. Simple Analytics' free tier deletes data older than 30 days automatically."
},
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Simple Analytics uses anonymization and doesn't track individuals."
},
{
"label": "AI Assistant",
"openpanel": "Coming Soon",
"competitor": "Yes - Chat with analytics",
"notes": "Simple Analytics offers an AI assistant that lets you chat with your analytics to get insights. OpenPanel is developing similar capabilities."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are privacy-focused, but with different capabilities and feature sets.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources",
"openpanel": true,
"competitor": true,
"notes": "Both track referrers and traffic sources"
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "Simple Analytics uses timezone instead of IP for location"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true,
"notes": "Both support custom events"
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics has basic goals but no multi-step funnels"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics' anonymous model doesn't support retention"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics intentionally doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics provides aggregate data only"
},
{
"name": "User Path Analysis",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics shows top pages but not user journeys"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics is analytics-only, no experimentation"
},
{
"name": "AI Chat Assistant",
"openpanel": false,
"competitor": true,
"notes": "Simple Analytics AI lets you chat with your analytics"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": true,
"notes": "Both offer scheduled email reports"
},
{
"name": "Dashboard Sharing",
"openpanel": true,
"competitor": true,
"notes": "Both support public and private dashboard sharing"
},
{
"name": "Google Analytics Import",
"openpanel": false,
"competitor": true,
"notes": "Simple Analytics has a GA import tool"
},
{
"name": "Ad-Blocker Bypass",
"openpanel": true,
"competitor": true,
"notes": "Simple Analytics requires Team plan for this feature"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true,
"notes": "Both are cookieless by default"
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true,
"notes": "Both designed with GDPR compliance in mind"
},
{
"name": "EU Data Hosting",
"openpanel": true,
"competitor": true,
"notes": "Simple Analytics data never leaves Netherlands/EU"
},
{
"name": "Self-Hosting Option",
"openpanel": true,
"competitor": false,
"notes": "Simple Analytics is cloud-only"
},
{
"name": "HIPAA Compliant",
"openpanel": true,
"competitor": true,
"notes": "Simple Analytics claims HIPAA compliance (no PHI collected)"
}
]
},
{
"group": "Integrations",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": true,
"notes": "Simple Analytics offers Stats API and Export API"
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true,
"notes": "Both support CSV export"
},
{
"name": "WordPress Plugin",
"openpanel": true,
"competitor": true,
"notes": "Both have WordPress integrations"
},
{
"name": "NPM/JavaScript SDK",
"openpanel": true,
"competitor": true,
"notes": "Both provide JavaScript integration options"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "1.9 KB (light) / 3.7 KB (full) gzipped",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"WordPress",
"Webflow",
"Squarespace",
"WIX",
"Ghost",
"Cloudflare",
"Google Tag Manager",
"Looker Studio",
"Power BI"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "No - Closed source (only tracking scripts MIT)",
"notes": "Simple Analytics is closed-source (only their tracking scripts are MIT licensed on GitHub)"
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Not available (cloud-only service)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "Proprietary (hosted on Worldstream/Leaseweb servers in Netherlands)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "30 days (free), 3 years (Simple), 5 years (Team)",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "Unknown (closed-source)",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Simple Analytics has a free tier but with limited data retention. OpenPanel offers full retention on free tier.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Full data retention even on free tier."
},
"competitor": {
"model": "Datapoint-based with limited free tier",
"description": "Free: Unlimited pageviews, 30-day retention, 5 sites, 1 user. Simple ($15/month): 10 sites, 3-year retention. Team ($40/month): 20 sites, 5-year retention, 2+ users, export API. 50% discount for nonprofits.",
"free_tier": "Free forever - unlimited pageviews (fair use), 30-day retention",
"pricing_url": "https://simpleanalytics.com/pricing"
}
},
"migration": {
"title": "Migrating from Simple Analytics to OpenPanel",
"intro": "Both use lightweight scripts and simple event tracking, making migration straightforward.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts, so the transition is straightforward."
},
{
"title": "Map Events",
"description": "Simple Analytics custom events translate directly to OpenPanel's op.track() calls."
},
{
"title": "Set Up User Identification (New)",
"description": "Unlike Simple Analytics, OpenPanel can identify users. Add op.identify() calls to unlock retention, cohorts, and user profiles."
},
{
"title": "Configure Product Analytics (New)",
"description": "Set up funnels, retention reports, and cohorts. These features aren't available in Simple Analytics."
},
{
"title": "Remove Simple Analytics Script",
"description": "Once verified, remove the Simple Analytics tracking script. Both are cookie-free so no consent changes needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use simple event tracking APIs."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Simple Analytics",
"intro": "Choose OpenPanel when you need product analytics, self-hosting, or longer data retention on free tier.",
"items": [
{
"title": "SaaS Products Needing User Analytics",
"description": "Simple Analytics shows aggregate website traffic. If you need to understand individual user journeys, retention, and behavior within your product, OpenPanel adds these capabilities while staying privacy-friendly.",
"icon": "users"
},
{
"title": "Teams Who Want Self-Hosting",
"description": "Simple Analytics is cloud-only with no self-hosting option. If data sovereignty or compliance requirements mean you need to host your own analytics, OpenPanel provides full self-hosting in a single Docker container.",
"icon": "server"
},
{
"title": "Projects Needing Longer Data Retention",
"description": "Simple Analytics' free tier only keeps 30 days of data. If you need historical data for trend analysis on a budget, OpenPanel's free tier includes full data retention.",
"icon": "database"
},
{
"title": "Mobile App Analytics",
"description": "Simple Analytics is designed for websites and doesn't provide native mobile SDKs. OpenPanel offers native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams Needing Funnel Analysis",
"description": "Simple Analytics has basic goals but doesn't offer multi-step funnel analysis. If understanding conversion paths matters, OpenPanel provides detailed funnel visualization.",
"icon": "filter"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Simple Analytics to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Simple Analytics?",
"answer": "Yes! Both are cookie-free by default and don't require consent banners. The key difference is that OpenPanel allows optional user identification for product analytics, while Simple Analytics is strictly anonymous. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Simple Analytics to OpenPanel?",
"answer": "Teams typically switch when they need: 1) Product analytics (funnels, retention, cohorts), 2) User identification, 3) Self-hosting options, 4) Longer data retention on the free tier, or 5) Native mobile SDKs. Simple Analytics excels at simple web analytics but doesn't offer these capabilities."
},
{
"question": "Does Simple Analytics have a free tier?",
"answer": "Yes, but with limitations. Simple Analytics offers a free-forever plan with unlimited pageviews (fair use) but only 30-day data retention and basic features. OpenPanel's free tier includes 10,000 events with full data retention and all features."
},
{
"question": "Can I self-host Simple Analytics?",
"answer": "No. Simple Analytics is a cloud-only service with no self-hosting option. They host all data in the Netherlands on EU servers. OpenPanel offers full self-hosting in a single Docker container if you need complete data control."
},
{
"question": "Which has the smaller tracking script?",
"answer": "Simple Analytics offers two script versions: a 'light' version at 1.9KB and a full version at 3.7KB (gzipped). OpenPanel's script is 2.3KB. All are significantly smaller than Google Analytics (45KB+)."
},
{
"question": "Can Simple Analytics track mobile apps?",
"answer": "Not natively. Simple Analytics is designed for web analytics and doesn't provide mobile SDKs. They have an iOS app to view your dashboard, but not to track mobile app users. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "What will I lose switching from Simple Analytics?",
"answer": "Simple Analytics has an AI chat assistant that lets you query your analytics conversationally - OpenPanel doesn't have this yet. They also have a Google Analytics import tool, a 'Mini Websites' feature showing referring pages, and an iOS app for viewing dashboards. However, you'll gain product analytics, self-hosting, and user identification that Simple Analytics doesn't offer."
},
{
"question": "Is Simple Analytics or OpenPanel better for blogs/content sites?",
"answer": "For simple content sites where you just need traffic stats, Simple Analytics' simplicity and AI assistant are excellent. Their Mini Websites feature is unique for seeing exactly which tweets or pages linked to you. If you're running a SaaS, e-commerce, or any product where understanding user behavior matters, OpenPanel's product analytics features provide more value."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,410 @@
{
"slug": "smartlook-alternative",
"page_type": "alternative",
"seo": {
"title": "Smartlook Alternative",
"description": "Compare OpenPanel with Smartlook: pricing, features, and deployment. OpenPanel offers product analytics with self-hosting; Smartlook combines analytics with session replay.",
"noindex": false
},
"hero": {
"heading": "Smartlook alternative",
"subheading": "Need product analytics without requiring session replay? OpenPanel is an open-source alternative to Smartlook that focuses on event-based analytics, funnels, and retention—with self-hosting and transparent pricing.",
"badges": [
"Open-source",
"Self-hostable",
"No session limits",
"Product analytics"
]
},
"competitor": {
"name": "Smartlook",
"logo": "/logos/smartlook.svg",
"url": "https://www.smartlook.com",
"short_description": "Combined product analytics and visual insights platform with session recordings, heatmaps, and event tracking. Acquired by Cisco in 2023.",
"founded": 2016,
"headquarters": "Brno, Czech Republic"
},
"summary_comparison": {
"title": "OpenPanel vs Smartlook: Which is right for you?",
"intro": "Both platforms offer product analytics, but Smartlook adds visual behavior tools (session replay, heatmaps) while OpenPanel focuses on event-based analytics with self-hosting.",
"one_liner": "OpenPanel is open source with self-hosting for product analytics; Smartlook combines analytics with session replay and heatmaps.",
"best_for_openpanel": [
"Teams needing self-hosting for data ownership and compliance",
"Open source requirements for transparency",
"Focus on event-based product analytics without visual replay",
"Teams wanting unlimited data retention with self-hosting",
"Server-side SDKs for backend tracking"
],
"best_for_competitor": [
"Teams needing session recordings to watch user interactions",
"UX designers requiring heatmaps (click, scroll, movement)",
"Mobile app crash reports with linked session recordings",
"Teams wanting combined analytics and replay in one tool",
"Unity game developers (Smartlook supports Unity)"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Smartlook compare on the factors that matter most.",
"items": [
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No (proprietary, Cisco-owned)"
},
{
"label": "Self-hosting",
"openpanel": "Yes, with Docker",
"competitor": "No (cloud only)"
},
{
"label": "Session replay",
"openpanel": "Not available",
"competitor": "Yes, full recordings"
},
{
"label": "Heatmaps",
"openpanel": "Not available",
"competitor": "Click, scroll, movement"
},
{
"label": "Pricing model",
"openpanel": "Event-based / free self-host",
"competitor": "Session-based from $55/mo"
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "OpenPanel focuses on product analytics; Smartlook combines analytics with visual behavior insights.",
"groups": [
{
"group": "Core analytics",
"features": [
{
"name": "Event tracking",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Funnels",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Retention analysis",
"openpanel": true,
"competitor": "Basic",
"notes": null
},
{
"name": "User profiles",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cohorts",
"openpanel": true,
"competitor": "Limited",
"notes": null
},
{
"name": "Custom dashboards",
"openpanel": true,
"competitor": "Limited",
"notes": null
},
{
"name": "Real-time data",
"openpanel": true,
"competitor": true,
"notes": null
}
]
},
{
"group": "Visual behavior analytics",
"features": [
{
"name": "Session recordings",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Click heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Scroll heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Movement heatmaps",
"openpanel": false,
"competitor": true,
"notes": null
},
{
"name": "Crash reports with replay",
"openpanel": false,
"competitor": true,
"notes": "Smartlook links crash reports to recordings"
}
]
},
{
"group": "Privacy & compliance",
"features": [
{
"name": "Self-hosting",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "Open source",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "GDPR compliant",
"openpanel": true,
"competitor": true,
"notes": null
},
{
"name": "Cookie-free tracking",
"openpanel": true,
"competitor": false,
"notes": null
},
{
"name": "SOC 2 certified",
"openpanel": false,
"competitor": true,
"notes": "Type II"
},
{
"name": "EU data residency",
"openpanel": "Via self-hosting",
"competitor": "Yes"
}
]
},
{
"group": "Integrations & data",
"features": [
{
"name": "REST API",
"openpanel": true,
"competitor": "Pro plans only",
"notes": null
},
{
"name": "Data export",
"openpanel": true,
"competitor": "CSV (Pro+)",
"notes": null
},
{
"name": "Webhooks",
"openpanel": true,
"competitor": "Limited",
"notes": null
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's how the implementations compare.",
"items": [
{
"label": "SDK size (JS)",
"openpanel": "~2.3 KB gzipped",
"competitor": "Larger (includes recording)",
"notes": "Smartlook's SDK includes session replay code"
},
{
"label": "Supported platforms",
"openpanel": [
"JavaScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Flutter",
"Node.js"
],
"competitor": [
"JavaScript",
"iOS",
"Android",
"React Native",
"Flutter",
"Unity",
"Cordova",
"Xamarin"
],
"notes": null
},
{
"label": "Open source",
"openpanel": "Yes (MIT)",
"competitor": "No",
"notes": null
},
{
"label": "Self-hosted deployment",
"openpanel": "Docker, simple setup",
"competitor": "Not available",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse + PostgreSQL",
"competitor": "AWS cloud infrastructure",
"notes": null
},
{
"label": "Data retention",
"openpanel": "Unlimited (self-hosted)",
"competitor": "1-3 months base, up to 12 months",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "OpenPanel offers event-based pricing with free self-hosting. Smartlook uses session-based pricing.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Start at $2.50/month for 5,000 events. Self-host for free with unlimited events. All features included at every tier."
},
"competitor": {
"model": "Session-based",
"description": "Free tier: 3,000 sessions/month with basic features. Pro: $55/month for 5,000 sessions with extended retention and exports. Enterprise: Custom pricing for 50,000+ sessions.",
"free_tier": "Yes (3,000 sessions/month)",
"pricing_url": "https://www.smartlook.com/pricing"
}
},
"migration": {
"title": "Migrating from Smartlook to OpenPanel",
"intro": "Moving from Smartlook to OpenPanel involves transitioning from combined session replay and analytics to event-based product analytics.",
"difficulty": "moderate",
"estimated_time": "2-4 hours",
"steps": [
{
"title": "Understand feature differences",
"description": "OpenPanel focuses on event-based product analytics. If you rely on session recordings and heatmaps, consider using complementary tools like Microsoft Clarity."
},
{
"title": "Create OpenPanel account or self-host",
"description": "Sign up for OpenPanel cloud or deploy self-hosted using Docker. Configure your project settings."
},
{
"title": "Install OpenPanel SDK",
"description": "Replace the Smartlook snippet with OpenPanel's SDK. Install via npm or use the CDN. For mobile apps, install the appropriate native SDK."
},
{
"title": "Map events and properties",
"description": "Convert Smartlook's event tracking to OpenPanel's event structure. Set up user identification using identify() to track users across sessions."
},
{
"title": "Build analytics dashboards",
"description": "Create funnels, retention charts, and cohort analyses in OpenPanel to replace Smartlook's analytics."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use similar event tracking APIs. Main difference is OpenPanel doesn't automatically record sessions."
},
"historical_data": {
"can_import": false,
"notes": "Historical session recordings from Smartlook cannot be migrated. Event data may be exportable depending on your Smartlook plan."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Smartlook",
"intro": "OpenPanel shines when you need product analytics with data ownership and don't require visual replay features.",
"items": [
{
"title": "Product analytics & growth",
"description": "Deep event-based analytics with funnels, retention analysis, and cohorts. Stronger retention and cohort capabilities than Smartlook.",
"icon": "chart"
},
{
"title": "Data ownership & self-hosting",
"description": "Complete data control with self-hosting. Smartlook is cloud-only with no self-hosting option.",
"icon": "server"
},
{
"title": "Open source requirements",
"description": "Full transparency and customization with MIT license. Smartlook is proprietary (now Cisco-owned).",
"icon": "code"
},
{
"title": "Unlimited data retention",
"description": "Self-hosted OpenPanel has unlimited retention. Smartlook limits data retention even on paid plans.",
"icon": "database"
},
{
"title": "Cost-effective for high volume",
"description": "Event-based pricing or free self-hosting. Smartlook's session-based pricing scales up quickly.",
"icon": "dollar"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Smartlook to OpenPanel.",
"items": [
{
"question": "Can OpenPanel replace Smartlook's session recordings?",
"answer": "No, OpenPanel does not provide session recordings or heatmaps. If you need visual behavior analytics, consider using Microsoft Clarity (free) or Hotjar alongside OpenPanel, or continue using Smartlook for recordings while using OpenPanel for deeper product analytics."
},
{
"question": "Which tool has better funnel analysis?",
"answer": "Both tools offer funnel analysis. Smartlook's advantage is the ability to watch session recordings of users who dropped off. OpenPanel offers more advanced funnel customization and cohort breakdowns."
},
{
"question": "Can I self-host Smartlook?",
"answer": "No, Smartlook is only available as a cloud-hosted service (now part of Cisco). OpenPanel offers both cloud hosting and self-hosted deployment via Docker for complete data ownership."
},
{
"question": "What happened with Cisco acquiring Smartlook?",
"answer": "Cisco completed the acquisition of Smartlook in June 2023. Smartlook is being integrated into Cisco's AppDynamics platform. The Smartlook product continues to operate independently."
},
{
"question": "How does pricing compare?",
"answer": "Smartlook uses session-based pricing with a free tier of 3,000 sessions/month and paid plans starting at $55/month. OpenPanel uses event-based pricing with 10,000 free events/month. OpenPanel's self-hosted option is completely free with unlimited events."
},
{
"question": "Does OpenPanel support mobile apps?",
"answer": "Yes. Both platforms offer mobile SDKs. OpenPanel supports iOS, Android, React Native, and Flutter with event tracking. Smartlook additionally supports Unity, Cordova, and Xamarin with session replay capabilities."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -0,0 +1,506 @@
{
"slug": "umami-alternative",
"page_type": "alternative",
"seo": {
"title": "Umami Alternative: Why Teams Choose OpenPanel",
"description": "Compare OpenPanel vs Umami Analytics. Discover why teams choose OpenPanel as their Umami alternative for deeper product analytics, user identification, and mobile SDKs while maintaining privacy.",
"noindex": false
},
"hero": {
"heading": "Umami Alternative",
"subheading": "Love Umami's simplicity and privacy focus? OpenPanel adds deeper product analytics - user identification, mobile SDKs, A/B testing, and detailed user profiles - while staying open source and cookie-free.",
"badges": [
"Open-source",
"Privacy-first",
"User Identification",
"Mobile SDKs"
]
},
"competitor": {
"name": "Umami Analytics",
"logo": "/logos/umami.svg",
"url": "https://umami.is",
"short_description": "Privacy-focused, open-source web analytics with lightweight script and developer-friendly setup.",
"founded": 2020,
"headquarters": "San Francisco Bay Area, USA"
},
"summary_comparison": {
"title": "OpenPanel vs Umami: Which is right for you?",
"intro": "Both are open-source, privacy-focused analytics tools. Umami focuses on anonymous web analytics. OpenPanel adds user identification and product analytics.",
"one_liner": "Umami excels at anonymous web analytics; OpenPanel adds user identification, product analytics, and mobile SDKs.",
"best_for_openpanel": [
"SaaS products needing user identification and retention tracking",
"Mobile app developers needing native iOS, Android, React Native SDKs",
"Teams needing A/B testing and experimentation capabilities",
"Products requiring session-level analysis and user behavior tracking"
],
"best_for_competitor": [
"Simple content sites and blogs wanting anonymous traffic stats",
"Developers prioritizing PostgreSQL over ClickHouse",
"Teams valuing extremely generous free tier (1M events/month)",
"Projects wanting the lightest possible tracking script"
]
},
"highlights": {
"title": "Key differences at a glance",
"intro": "Here's how OpenPanel and Umami compare on key factors.",
"items": [
{
"label": "User Identification",
"openpanel": "Yes - Track individual users",
"competitor": "No - Anonymous aggregate only",
"notes": "OpenPanel lets you identify and track individual users across sessions. Umami intentionally anonymizes all data and doesn't support user identification to maximize privacy."
},
{
"label": "Mobile SDKs",
"openpanel": "iOS, Android, React Native",
"competitor": "Web only (API for backend)",
"notes": "OpenPanel offers native mobile SDKs for iOS, Android, and React Native. Umami is designed for web analytics and requires API calls for any server-side tracking."
},
{
"label": "A/B Testing",
"openpanel": "Built-in experimentation",
"competitor": "Not available",
"notes": "OpenPanel includes A/B testing capabilities. Umami focuses purely on analytics and doesn't offer experimentation features."
},
{
"label": "Cloud Free Tier",
"openpanel": "10,000 events/month",
"competitor": "1 million events/month",
"notes": "Umami Cloud offers a very generous free tier of 1 million events per month. OpenPanel offers 10,000 events/month free."
},
{
"label": "Open Source License",
"openpanel": "MIT License",
"competitor": "MIT License",
"notes": "Both platforms use the permissive MIT license, offering maximum flexibility for commercial use and modification."
}
]
},
"feature_comparison": {
"title": "Feature comparison",
"intro": "Both are open source and privacy-focused, but with different depths of analytics capabilities.",
"groups": [
{
"group": "Web Analytics",
"features": [
{
"name": "Page Views & Visitors",
"openpanel": true,
"competitor": true
},
{
"name": "Traffic Sources & Referrers",
"openpanel": true,
"competitor": true
},
{
"name": "Geographic Data",
"openpanel": true,
"competitor": true,
"notes": "Both offer country, region, and city-level data"
},
{
"name": "Device & Browser",
"openpanel": true,
"competitor": true
},
{
"name": "UTM Campaign Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Real-Time Dashboard",
"openpanel": true,
"competitor": true
},
{
"name": "Bounce Rate",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Product Analytics",
"features": [
{
"name": "Custom Event Tracking",
"openpanel": true,
"competitor": true
},
{
"name": "Funnel Analysis",
"openpanel": true,
"competitor": true,
"notes": "Umami added funnels in 2023, supports URLs and custom events"
},
{
"name": "Retention Analysis",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added retention reports"
},
{
"name": "User Profiles",
"openpanel": true,
"competitor": false,
"notes": "Umami intentionally doesn't track individual users"
},
{
"name": "Cohort Analysis",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added cohort analysis"
},
{
"name": "User Path/Journey Analysis",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added journey reports"
},
{
"name": "User Identification",
"openpanel": true,
"competitor": false,
"notes": "Umami has distinct ID but no true user identification"
}
]
},
{
"group": "Advanced Features",
"features": [
{
"name": "A/B Testing",
"openpanel": true,
"competitor": false,
"notes": "Umami is analytics-only, no experimentation"
},
{
"name": "Custom Properties on Events",
"openpanel": true,
"competitor": true
},
{
"name": "Segments",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added saved filter segments"
},
{
"name": "Shareable Dashboards",
"openpanel": true,
"competitor": true,
"notes": "Both support public/private shareable links"
},
{
"name": "Email Reports",
"openpanel": true,
"competitor": false,
"notes": "Umami email reports only on cloud/paid plans"
},
{
"name": "Tracking Pixels",
"openpanel": false,
"competitor": true,
"notes": "Umami v3 added invisible tracking pixels for emails"
},
{
"name": "Link Tracking",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added short URL link tracking"
}
]
},
{
"group": "Privacy & Compliance",
"features": [
{
"name": "Cookie-Free by Default",
"openpanel": true,
"competitor": true
},
{
"name": "No Consent Banner Required",
"openpanel": true,
"competitor": true,
"notes": "Both claim no consent needed for basic analytics"
},
{
"name": "GDPR Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "CCPA Compliant",
"openpanel": true,
"competitor": true
},
{
"name": "IP Anonymization",
"openpanel": true,
"competitor": true
},
{
"name": "Self-Hostable",
"openpanel": true,
"competitor": true
}
]
},
{
"group": "Integrations & SDKs",
"features": [
{
"name": "JavaScript SDK",
"openpanel": true,
"competitor": true
},
{
"name": "React SDK",
"openpanel": true,
"competitor": true,
"notes": "Via npm packages for both"
},
{
"name": "Next.js SDK",
"openpanel": true,
"competitor": true
},
{
"name": "iOS SDK",
"openpanel": true,
"competitor": false,
"notes": "Umami is web-focused, no native mobile SDKs"
},
{
"name": "Android SDK",
"openpanel": true,
"competitor": false
},
{
"name": "React Native SDK",
"openpanel": true,
"competitor": false
},
{
"name": "Python SDK",
"openpanel": true,
"competitor": true,
"notes": "umami-analytics package available on PyPI"
},
{
"name": "REST API",
"openpanel": true,
"competitor": true
},
{
"name": "Data Export",
"openpanel": true,
"competitor": true,
"notes": "Umami v3 added UI-based data export"
}
]
}
]
},
"technical_comparison": {
"title": "Technical comparison",
"intro": "For developers evaluating analytics tools, here's the technical breakdown.",
"items": [
{
"label": "SDK Size",
"openpanel": "2.3 KB (gzipped)",
"competitor": "~2 KB (~1.5 KB gzipped)",
"notes": null
},
{
"label": "Platforms",
"openpanel": [
"JavaScript/TypeScript",
"React",
"Next.js",
"Vue",
"React Native",
"iOS",
"Android",
"Node.js",
"Python",
"PHP",
"Go",
"Rust"
],
"competitor": [
"JavaScript (browser)",
"React (via npm)",
"Next.js",
"Vue",
"Python (umami-analytics)",
"REST API"
],
"notes": null
},
{
"label": "Open Source",
"openpanel": "Yes - MIT License",
"competitor": "Yes - MIT License",
"notes": "Both are MIT licensed. Umami has 23,000+ GitHub stars."
},
{
"label": "Self Hosting",
"openpanel": "Docker (simple single-container setup)",
"competitor": "Docker Compose with PostgreSQL (Node.js 18.18+ required)",
"notes": null
},
{
"label": "Database",
"openpanel": "ClickHouse",
"competitor": "PostgreSQL (v3 dropped MySQL support)",
"notes": null
},
{
"label": "Data Retention",
"openpanel": "Unlimited (self-hosted), configurable (cloud)",
"competitor": "5 years (cloud), unlimited (self-hosted)",
"notes": null
},
{
"label": "Language",
"openpanel": "TypeScript/Node.js",
"competitor": "React/Next.js/Node.js",
"notes": null
}
]
},
"pricing": {
"title": "Pricing comparison",
"intro": "Umami offers a very generous free tier. OpenPanel offers simpler event-based pricing with all features.",
"openpanel": {
"model": "Event-based, transparent",
"description": "Simple pricing with 10,000 free events per month. All features included at every tier. Self-host for free with unlimited events."
},
"competitor": {
"model": "Event-based with very generous free tier",
"description": "1M events/month free. $0.00002/event after free tier. Unlimited websites, unlimited team members, 5 years data retention. Self-hosted is completely free with no limits.",
"free_tier": "1,000,000 events/month free",
"pricing_url": "https://umami.is/pricing"
}
},
"migration": {
"title": "Migrating from Umami to OpenPanel",
"intro": "Both use lightweight scripts with similar event tracking, making migration straightforward.",
"difficulty": "easy",
"estimated_time": "30 minutes to 2 hours",
"steps": [
{
"title": "Install OpenPanel SDK",
"description": "Add the OpenPanel SDK to your application. Both use lightweight scripts with similar size (~2KB), making the transition easy."
},
{
"title": "Map Custom Events",
"description": "Umami custom events translate directly to OpenPanel. umami.track('signup', {plan: 'pro'}) becomes op.track('signup', {plan: 'pro'})."
},
{
"title": "Add User Identification (New)",
"description": "Unlike Umami which is fully anonymous, OpenPanel supports user identification. Add op.identify() calls to unlock user profiles, retention by user, and cohort analysis."
},
{
"title": "Recreate Funnels and Reports",
"description": "Set up your funnels in OpenPanel. You'll have access to additional product analytics features like user-level analysis that Umami doesn't provide."
},
{
"title": "Remove Umami Script",
"description": "Once verified, remove the Umami tracking script. Both are cookie-free so no consent flow changes are needed."
}
],
"sdk_compatibility": {
"similar_api": true,
"notes": "Both use event-based tracking with similar APIs. umami.track() becomes op.track()."
},
"historical_data": {
"can_import": false,
"notes": "Most teams start fresh with OpenPanel and run both tools in parallel briefly."
}
},
"use_cases": {
"title": "Where OpenPanel is a better fit than Umami",
"intro": "Choose OpenPanel when you need user identification, mobile SDKs, or A/B testing.",
"items": [
{
"title": "SaaS Products Needing User Identification",
"description": "Umami anonymizes all visitors by design. If you need to track logged-in users, understand individual customer journeys, or analyze user-level retention, OpenPanel provides these capabilities while still respecting privacy.",
"icon": "user-check"
},
{
"title": "Mobile App Analytics",
"description": "Umami is designed for web analytics and doesn't offer native mobile SDKs. OpenPanel provides native iOS, Android, and React Native SDKs with full product analytics capabilities.",
"icon": "smartphone"
},
{
"title": "Teams Needing A/B Testing",
"description": "Umami focuses purely on analytics without experimentation features. If you need to run A/B tests and measure their impact, OpenPanel includes built-in experimentation.",
"icon": "git-branch"
},
{
"title": "Companies Building Data Pipelines",
"description": "While Umami offers API access and data export, OpenPanel's ClickHouse backend is optimized for high-volume analytics queries and integrations with data warehouses.",
"icon": "database"
},
{
"title": "Products Requiring Session-Level Analysis",
"description": "Umami provides aggregate metrics but doesn't track individual sessions in detail. OpenPanel lets you analyze specific user sessions and behaviors.",
"icon": "activity"
}
]
},
"faqs": {
"title": "Frequently asked questions",
"intro": "Common questions about switching from Umami to OpenPanel.",
"items": [
{
"question": "Is OpenPanel as privacy-friendly as Umami?",
"answer": "Both are cookie-free by default and GDPR compliant. The key difference is that OpenPanel allows optional user identification for product analytics, while Umami is strictly anonymous by design. You control whether to identify users in OpenPanel."
},
{
"question": "Why switch from Umami to OpenPanel?",
"answer": "Teams typically switch when they need user identification, mobile SDKs, or A/B testing. Umami excels at anonymous web analytics, but if you're building a product and need to understand individual user behavior across sessions, OpenPanel provides these capabilities."
},
{
"question": "How does Umami's free tier compare to OpenPanel?",
"answer": "Umami Cloud offers 1 million events/month free, which is very generous. OpenPanel offers 10,000 events/month free. However, Umami's self-hosted version is completely free with no limits, as is OpenPanel's self-hosted option."
},
{
"question": "Which has the smaller tracking script?",
"answer": "Both are very similar - Umami's script is about 2KB (1.5KB gzipped) and OpenPanel's is 2.3KB. Both are significantly smaller than Google Analytics (45KB+) or Mixpanel."
},
{
"question": "Can Umami track mobile apps?",
"answer": "Not with native SDKs. Umami is designed for web analytics and requires API calls for any non-browser tracking. OpenPanel offers native iOS, Android, and React Native SDKs."
},
{
"question": "Does Umami support heatmaps or session replay?",
"answer": "No. Umami focuses on privacy-first analytics without session recording or heatmaps. Neither does OpenPanel - both prioritize privacy over invasive tracking methods."
},
{
"question": "How does self-hosting compare?",
"answer": "Umami requires Docker with PostgreSQL (Node.js 18.18+ minimum). Umami v3 dropped MySQL support. OpenPanel runs in a single Docker container with simpler setup."
},
{
"question": "Is Umami or OpenPanel better for simple content websites?",
"answer": "For simple blogs or content sites where you just need traffic stats without user identification, Umami's generous free tier and simplicity are excellent. For products, SaaS, or apps where you need to understand user behavior, OpenPanel's product analytics features provide more value."
}
]
},
"ctas": {
"primary": {
"label": "Start with OpenPanel",
"href": "/onboarding"
},
"secondary": {
"label": "View on GitHub",
"href": "https://github.com/Openpanel-dev/openpanel"
}
}
}

View File

@@ -12,7 +12,7 @@ A **device ID** is a unique identifier generated for each device/browser combina
- **Origin** (project ID) - **Origin** (project ID)
- **Salt** (a rotating secret key) - **Salt** (a rotating secret key)
```typescript:packages/common/server/profileId.ts ```typescript
export function generateDeviceId({ export function generateDeviceId({
salt, salt,
ua, ua,
@@ -31,7 +31,7 @@ The salt used for device ID generation rotates **daily at midnight** (UTC). This
- Device IDs reset each day for privacy purposes - Device IDs reset each day for privacy purposes
- The system maintains both the current and previous day's salt to handle events that may arrive slightly after midnight - The system maintains both the current and previous day's salt to handle events that may arrive slightly after midnight
```typescript:apps/worker/src/jobs/cron.salt.ts ```typescript
// Salt rotation happens daily at midnight (pattern: '0 0 * * *') // Salt rotation happens daily at midnight (pattern: '0 0 * * *')
``` ```
@@ -45,7 +45,7 @@ A **session** represents a continuous period of user activity. Sessions are used
Sessions have a **30-minute timeout**. If no events are received for 30 minutes, the session automatically ends. Each new event resets this 30-minute timer. Sessions have a **30-minute timeout**. If no events are received for 30 minutes, the session automatically ends. Each new event resets this 30-minute timer.
```typescript:apps/worker/src/utils/session-handler.ts ```typescript
export const SESSION_TIMEOUT = 1000 * 60 * 30; // 30 minutes export const SESSION_TIMEOUT = 1000 * 60 * 30; // 30 minutes
``` ```
@@ -59,7 +59,7 @@ Sessions are **only created for client events**, not server events. This means:
Additionally, sessions are **not created for events older than 15 minutes**. This prevents historical data imports from creating artificial sessions. Additionally, sessions are **not created for events older than 15 minutes**. This prevents historical data imports from creating artificial sessions.
```typescript:apps/worker/src/jobs/events.incoming-event.ts ```typescript
// Sessions are not created if: // Sessions are not created if:
// 1. The event is from a server (uaInfo.isServer === true) // 1. The event is from a server (uaInfo.isServer === true)
// 2. The timestamp is from the past (isTimestampFromThePast === true) // 2. The timestamp is from the past (isTimestampFromThePast === true)
@@ -81,7 +81,7 @@ This means:
- Once you identify a user (by providing a profile ID), all their events will be associated with that profile - Once you identify a user (by providing a profile ID), all their events will be associated with that profile
- The same user can be tracked across multiple devices by using the same profile ID - The same user can be tracked across multiple devices by using the same profile ID
```typescript:packages/db/src/services/event.service.ts ```typescript
// If no profileId is provided, it defaults to deviceId // If no profileId is provided, it defaults to deviceId
if (!payload.profileId && payload.deviceId) { if (!payload.profileId && payload.deviceId) {
payload.profileId = payload.deviceId; payload.profileId = payload.deviceId;
@@ -116,7 +116,7 @@ Server events:
- Are attached to existing sessions if available - Are attached to existing sessions if available
- Are useful for backend tracking without session management - Are useful for backend tracking without session management
```typescript:packages/common/server/parser-user-agent.ts ```typescript
// Server events are detected by patterns like "Go-http-client/1.0" // Server events are detected by patterns like "Go-http-client/1.0"
function isServer(res: UAParser.IResult) { function isServer(res: UAParser.IResult) {
if (SINGLE_NAME_VERSION_REGEX.test(res.ua)) { if (SINGLE_NAME_VERSION_REGEX.test(res.ua)) {
@@ -128,7 +128,7 @@ function isServer(res: UAParser.IResult) {
The distinction is made in the event processing pipeline: The distinction is made in the event processing pipeline:
```typescript:apps/worker/src/jobs/events.incoming-event.ts ```typescript
const uaInfo = parseUserAgent(userAgent, properties); const uaInfo = parseUserAgent(userAgent, properties);
// Only client events create sessions // Only client events create sessions
@@ -158,7 +158,7 @@ The system validates timestamps to prevent abuse and ensure data quality:
1. **Future timestamps**: If a timestamp is more than **1 minute in the future**, the server timestamp is used instead 1. **Future timestamps**: If a timestamp is more than **1 minute in the future**, the server timestamp is used instead
2. **Past timestamps**: If a timestamp is older than **15 minutes**, it's marked as `isTimestampFromThePast: true` 2. **Past timestamps**: If a timestamp is older than **15 minutes**, it's marked as `isTimestampFromThePast: true`
```typescript:apps/api/src/controllers/track.controller.ts ```typescript
// Timestamp validation logic // Timestamp validation logic
const ONE_MINUTE_MS = 60 * 1000; const ONE_MINUTE_MS = 60 * 1000;
const FIFTEEN_MINUTES_MS = 15 * ONE_MINUTE_MS; const FIFTEEN_MINUTES_MS = 15 * ONE_MINUTE_MS;
@@ -177,7 +177,7 @@ const isTimestampFromThePast =
**Important**: Events with timestamps older than 15 minutes (`isTimestampFromThePast: true`) will **not create new sessions**. This prevents historical data imports from creating artificial sessions in your analytics. **Important**: Events with timestamps older than 15 minutes (`isTimestampFromThePast: true`) will **not create new sessions**. This prevents historical data imports from creating artificial sessions in your analytics.
```typescript:apps/worker/src/jobs/events.incoming-event.ts ```typescript
// Events from the past don't create sessions // Events from the past don't create sessions
if (uaInfo.isServer || isTimestampFromThePast) { if (uaInfo.isServer || isTimestampFromThePast) {
// Attach to existing session or track without session // Attach to existing session or track without session

View File

@@ -13,7 +13,7 @@ import WebSdkConfig from '@/components/web-sdk-config.mdx';
<Steps> <Steps>
### Step 1: Install ### Step 1: Install
```bash ```npm
npm install @openpanel/sdk npm install @openpanel/sdk
``` ```

View File

@@ -12,7 +12,7 @@ The OpenPanel Kotlin SDK allows you to track user behavior in your Kotlin applic
## Installation ## Installation
<Callout type="warn"> <Callout type="warn">
This package is not yet published. So you cannot install it with `gradle` yet. This package is not yet published. So you cannot install it with `` yet.
</Callout> </Callout>
<Steps> <Steps>
@@ -20,7 +20,7 @@ This package is not yet published. So you cannot install it with `gradle` yet.
Add the OpenPanel SDK to your project's dependencies: Add the OpenPanel SDK to your project's dependencies:
```gradle ```
dependencies { dependencies {
implementation 'dev.openpanel:openpanel:0.0.1' implementation 'dev.openpanel:openpanel:0.0.1'
} }

View File

@@ -17,7 +17,7 @@ import CommonSdkConfig from '@/components/common-sdk-config.mdx';
We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`. We're dependent on `expo-application` for `buildNumber`, `versionNumber` (and `referrer` on android) and `expo-constants` to get the `user-agent`.
```bash ```npm
npm install @openpanel/react-native npm install @openpanel/react-native
npx expo install expo-application expo-constants npx expo install expo-application expo-constants
``` ```

View File

@@ -133,7 +133,7 @@ window.op('init', {
<Steps> <Steps>
#### Step 1: Install the SDK #### Step 1: Install the SDK
```bash ```npm
npm install @openpanel/web npm install @openpanel/web
``` ```
@@ -186,7 +186,7 @@ declare global {
<Steps> <Steps>
##### Step 1: Install the SDK ##### Step 1: Install the SDK
```bash ```npm
npm install @openpanel/web npm install @openpanel/web
``` ```

View File

@@ -13,7 +13,7 @@ import WebSdkConfig from '@/components/web-sdk-config.mdx';
<Steps> <Steps>
### Step 1: Install ### Step 1: Install
```bash ```npm
npm install @openpanel/web npm install @openpanel/web
``` ```

View File

@@ -1,21 +0,0 @@
---
title: Pricing
description: Our simple, usage-based pricing means you only pay for what you use. Scale effortlessly for the best value.
---
import Pricing from '@/components/sections/pricing';
import Stats from '@/components/sections/stats';
import Testimonials from '@/components/sections/testimonials';
import Faq from '@/components/sections/faq';
Our pricing model is simple, pick how many events you want and pay that amount. It doesn't matter what tier you're in, you should always be able to:
- Create as many reports you want
- Add as many websites you needs
- Invite all your co-workers
- You probably get the point
<div className="lg:-mx-20 xl:-mx-40 not-prose -mt-16">
<Pricing className="!rounded-xl" />
<Testimonials />
<Faq />
</div>

View File

@@ -1,25 +0,0 @@
import {
articleCollection,
articleMeta,
docs,
meta,
pageCollection,
pageMeta,
} from '@/.source';
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from 'fumadocs-mdx';
export const source = loader({
baseUrl: '/docs',
source: createMDXSource(docs, meta),
});
export const articleSource = loader({
baseUrl: '/articles',
source: createMDXSource(articleCollection, articleMeta),
});
export const pageSource = loader({
baseUrl: '/',
source: createMDXSource(pageCollection, pageMeta),
});

View File

@@ -1,6 +0,0 @@
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

View File

@@ -3,50 +3,55 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "pnpm with-env next dev --port 3001", "build": "next build",
"build": "pnpm with-env next build", "dev": "next dev",
"start": "next start", "start": "next start",
"types:check": "fumadocs-mdx && tsc --noEmit",
"postinstall": "fumadocs-mdx", "postinstall": "fumadocs-mdx",
"with-env": "dotenv -e ../../.env -c --", "lint": "biome check",
"typecheck": "tsc --noEmit" "format": "biome format --write"
}, },
"dependencies": { "dependencies": {
"@hyperdx/node-opentelemetry": "^0.8.1", "@nivo/funnel": "^0.87.0",
"@number-flow/react": "0.3.5", "@number-flow/react": "0.5.10",
"@openpanel/common": "workspace:*", "@openpanel/common": "workspace:*",
"@openpanel/nextjs": "^1.1.1", "@openpanel/nextjs": "^1.1.1",
"@openpanel/payments": "workspace:^", "@openpanel/payments": "workspace:^",
"@openpanel/sdk-info": "workspace:^", "@openpanel/sdk-info": "workspace:^",
"@openstatus/react": "0.0.3", "@openstatus/react": "0.0.3",
"@radix-ui/react-accordion": "1.2.3", "@radix-ui/react-accordion": "1.2.12",
"@radix-ui/react-slider": "1.2.3", "@radix-ui/react-slider": "1.3.6",
"@radix-ui/react-slot": "1.1.2", "@radix-ui/react-slot": "1.2.4",
"@radix-ui/react-tooltip": "1.1.8", "@radix-ui/react-tooltip": "1.2.8",
"class-variance-authority": "0.7.1", "class-variance-authority": "0.7.1",
"clsx": "2.1.1", "clsx": "2.1.1",
"dotted-map": "2.2.3", "dotted-map": "2.2.3",
"framer-motion": "11.18.2", "framer-motion": "12.23.24",
"fumadocs-core": "14.1.1", "fumadocs-core": "16.1.0",
"fumadocs-mdx": "11.1.1", "fumadocs-mdx": "14.0.3",
"fumadocs-ui": "14.1.1", "fumadocs-ui": "16.1.0",
"geist": "1.3.1", "geist": "1.5.1",
"lucide-react": "0.454.0", "lucide-react": "^0.552.0",
"next": "15.0.3", "next": "16.0.5",
"next-themes": "^0.4.6",
"react": "catalog:", "react": "catalog:",
"react-dom": "catalog:", "react-dom": "catalog:",
"react-markdown": "^10.1.0",
"recharts": "^2.15.0",
"rehype-external-links": "3.0.0", "rehype-external-links": "3.0.0",
"tailwind-merge": "1.14.0", "tailwind-merge": "3.4.0",
"tailwindcss-animate": "1.0.7", "tailwindcss-animate": "1.0.7",
"zod": "catalog:" "zod": "catalog:"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4.1.16",
"@types/mdx": "^2.0.13", "@types/mdx": "^2.0.13",
"@types/node": "catalog:", "@types/node": "catalog:",
"@types/react": "catalog:", "@types/react": "catalog:",
"@types/react-dom": "catalog:", "@types/react-dom": "catalog:",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.22",
"postcss": "^8.4.47", "postcss": "^8.5.6",
"tailwindcss": "3.4.17", "tailwindcss": "4.1.17",
"typescript": "catalog:" "typescript": "catalog:"
} }
} }

View File

@@ -1,6 +1,5 @@
export default { export default {
plugins: { plugins: {
tailwindcss: {}, '@tailwindcss/postcss': {},
autoprefixer: {},
}, },
}; };

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 681 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Some files were not shown because too many files have changed in this diff Show More