mirror of
https://github.com/BillyOutlast/posthog.com.git
synced 2026-02-04 03:11:21 +01:00
version bump (#12254)
Co-authored-by: Cory Watilo <corywatilo@gmail.com> Co-authored-by: Eli Kinsey <eli@ekinsey.dev> Co-authored-by: Lucas Faria <12522524+lucasheriques@users.noreply.github.com> Co-authored-by: Ben White <ben@posthog.com> Co-authored-by: Juraj Majerik <juro.majerik@gmail.com> Co-authored-by: Rafael Audibert <32079912+rafaeelaudibert@users.noreply.github.com>
This commit is contained in:
32
.cursor/rules/components.mdc
Normal file
32
.cursor/rules/components.mdc
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# Component structure and naming
|
||||
|
||||
**Radix UI**
|
||||
- Custom components go in `/src/components/RadixUI`
|
||||
|
||||
|
||||
### Radix UI
|
||||
|
||||
We use Radix UI components. To get them to match our design, we typically create our own version of these components and place them in `/src/components/RadixUI`.
|
||||
|
||||
Use `Radix` prefix for imports, then wrap as `<Tabs />`, etc. Example:
|
||||
|
||||
```
|
||||
import { Tabs as RadixTabs } from 'radix-ui'
|
||||
```
|
||||
|
||||
This allows us to have simple naming conventions for our components like `<Tabs />`.
|
||||
|
||||
### Other components
|
||||
|
||||
We also have custom built components (for things that are outside the scope of Radix primatives). They start with `OS` in the name, like:
|
||||
|
||||
1. ``/src/components/OSButton`
|
||||
1. `/src/components/OSFieldset`
|
||||
1. `/src/components/OSIcons`
|
||||
1. `/src/components/OSTable`
|
||||
1. ``/src/components/OSTabs`
|
||||
34
.cursor/rules/data.mdc
Normal file
34
.cursor/rules/data.mdc
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# Hooks for product, customer, and navigation data
|
||||
|
||||
PostHog is a multi-product company, so data is stored in strucutred files in few central locations which makes it available across the site.
|
||||
|
||||
## Product data
|
||||
|
||||
1. @useProduct.ts is the first place to check for product information. This is used for beta products, unreleased products, and other "apps" that aren't fully-fledged products that customers typically pay for. (For example, there are entries for things like Webhooks and Notebooks for the purposes of displaying icons for these products.)
|
||||
2. If the product's slug or handle isn't found in there, @useProduct.ts is extended using @useProducts.tsx. When referencing product data, only refer to @useProduct.ts and let that file handle the data extending.
|
||||
|
||||
## Customer data
|
||||
|
||||
We reference customer names, logos, and sometimes quotes in various places on the site. This data is sourced from @useCustomers.ts.
|
||||
|
||||
## Navigation menus
|
||||
|
||||
[index.js](mdc:src/navs/index.js) is the source for all navigation data. This includes:
|
||||
|
||||
1. `companyMenu`
|
||||
1. `handbookSidebar`
|
||||
1. `communityMenu`
|
||||
1. `sexyLegalMenu`
|
||||
1. `companyMenu`
|
||||
1. `docsMenu`
|
||||
1. `pricingMenu`
|
||||
1. `productMenu`
|
||||
1. `menu`
|
||||
|
||||
During the development of this website (as of June 2025), this file can't be modified because it's in use with the live website. As a result, there are several places where this json data is filtered on the front end.
|
||||
|
||||
41
.cursor/rules/environment-structure.mdc
Normal file
41
.cursor/rules/environment-structure.mdc
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Environment & site structure
|
||||
|
||||
PostHog.com is the website for PostHog. It contains marketing materials, technical docs, tutorials, a headless Shopify merch store, and a community forum setup built in-house.
|
||||
|
||||
It's a static website built on Gatsby and hosted with Vercel.
|
||||
|
||||
## Resources and servers
|
||||
|
||||
- Use yarn instead of npm
|
||||
- Run the app with `yarn start`. To make sure everything is fresh, run `yarn clean && yarn && yarn start`.
|
||||
- The site runs on port `8001`. If you need to test something, check if it's already running on that port – no need to spin up a new server if so.
|
||||
- Sometimes the project is run inside a parent folder so a VS Code Workspace can include the squeak-strapi repo in another subfolder. Always verify your directory when searching for files or trying to run commands.
|
||||
|
||||
## Site features
|
||||
|
||||
PostHog.com is designed to replicate the experience of a desktop operating system within the browser. It has:
|
||||
|
||||
- A MacOS-style global header bar
|
||||
- The ability to have multiple windows open simultaneously
|
||||
- Windows that are draggable, resizeable, and can be snapped, maximized, or minimized
|
||||
- A panel to see all open windows
|
||||
|
||||
## Site structure
|
||||
|
||||
- The desktop is rendered in [index.tsx](mdc:src/components/Desktop/index.tsx). Apps (windows) can be launched by clicking an icon.
|
||||
- Apps are opened by passing `state={{ newWindow: true}}` and use various templates as specified by the "app".
|
||||
- When a page is opened (like /products [index.tsx](mdc:src/pages/products/index.tsx)), it opens inside of the desktop-style window component using [index.tsx](mdc:src/components/AppWindow/index.tsx). Then the page passes content into the app.
|
||||
- The window references `appSettings` in [App.tsx](mdc:src/context/App.tsx) to check for window size settings.
|
||||
|
||||
## "Apps"
|
||||
|
||||
- ReaderView: [index.tsx](mdc:src/components/ReaderView/index.tsx)
|
||||
- Wizard: [index.tsx](mdc:src/components/Wizard/index.tsx)
|
||||
- Explorer: [index.tsx](mdc:src/components/Explorer/index.tsx)
|
||||
- etc
|
||||
15
.cursor/rules/prompt-guardrails.mdc
Normal file
15
.cursor/rules/prompt-guardrails.mdc
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# AI code editing, prompt guardrails, and syntax
|
||||
|
||||
- Always check for any code changes in files you've edited before making further edits. I often make changes to files in between prompts and don't want my changes to get overwritten.
|
||||
- Assume user may have manually changed the file mid-flow
|
||||
- Always use double quotes (unless something different is necessated by content)
|
||||
- Always use sentence casing, even when writing internal documentation in Markdown
|
||||
- Add a `README.md` file for large, structural changes or new features
|
||||
- Always use best practices – if you're having to duplicate code or hard code values, ask before implementing because often times we can simplify or change our approach rather than ending up with unnecessary duplication
|
||||
- When implementing based on reference data, don't include a fallback value that's hard coded based on reference data. If a field is required, there's no need for a fallback. (For example if I provide an example image like <img src="value.jpg" width="800" height="400" />, don't hard code the width and height in the code)
|
||||
26
.cursor/rules/tailwind.mdc
Normal file
26
.cursor/rules/tailwind.mdc
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
# Tailwind usage guide for PostHog.com
|
||||
|
||||
- Don’t add new Tailwind styles or use stock colors
|
||||
- Use only colors defined in [tailwind.config.js](mdc:tailwind.config.js)
|
||||
- Two modes (light/dark), three schemes (primary/secondary/tertiary)
|
||||
|
||||
Use these classes:
|
||||
- `bg-primary`, `bg-accent`
|
||||
- `border-primary`, `border-input`
|
||||
- `text-primary`, `text-secondary`, `text-muted`, `text-input`
|
||||
|
||||
**Style guidance:**
|
||||
- Prefer inline Tailwind classes
|
||||
- Custom CSS → [global.css](mdc:src/styles/global.css) with `@apply`
|
||||
- JIT classes if needed
|
||||
- Fallback to nested regular CSS
|
||||
|
||||
**Links:**
|
||||
- `font-semibold`
|
||||
- `text-right`
|
||||
- `dark:text-yellow`
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "18"
|
||||
}
|
||||
},
|
||||
"postCreateCommand": ". ${NVM_DIR}/nvm.sh && nvm install --lts && nvm use 18"
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "22"
|
||||
}
|
||||
},
|
||||
"postCreateCommand": ". ${NVM_DIR}/nvm.sh && nvm install --lts && nvm use 22"
|
||||
}
|
||||
|
||||
236
.github/workflows/sales-handbook-notify.yml
vendored
236
.github/workflows/sales-handbook-notify.yml
vendored
@@ -1,125 +1,125 @@
|
||||
name: Sales Handbook Change Notification
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
paths:
|
||||
- 'contents/handbook/growth/sales/**'
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths:
|
||||
- 'contents/handbook/growth/sales/**'
|
||||
|
||||
jobs:
|
||||
notify-sales-team:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2 # Get current and previous commit for comparison
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
run: |
|
||||
# Get the list of changed files in the sales handbook directory
|
||||
CHANGED_FILES=$(git diff --name-status HEAD~1 HEAD -- contents/handbook/growth/sales/ | head -20)
|
||||
|
||||
# Format the changes for Slack
|
||||
echo "CHANGED_FILES<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$CHANGED_FILES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
# Get commit info
|
||||
COMMIT_MESSAGE=$(git log -1 --pretty=format:"%s")
|
||||
COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an")
|
||||
COMMIT_HASH=$(git log -1 --pretty=format:"%h")
|
||||
COMMIT_URL="https://github.com/${{ github.repository }}/commit/${{ github.sha }}"
|
||||
|
||||
echo "COMMIT_MESSAGE=$COMMIT_MESSAGE" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_AUTHOR=$COMMIT_AUTHOR" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_URL=$COMMIT_URL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Format file changes
|
||||
id: format-changes
|
||||
run: |
|
||||
# Process the changed files and format them nicely
|
||||
CHANGES="${{ steps.changed-files.outputs.CHANGED_FILES }}"
|
||||
|
||||
ADDED_FILES=""
|
||||
MODIFIED_FILES=""
|
||||
DELETED_FILES=""
|
||||
|
||||
while IFS=$'\t' read -r status file; do
|
||||
if [ -n "$file" ]; then
|
||||
filename=$(basename "$file")
|
||||
case "$status" in
|
||||
"A")
|
||||
ADDED_FILES="$ADDED_FILES• ➕ Added: $filename\n"
|
||||
;;
|
||||
"M")
|
||||
MODIFIED_FILES="$MODIFIED_FILES• ✏️ Modified: $filename\n"
|
||||
;;
|
||||
"D")
|
||||
DELETED_FILES="$DELETED_FILES• ❌ Deleted: $filename\n"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done <<< "$CHANGES"
|
||||
|
||||
# Combine all changes
|
||||
ALL_CHANGES="$ADDED_FILES$MODIFIED_FILES$DELETED_FILES"
|
||||
|
||||
# Remove trailing newline
|
||||
ALL_CHANGES=$(echo -e "$ALL_CHANGES" | sed '$d')
|
||||
|
||||
echo "ALL_CHANGES<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$ALL_CHANGES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Send Slack notification
|
||||
uses: 8398a7/action-slack@v3
|
||||
with:
|
||||
status: custom
|
||||
custom_payload: |
|
||||
{
|
||||
"channel": "#sales-alerts",
|
||||
"attachments": [
|
||||
{
|
||||
"color": "good",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "header",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "📚 Sales Handbook Updated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*Commit:* ${{ steps.changed-files.outputs.COMMIT_MESSAGE }}\n*Author:* ${{ steps.changed-files.outputs.COMMIT_AUTHOR }}\n*Hash:* `${{ steps.changed-files.outputs.COMMIT_HASH }}`"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*📝 Changes:*\n${{ steps.format-changes.outputs.ALL_CHANGES }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*🔗 Links:*\n• <${{ steps.changed-files.outputs.COMMIT_URL }}|View Commit>\n• <https://github.com/${{ github.repository }}/tree/${{ github.sha }}/contents/handbook/growth/sales|View Sales Handbook>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_SALES_WEBHOOK }}
|
||||
notify-sales-team:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2 # Get current and previous commit for comparison
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
run: |
|
||||
# Get the list of changed files in the sales handbook directory
|
||||
CHANGED_FILES=$(git diff --name-status HEAD~1 HEAD -- contents/handbook/growth/sales/ | head -20)
|
||||
|
||||
# Format the changes for Slack
|
||||
echo "CHANGED_FILES<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$CHANGED_FILES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
# Get commit info
|
||||
COMMIT_MESSAGE=$(git log -1 --pretty=format:"%s")
|
||||
COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an")
|
||||
COMMIT_HASH=$(git log -1 --pretty=format:"%h")
|
||||
COMMIT_URL="https://github.com/${{ github.repository }}/commit/${{ github.sha }}"
|
||||
|
||||
echo "COMMIT_MESSAGE=$COMMIT_MESSAGE" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_AUTHOR=$COMMIT_AUTHOR" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_OUTPUT
|
||||
echo "COMMIT_URL=$COMMIT_URL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Format file changes
|
||||
id: format-changes
|
||||
run: |
|
||||
# Process the changed files and format them nicely
|
||||
CHANGES="${{ steps.changed-files.outputs.CHANGED_FILES }}"
|
||||
|
||||
ADDED_FILES=""
|
||||
MODIFIED_FILES=""
|
||||
DELETED_FILES=""
|
||||
|
||||
while IFS=$'\t' read -r status file; do
|
||||
if [ -n "$file" ]; then
|
||||
filename=$(basename "$file")
|
||||
case "$status" in
|
||||
"A")
|
||||
ADDED_FILES="$ADDED_FILES• ➕ Added: $filename\n"
|
||||
;;
|
||||
"M")
|
||||
MODIFIED_FILES="$MODIFIED_FILES• ✏️ Modified: $filename\n"
|
||||
;;
|
||||
"D")
|
||||
DELETED_FILES="$DELETED_FILES• ❌ Deleted: $filename\n"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done <<< "$CHANGES"
|
||||
|
||||
# Combine all changes
|
||||
ALL_CHANGES="$ADDED_FILES$MODIFIED_FILES$DELETED_FILES"
|
||||
|
||||
# Remove trailing newline
|
||||
ALL_CHANGES=$(echo -e "$ALL_CHANGES" | sed '$d')
|
||||
|
||||
echo "ALL_CHANGES<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$ALL_CHANGES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Send Slack notification
|
||||
uses: 8398a7/action-slack@v3
|
||||
with:
|
||||
status: custom
|
||||
custom_payload: |
|
||||
{
|
||||
"channel": "#sales-alerts",
|
||||
"attachments": [
|
||||
{
|
||||
"color": "good",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "header",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "📚 Sales Handbook Updated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*Commit:* ${{ steps.changed-files.outputs.COMMIT_MESSAGE }}\n*Author:* ${{ steps.changed-files.outputs.COMMIT_AUTHOR }}\n*Hash:* `${{ steps.changed-files.outputs.COMMIT_HASH }}`"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*📝 Changes:*\n${{ steps.format-changes.outputs.ALL_CHANGES }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*🔗 Links:*\n• <${{ steps.changed-files.outputs.COMMIT_URL }}|View Commit>\n• <https://github.com/${{ github.repository }}/tree/${{ github.sha }}/contents/handbook/growth/sales|View Sales Handbook>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_SALES_WEBHOOK }}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -27,7 +27,6 @@ static/fonts/MatterSQItalicVF.woff2
|
||||
static/fonts/MatterSQVF.woff
|
||||
static/fonts/MatterSQVF.woff2
|
||||
yarn.lock
|
||||
src/components/Layout/Fonts.scss
|
||||
.vercel
|
||||
.env
|
||||
*Type.ts
|
||||
|
||||
10
.prettierrc
10
.prettierrc
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120
|
||||
}
|
||||
|
||||
30
README-OS.md
Normal file
30
README-OS.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## Components
|
||||
|
||||
### Colors
|
||||
|
||||
```
|
||||
<main data-scheme="primary" className="flex-1 bg-primary p-2">
|
||||
color test:
|
||||
<div data-scheme="primary" className="bg-primary text-primary border border-primary p-4">
|
||||
<p className="text-secondary">Primary text</p>
|
||||
<input
|
||||
className="bg-input hover:bg-input-hover border-input hover:border-input-hover text-muted"
|
||||
placeholder="Placeholder text"
|
||||
/>
|
||||
</div>
|
||||
<div data-scheme="secondary" className="bg-primary text-primary border border-primary p-4">
|
||||
<p className="text-secondary">Secondary text</p>
|
||||
<input
|
||||
className="bg-input hover:bg-input-hover border-input hover:border-input-hover text-muted"
|
||||
placeholder="Placeholder text"
|
||||
/>
|
||||
</div>
|
||||
<div data-scheme="tertiary" className="bg-primary text-primary border border-primary p-4">
|
||||
<p className="text-secondary">Tertiary text</p>
|
||||
<input
|
||||
className="bg-input hover:bg-input-hover border-input hover:border-input-hover text-muted"
|
||||
placeholder="Placeholder text"
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
```
|
||||
@@ -32,7 +32,7 @@ This is the repository for the PostHog website. It contains:
|
||||
|
||||
1. **Pre-installation**
|
||||
|
||||
Install [Node](https://nodejs.org/en/download/) (version 18) - if you installed Node using nvm, you can run `nvm use` to automatically switch to the correct version.
|
||||
Install [Node](https://nodejs.org/en/download/) (version 22) - if you installed Node using nvm, you can run `nvm use` to automatically switch to the correct version.
|
||||
|
||||
Install [Yarn](https://classic.yarnpkg.com/en/). (If you're on a Mac with Apple Silicon and get an error with `-86` in it, you may need to [install Rosetta](https://osxdaily.com/2020/12/04/how-install-rosetta-2-apple-silicon-mac/).)
|
||||
|
||||
@@ -42,7 +42,7 @@ This is the repository for the PostHog website. It contains:
|
||||
|
||||
|
||||
|
||||
1. **Start developing**
|
||||
2. **Start developing**
|
||||
|
||||
Clone the repo and navigate into your new site’s directory:
|
||||
|
||||
@@ -66,7 +66,7 @@ This is the repository for the PostHog website. It contains:
|
||||
|
||||
> **Tip:** Seeing a discrepancy between local development and staging/production? Preview the production build locally by running `gatsby build && gatsby serve`
|
||||
|
||||
1. **Open the source code and start editing!**
|
||||
3. **Open the source code and start editing!**
|
||||
|
||||
Your site is now running at `http://localhost:8001`!
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-matomo">Matomo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-fullstory">FullStory</a></td>
|
||||
<td className="w-3/12 text-center bg-gray-accent bg-opacity-50">
|
||||
<td className="w-3/12 text-center bg-accent bg-opacity-50">
|
||||
<strong>PostHog</strong>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -20,7 +20,7 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td className="bg-gray-accent bg-opacity-50"> </td>
|
||||
<td className="bg-accent bg-opacity-50"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single-page app support</td>
|
||||
@@ -44,7 +44,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -72,7 +72,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-red text-lg inline-block">
|
||||
<Close2 />
|
||||
</span>
|
||||
@@ -100,7 +100,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-red text-lg inline-block">
|
||||
<Close2 />
|
||||
</span>
|
||||
@@ -128,7 +128,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -156,7 +156,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -184,7 +184,7 @@
|
||||
<Close2 />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -212,7 +212,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -240,7 +240,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -268,7 +268,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -296,7 +296,7 @@
|
||||
<Check />
|
||||
</span>
|
||||
</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<span className="text-green text-lg inline-block">
|
||||
<Check />
|
||||
</span>
|
||||
@@ -308,7 +308,7 @@
|
||||
<td className="text-center">1 month</td>
|
||||
<td className="text-center">24 months</td>
|
||||
<td className="text-center">1 month</td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center">
|
||||
<td className="bg-accent bg-opacity-50 text-center">
|
||||
<strong>PostHog Cloud (free):</strong> 1 month
|
||||
<br />
|
||||
<strong>PostHog Cloud (paid):</strong> 3 months
|
||||
|
||||
220
contents/about.mdx
Normal file
220
contents/about.mdx
Normal file
@@ -0,0 +1,220 @@
|
||||
---
|
||||
title: We're here to help you build successful products
|
||||
---
|
||||
|
||||
<Letterhead />
|
||||
|
||||
<LottieAnimation variant="kendrick" />
|
||||
|
||||
## We're here to help product engineers build successful products
|
||||
|
||||
Literally every piece of SaaS that a product engineer needs.
|
||||
|
||||
This includes tools for building products, talking to customers customers, and making sense of all your customer data.
|
||||
|
||||
PostHog is a single platform for people who build things.
|
||||
|
||||
<OSButton asLink to="/products" variant="secondary" size="md" state={{ newWindow: true }}>
|
||||
Explore product suite
|
||||
</OSButton>
|
||||
|
||||
<div class="clear-both" />
|
||||
|
||||
---
|
||||
|
||||
### So how did we get here?
|
||||
|
||||
<YC />
|
||||
|
||||
We launched on Hacker News with our MVP in 2020 – just 4 weeks after we started writing code. The response was overwhelmingly positive.
|
||||
|
||||
Since then, we've grown far beyond analytics – into an entire product & data toolkit – used by <CustomerCount /> teams.
|
||||
|
||||
But our approach to building PostHog is very different.
|
||||
|
||||
<OSButton asLink to="/handbook/why-does-posthog-exist" variant="secondary" size="md" state={{ newWindow: true }}>
|
||||
Read our story
|
||||
</OSButton>
|
||||
|
||||
<div class="clear-both" />
|
||||
|
||||
---
|
||||
|
||||
## Why we're different
|
||||
|
||||
<DifferentHighlights />
|
||||
|
||||
<div class="grid @lg:grid-cols-2 @lg:gap-4">
|
||||
<div>
|
||||
|
||||
We're building the company we've always wanted to work for. This means rejecting all the annoying parts of the SaaS industry that have somehow become industry-standard.
|
||||
|
||||
If it gives you the ick, you know it gives us the ick too.
|
||||
|
||||
You can sum it up our ideology with this: we try to treat you how _we'd_ want to be treated.
|
||||
|
||||
</div>
|
||||
|
||||
<LottieAnimation variant="different" />
|
||||
|
||||
</div>
|
||||
|
||||
### We just do the right thing
|
||||
|
||||
<div class="@xl:float-right @xl:ml-6 mx-auto @xl:mx-0">
|
||||
|
||||
<TLDR>
|
||||
|
||||
PostHog \[breaks\] every SaaS rule:
|
||||
|
||||
- <Link to="https://github.com/posthog/posthog" state={{ newWindow: true }} external>
|
||||
Open source products
|
||||
</Link>
|
||||
- <Link to="/pricing" state={{ newWindow: true }}>
|
||||
Generous free tiers
|
||||
</Link>
|
||||
- <Link to="/sales" state={{ newWindow: true }}>
|
||||
No outbound sales
|
||||
</Link>
|
||||
- <Link to="/blog/analytics-pricing" state={{ newWindow: true }}>
|
||||
Price cuts
|
||||
</Link> instead of increases
|
||||
- <Link to="/side-project-insurance" state={{ newWindow: true }}>
|
||||
Protection
|
||||
</Link> against viral usage spikes
|
||||
|
||||
While Salesforce hikes prices 6% annually, PostHog proves there's room for startups that do the exact opposite of what private equity-backed software companies typically do.
|
||||
|
||||
</TLDR>
|
||||
|
||||
</div>
|
||||
|
||||
The _TLDR newsletter_ highlighted an article that covered some of the key things that make us different. Here are a few more they missed:
|
||||
|
||||
- **No loss leaders.** We don't sell products at a loss - we run the company default alive. This means we've never had layoffs, and we don't take huge risks that could result in the company disappearing overnight.
|
||||
- **No sleazy renewal tactics.** We don't screw you on contract terms like auto-renewal. And while most companies will try to _increase_ your prices every year, you won't find that here.
|
||||
- **Use it without talking to us.** You can use all our stuff monthly until you want to lock things in with us. We don't pressure people.
|
||||
- **Actually technical support.** We don't offshore our support. In fact, the <Link to="/teams/support" state={{ newWindow: true}}>entire support team</Link> has engineering backgrounds!
|
||||
- **Here for the long haul.** We have zero intention of selling our business. We want to see just how crazy huge this gigantic software stack can get - and we think that it will reach at least $100bn in value. We'll be around and fighting for a long, long time. It's our life's work.
|
||||
- **Honest communication.** Even in <Link to="/posts" state={{ newWindow: true}}>our content</Link>, it's more honest and not like the marketing-speak you've come to expect from other companies. It actively helps developers build successful products. That's our mission.
|
||||
|
||||
The reason we uniquely love doing all these sorts of things is that **we grow because of our reputation on the internet,** whereas every single competitor grows by salespeople. We are very, very proudly inbound only. This aligns us with customers. Long term, that is what wins.
|
||||
|
||||
### Transparency >>
|
||||
|
||||
<CloudinaryImage
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/about_transparency_47abc6e4dd.png"
|
||||
alt="PostHog handbook"
|
||||
width={651}
|
||||
height={289}
|
||||
className="@xl:float-right @xl:-mr-80 w-full @xl:-mt-2 mb-2 @xl:mb-0"
|
||||
/>
|
||||
|
||||
You can see how our entire company operates.
|
||||
|
||||
- Our <Link to="/handbook/growth/sales/overview" state={{ newWindow: true}}>manual for our salespeople</Link>, <Link to="/handbook/growth/marketing" state={{ newWindow: true}}>marketing team</Link>, and so on
|
||||
- You can even <Link to="/handbook/people/compensation" state={{ newWindow: true}}>see what everyone is paid</Link>
|
||||
- Our <Link to="/roadmap" state={{ newWindow: true}}>product roadmap</Link> is public – you can vote on what we should build next
|
||||
- <Link to="/teams" state={{ newWindow: true }}>
|
||||
See who's working on which product and what their goals are
|
||||
</Link>
|
||||
- Our codebase is <Link to="https://github.com/posthog/posthog" state={{ newWindow: true}} external>open source</Link> – if you're interested in seeing how we handle customer data, you can audit our entire codebase
|
||||
|
||||
You won't get this level of transparency from most companies!
|
||||
|
||||
If you're thinking about bringing PostHog into your business – or if you're interested in <Link to="/careers" state={{ newWindow: true}}>joining us</Link> – you should be able to make an informed decision. Not just about what exists today, but about the future and longevity of the organization.
|
||||
|
||||
## Everything in one place
|
||||
|
||||
Sure, building one product is great, but why stop there?
|
||||
|
||||
One of the advantages of PostHog is that we're building all the _tools_ you need, so you can have all the _context_ you need in one place. This frees up your time to focus on your users instead of fixing endless data integrations.
|
||||
|
||||
<p>
|
||||
We have{' '}
|
||||
<strong>
|
||||
<ProductCount /> paid products
|
||||
</strong>{' '}
|
||||
today, and even if we don't offer it yet, we will eventually.
|
||||
</p>
|
||||
|
||||
Our unique approach to building a company has allowed us to attract top talent. Many of our team are former founders. We allow our <Link to="/teams" state={{ newWindow: true}}>small teams</Link> to operate mostly autonomously, which means it's like we're building a bunch of mini startups within an organization that already has product-market fit.
|
||||
|
||||
We're going to build every piece of SaaS you need to make your product successful. You read that right. We've already got the world's best track record at delivering them by being the widest with so many customers.
|
||||
|
||||
## ~~Value-based pricing~~ _Usage-based pricing_
|
||||
|
||||
<div class="grid @lg:grid-cols-2 @lg:gap-4">
|
||||
<div>
|
||||
|
||||
Companies with large sales teams use _value-based pricing_ where they try to suss out how much you're willing to spend. PostHog operates more like a utility – we cover our costs with razor thin margins, and we make up for it with scale.
|
||||
|
||||
PostHog is always cheaper than the cheapest major competitor, so you know you don't have to compare pricing for each new product.
|
||||
|
||||
And because every product has a generous free tier, you can always try it out before paying anything at all. Without talking to sales. Because our pricing is completely transparent.
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<LottieAnimation variant="toy" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## The strategy appears to be working
|
||||
|
||||
<div className="flex justify-center @lg:float-right lg:-mr-4">
|
||||
<div className="@lg:ml-4 rotate-1 inline-block mx-auto mb-2 @lg:mt-2">
|
||||
<CloudinaryImage
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/team_tulum_a4899e0a9e.jpg"
|
||||
alt="PostHog pricing"
|
||||
width={782}
|
||||
height={521}
|
||||
className="border-4 border-white shadow-xl rounded"
|
||||
imgClassName="max-w-xs rounded"
|
||||
/>
|
||||
<p className="!text-xs text-right !my-0">The team at a recent offsite in Tulum</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Nobody wants to be a sheep, but it's probably a good sign when something is very popular.
|
||||
|
||||
We have over _<CustomerCount /> customers_ using our products. Just under a quarter of a million engineers use us. That's far, far more than any of our competitors – most have around 1-3k customers. It's what happens when the internet loves you.
|
||||
|
||||
**65% of every Y Combinator batch** (the world's best accelerator for startups) use our products.
|
||||
|
||||
<div class="clear-both" />
|
||||
|
||||
---
|
||||
|
||||
## So tl;dr:
|
||||
|
||||
<LottieAnimation variant="office" />
|
||||
|
||||
Whether you're looking to bring PostHog into your business – or if you're looking to build products with us – we hope you leave our portal on the internet with the understanding that we're here to build a generational company.
|
||||
|
||||
This isn't a bait-and-switch scheme or an attempt to exit in a few years. **We're building the company we've always wanted to work for** – and the type of organization that we'd want to buy software from.
|
||||
|
||||
If we haven't convinced you yet, come back to our site in a few months. It's almost guaranteed we'll have a few new products by then.
|
||||
|
||||
<div class="flex gap-1 items-center mt-6 mb-4">
|
||||
<James class="h-12" />
|
||||
{/* <Plus class="h-6" />
|
||||
<Tim class="h-10" /> */}
|
||||
</div>
|
||||
|
||||
<div class="bg-accent rounded border border-primary p-4 pr-44 flex gap-4 relative mt-4">
|
||||
|
||||
<p class="flex-1 !m-0">
|
||||
P.S. We've also got some{' '}
|
||||
<Link to="/merch" state={{ newWindow: true }}>
|
||||
cool company merch
|
||||
</Link>
|
||||
. It's made of high quality materials so you'll actually want to wear it.
|
||||
</p>
|
||||
|
||||
<div class="absolute right-2 top-4 @md:-top-8 size-36 rotate-3 rounded overflow-hidden">
|
||||
<OSButton asLink to="/merch?product=data-warehouse-t-shirt" state={{ newWindow: true }} className="bg-primary border border-primary active:bg-primary">
|
||||
<img src="https://res.cloudinary.com/dmukukwp6/image/upload/h_500,c_limit,q_auto,f_auto/warehouse_5d02e5d7b0.webp" alt="PostHog warehouse t-shirt" class="" /></OSButton>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,7 +23,7 @@ Until now, we charged the same for all events we ingested. This is standard prac
|
||||
|
||||
But now we’re changing that by splitting our product analytics pricing into two event types:
|
||||
|
||||
<h3><strong className="text-red dark:text-yellow">1. Identified events</strong> <span class="text-sm font-normal text-primary/75 dark:text-primary-dark/75">(previous default event type)</span></h3>
|
||||
<h3><strong className="text-red dark:text-yellow">1. Identified events</strong> <span class="text-sm font-normal text-secondary">(previous default event type)</span></h3>
|
||||
|
||||
Events generated by logged-in users associated with a person profile, which **can include custom data** like a user's name and email address
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ sidebar: Blog
|
||||
showTitle: true
|
||||
hideAnchor: true
|
||||
author:
|
||||
- andy-vandervell
|
||||
- andy-vandervell
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/open-source-testing-tools/testinghog.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/open-source-testing-tools/testinghog.png
|
||||
featuredImageType: full
|
||||
category: General
|
||||
tags:
|
||||
- Privacy
|
||||
- Privacy
|
||||
---
|
||||
|
||||
What do [Optimizely](/blog/posthog-vs-optimizely), Convert, and Webtrends Optimize have in common?
|
||||
@@ -34,7 +34,7 @@ There are three ways to comply with the Privacy rule when adopting analytics and
|
||||
|
||||
3. **Self-host and keep control of all your data:** The less common is to self-host tools for analytics and experimentation on your own infrastructure. This reduces the number of BAAs and general legal wrangling needed to generate user insights. The only downside is you'll need the expertise to manage self-hosted instances, or third-party support to do so, and you are wholly liable for any security breaches.
|
||||
|
||||
These are the broad principles, but **please consult an expert** before making any final decision on how to implement tools in compliance with HIPAA.
|
||||
These are the broad principles, but **please consult an expert** before making any final decision on how to implement tools in compliance with HIPAA.
|
||||
|
||||
## The best HIPAA-compliant A/B testing tools
|
||||
|
||||
@@ -44,20 +44,20 @@ These are the broad principles, but **please consult an expert** before making a
|
||||
|
||||
#### Features
|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Summary
|
||||
|
||||
[PostHog](https://posthog.com/) is an open source all-in-one platform that combines A/B testing with product analytics, session replay, feature management, and user surveys – everything you need to understand user behavior. All these tools are seamlessly integrated and, because you get everything in one, you only need to sign one BAA for all your analytics needs.
|
||||
|
||||
PostHog offers a BAA on its [platform add-ons](/platform-addons), which start at $250 and include [generous monthly free allowances](/pricing), such as 1 million analytics events every month. You can also self-host the open-source edition for free, though this isn't recommended as it's provided without support or guarantee.
|
||||
PostHog offers a BAA on its [platform packages](/platform-packages), which start at $250 and include [generous monthly free allowances](/pricing), such as 1 million analytics events every month. You can also self-host the open-source edition for free, though this isn't recommended as it's provided without support or guarantee.
|
||||
|
||||
### 2. Kameleoon
|
||||
|
||||
@@ -65,14 +65,14 @@ PostHog offers a BAA on its [platform add-ons](/platform-addons), which start at
|
||||
|
||||
#### Features
|
||||
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Summary
|
||||
|
||||
@@ -86,14 +86,14 @@ Kameleoon doesn't publish pricing publicly, but conversion optimization consulta
|
||||
|
||||
#### Features
|
||||
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Summary
|
||||
|
||||
@@ -107,26 +107,26 @@ Unlike most tools in this list, VWO charges separately for website and mobile ap
|
||||
|
||||
#### Features
|
||||
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Summary
|
||||
|
||||
[LaunchDarkly](/blog/best-launchdarkly-alternatives) is primarily a feature management platform for controlling what users see and when, and managing the rollout of new features. However, it also offers an experimentation suite, albeit as a paid add-on.
|
||||
|
||||
As a tool designed for engineers, LaunchDarkly supports running experiments on the front and back end. This enables engineers to run experiments to measure the performance impact of API and infrastructure changes, for example.
|
||||
As a tool designed for engineers, LaunchDarkly supports running experiments on the front and back end. This enables engineers to run experiments to measure the performance impact of API and infrastructure changes, for example.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Who does HIPAA apply to?
|
||||
|
||||
HIPAA applies to "covered entities," such as healthcare providers who transmit any health information in electronic form, health plans, and healthcare clearinghouses. Mobile apps fall under HIPAA if they store protected health information (PHI), and share it with any covered entity.
|
||||
HIPAA applies to "covered entities," such as healthcare providers who transmit any health information in electronic form, health plans, and healthcare clearinghouses. Mobile apps fall under HIPAA if they store protected health information (PHI), and share it with any covered entity.
|
||||
|
||||
HIPAA also applies to "business associates," which, according to the [US Department of Health and Human Services](https://www.hhs.gov/hipaa/for-professionals/covered-entities/sample-business-associate-agreement-provisions/index.html), are "a subcontractor that creates, receives, maintains, or transmits protected health information on behalf of another business associate."
|
||||
|
||||
@@ -134,7 +134,7 @@ Under HIPAA, the A/B testing tools in this guide would all be considered busines
|
||||
|
||||
### What is PHI (Protected Health Information)?
|
||||
|
||||
Protected Health Information (PHI) is any information about health status, provision of healthcare, or payment for healthcare that can be linked to an individual.
|
||||
Protected Health Information (PHI) is any information about health status, provision of healthcare, or payment for healthcare that can be linked to an individual.
|
||||
|
||||
This includes medical records, laboratory results, billing information, and any other information that identifies an individual and relates to their past, present, or future physical or mental health condition, treatment, or payment for healthcare services.
|
||||
|
||||
@@ -144,4 +144,4 @@ There's no objective correct answer here. In theory, self-hosting is preferable
|
||||
|
||||
But self-hosting also presents additional risks. You're wholly liable for ensuring your A/B testing infrastructure is secure, which can be challenging if you don't have the internal expertise to manage this. If this is the case, it may be better to rely on a HIPAA-compliant business associate who has experience hosting analytics at scale.
|
||||
|
||||
<NewsletterForm />
|
||||
<NewsletterForm />
|
||||
|
||||
@@ -6,20 +6,20 @@ sidebar: Blog
|
||||
showTitle: true
|
||||
hideAnchor: true
|
||||
author:
|
||||
- andy-vandervell
|
||||
- andy-vandervell
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/hipaa-compliant-ab-testing/hipaa.jpeg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/hipaa-compliant-ab-testing/hipaa.jpeg
|
||||
featuredImageType: full
|
||||
category: General
|
||||
tags:
|
||||
- Privacy
|
||||
- Privacy
|
||||
---
|
||||
|
||||
## What is HIPAA?
|
||||
|
||||
Passed in 1996, HIPAA (Health Insurance Portability and Accountability Act) defines the legal requirements for securing and handling health information, and the severe penalties for failing to do so.
|
||||
|
||||
Data protected under HIPAA is called [Protected Health Information](/blog/what-is-personal-data-pii) (PHI), or ePHI if it is digitized. It includes any data that can be used to identify the past, current or future health status of an individual.
|
||||
Data protected under HIPAA is called [Protected Health Information](/blog/what-is-personal-data-pii) (PHI), or ePHI if it is digitized. It includes any data that can be used to identify the past, current or future health status of an individual.
|
||||
|
||||
This includes test results and diagnoses, but also birthdays, ethnicity, gender and other information. Even an IP address can be considered ePHI under HIPAA.
|
||||
|
||||
@@ -28,13 +28,13 @@ While similar in some respects to the EU's General Data Protection Regulation (G
|
||||
There are two ways to be HIPAA-compliant while using analytics tools:
|
||||
|
||||
1. Self-host your analytics, so data remains totally within your control.
|
||||
2. Sign a Business Associate Agreement (BAA) with a third-party analytics tool.
|
||||
2. Sign a Business Associate Agreement (BAA) with a third-party analytics tool.
|
||||
|
||||
## What is a Business Associate Agreement (BAA)?
|
||||
|
||||
Some services enable HIPAA compliance through the creation of a [Business Associate Agreement](https://www.hhs.gov/hipaa/for-professionals/covered-entities/sample-business-associate-agreement-provisions/index.html) (US Department of Health). This is a contract with a service provider to ensure that they are jointly compliant and liable for services they provide.
|
||||
Some services enable HIPAA compliance through the creation of a [Business Associate Agreement](https://www.hhs.gov/hipaa/for-professionals/covered-entities/sample-business-associate-agreement-provisions/index.html) (US Department of Health). This is a contract with a service provider to ensure that they are jointly compliant and liable for services they provide.
|
||||
|
||||
It's worth noting that, because BAAs expose third-parties to increased risk and scrutiny, they are often an expensive option and/or require users to purchase a higher tier of license.
|
||||
It's worth noting that, because BAAs expose third-parties to increased risk and scrutiny, they are often an expensive option and/or require users to purchase a higher tier of license.
|
||||
|
||||
Some analytics tools, such as Google Analytics, don't offer BAAs and are therefore not HIPAA-compliant.
|
||||
|
||||
@@ -46,13 +46,13 @@ Some analytics tools, such as Google Analytics, don't offer BAAs and are therefo
|
||||
|
||||
#### Overview
|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
[PostHog](https://posthog.com/) is an open-source platform that combines product analytics, web analytics, session replay, feature flags, A/B testing, and user surveys into one platform. It gives you every tool you need to understand user behavior and, unlike typical analytics tools that rely on third-party integrations, all these tools work together seamlessly.
|
||||
|
||||
@@ -63,10 +63,10 @@ Being an all-in-one platform has two further benefits:
|
||||
|
||||
#### PostHog and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
A BAA is available on PostHog's [platform add-ons](/platform-addons), which also includes priority support and generous free usage limits for all tools – e.g. 1 million free analytics events every month. You can also self-host the open-source edition of PostHog, but this isn't recommended as it's provided without guarantee or support.
|
||||
A BAA is available on PostHog's [platform packages](/platform-packages), which also includes priority support and generous free usage limits for all tools – e.g. 1 million free analytics events every month. You can also self-host the open-source edition of PostHog, but this isn't recommended as it's provided without guarantee or support.
|
||||
|
||||
### 2. Mixpanel
|
||||
|
||||
@@ -74,20 +74,20 @@ A BAA is available on PostHog's [platform add-ons](/platform-addons), which also
|
||||
|
||||
#### Overview
|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
|
||||
[Mixpanel](https://mixpanel.com/) is a pure product analytics tool for analyzing user funnels and behavior. It doesn't offer built-in tools for things like session replay, feature management, A/B testing, or user surveys, but it does have extensive integrations with third-party tools for these.
|
||||
[Mixpanel](https://mixpanel.com/) is a pure product analytics tool for analyzing user funnels and behavior. It doesn't offer built-in tools for things like session replay, feature management, A/B testing, or user surveys, but it does have extensive integrations with third-party tools for these.
|
||||
|
||||
#### Mixpanel and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
A BAA is available on Mixpanel's Growth plan, which starts at $20 per month for 10,000 events. You'll need to sign separate BAAs with any other analytics you wish to integrate with Mixpanel.
|
||||
|
||||
@@ -99,20 +99,20 @@ A BAA is available on Mixpanel's Growth plan, which starts at $20 per month for
|
||||
|
||||
#### Overview
|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-green text-lg">✔</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
|
||||
[Countly](https://countly.com) is an analytics platform for mobile, web, and desktop applications that also offers add-ons for remote configuration, A/B testing, and user surveys. Support for app crash and error reports, and push notifications, makes it particularly well-suited to [mobile app analytics](/blog/best-mobile-app-analytics-tools).
|
||||
|
||||
#### Countly and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-red text-lg">✖</span>
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-red text-lg">✖</span>
|
||||
|
||||
Countly doesn't offer a BAA for HIPAA compliance on its hosted cloud, but it does offer the option to either:
|
||||
|
||||
@@ -125,24 +125,24 @@ This makes Countly a good option if you'd prefer to self-host your analytics.
|
||||
|
||||

|
||||
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Overview
|
||||
|
||||
[Freshpaint](https://www.freshpaint.io/) isn't an analytics tool per se, it's more of an analytics event tracker and customer data platform (CDP) that's specifically designed for healthcare companies.
|
||||
[Freshpaint](https://www.freshpaint.io/) isn't an analytics tool per se, it's more of an analytics event tracker and customer data platform (CDP) that's specifically designed for healthcare companies.
|
||||
|
||||
Freshpaint sits between data sources (e.g data warehouses) and third-party data destinations and ensures no PHI is passed between them. This means you can continue to use non-HIPAA compliant tools, such as Google Analytics, safe in the knowledge you're not accidentally passing PHI into them.
|
||||
|
||||
#### Freshpaint and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
Freshpaint is a cloud-only product specifically designed for healthcare companies, so offers a BAA for HIPAA compliance.
|
||||
|
||||
@@ -150,13 +150,13 @@ Freshpaint is a cloud-only product specifically designed for healthcare companie
|
||||
|
||||

|
||||
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Web analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Session replay:** <span className="text-red text-lg">✖</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
#### Overview
|
||||
|
||||
@@ -164,8 +164,8 @@ Piwik PRO is a commercial analytics and customer data platform spun out of the o
|
||||
|
||||
#### PiwikPRO and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-green text-lg">✔</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
PiwikPRO offers HIPAA compliance as part of its PRO Enterprise plan, either by signing a BAA or by self-hosting, giving you maximum flexibility.
|
||||
|
||||
@@ -175,20 +175,20 @@ PiwikPRO offers HIPAA compliance as part of its PRO Enterprise plan, either by s
|
||||
|
||||
#### Overview
|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-green text-lg">✔</span>
|
||||
- **A/B testing:** <span className="text-green text-lg">✔</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
[Amplitude](/blog/posthog-vs-amplitude) sits somewhere between PostHog and Mixpanel. It's a product analytics tool at its core, but also has extra features such as session replay, feature flags, and A/B testing. It also has anomaly detection, which will automatically flag when certain metrics fall outside expected trends, and creating insights based on natural language questions like "signups in the last 30 days."
|
||||
[Amplitude](/blog/posthog-vs-amplitude) sits somewhere between PostHog and Mixpanel. It's a product analytics tool at its core, but also has extra features such as session replay, feature flags, and A/B testing. It also has anomaly detection, which will automatically flag when certain metrics fall outside expected trends, and creating insights based on natural language questions like "signups in the last 30 days."
|
||||
|
||||
#### Amplitude and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
Amplitude offers a BAA, but doesn't stipulate the minimum terms for signing one on its website. You can also use its product analytics tool on top of a Snowflake data warehouse, which may be an option for HIPAA compliance if you're already storing analytics data in Snowflake.
|
||||
|
||||
@@ -198,13 +198,13 @@ Amplitude offers a BAA, but doesn't stipulate the minimum terms for signing one
|
||||
|
||||

|
||||
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
- **Product analytics:** <span className="text-green text-lg">✔</span>
|
||||
- **Web analytics:** <span className="text-red text-lg">✖</span>
|
||||
- **Session replay:** <span className="text-green text-lg">✔</span>
|
||||
- **Feature flags:** <span className="text-red text-lg">✖</span>
|
||||
- **A/B testing:** <span className="text-red text-lg">✖</span>
|
||||
- **Surveys:** <span className="text-red text-lg">✖</span>
|
||||
- **Customer data platform:** <span className="text-red text-lg">✖</span>
|
||||
|
||||
#### Overview
|
||||
|
||||
@@ -212,8 +212,8 @@ Amplitude offers a BAA, but doesn't stipulate the minimum terms for signing one
|
||||
|
||||
#### Heap and HIPAA compliance
|
||||
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
- **Self-hostable:** <span className="text-red text-lg">✖</span>
|
||||
- **BAA available:** <span className="text-green text-lg">✔</span>
|
||||
|
||||
Heap offers a BAA, but only on its Pro and Premier plans, not on its self-serve Growth plan. It's not available as a self-hosted product.
|
||||
|
||||
@@ -223,7 +223,7 @@ Heap offers a BAA, but only on its Pro and Premier plans, not on its self-serve
|
||||
|
||||
### Who does HIPAA apply to?
|
||||
|
||||
HIPAA applies to "covered entities," such as healthcare providers who transmit any health information in electronic form, health plans, and healthcare clearinghouses. Mobile apps fall under HIPAA if they store protected health information (PHI), and share it with any covered entity.
|
||||
HIPAA applies to "covered entities," such as healthcare providers who transmit any health information in electronic form, health plans, and healthcare clearinghouses. Mobile apps fall under HIPAA if they store protected health information (PHI), and share it with any covered entity.
|
||||
|
||||
HIPAA also applies to "business associates," which, according to the [US Department of Health and Human Services](https://www.hhs.gov/hipaa/for-professionals/covered-entities/sample-business-associate-agreement-provisions/index.html), are "a subcontractor that creates, receives, maintains, or transmits protected health information on behalf of another business associate."
|
||||
|
||||
@@ -231,7 +231,7 @@ Under HIPAA, the analytics tools in this guide would all be considered business
|
||||
|
||||
### What is PHI (Protected Health Information)?
|
||||
|
||||
Protected Health Information (PHI) is any information about health status, provision of healthcare, or payment for healthcare that can be linked to an individual.
|
||||
Protected Health Information (PHI) is any information about health status, provision of healthcare, or payment for healthcare that can be linked to an individual.
|
||||
|
||||
This includes medical records, laboratory results, billing information, and any other information that identifies an individual and relates to their past, present, or future physical or mental health condition, treatment, or payment for healthcare services.
|
||||
|
||||
@@ -241,4 +241,4 @@ There's no objective correct answer here. In theory, self-hosting is preferable
|
||||
|
||||
But self-hosting also presents additional risks. You're wholly liable for ensuring your analytics infrastructure is secure, which can be challenging if you don't have the internal expertise to manage this. If this is the case, it may be better to rely on a HIPAA-compliant business associate who has experience hosting analytics at scale.
|
||||
|
||||
<NewsletterForm />
|
||||
<NewsletterForm />
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
title: 'In-depth: PostHog vs Amplitude'
|
||||
date: 2024-09-10
|
||||
author:
|
||||
- andy-vandervell
|
||||
- andy-vandervell
|
||||
rootpage: /blog
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/comparisons/amplitude.jpeg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/comparisons/amplitude.jpeg
|
||||
featuredImageType: full
|
||||
category: General
|
||||
tags:
|
||||
- Comparisons
|
||||
- Comparisons
|
||||
---
|
||||
|
||||
import { ComparisonTable } from 'components/ComparisonTable'
|
||||
@@ -22,12 +22,12 @@ import { ComparisonRow } from 'components/ComparisonTable/row'
|
||||
|
||||
What does this mean?
|
||||
|
||||
- It means our pricing is 100% transparent.
|
||||
- It means engineers make product decisions.
|
||||
- It means [we ship fast](/changelog) and iterate based on user feedback.
|
||||
- It means engineers do support – all product teams have a [weekly support hero](/handbook/engineering/support-hero).
|
||||
- It means we work in the open – [our roadmap](/roadmap) and [company handbook](/handbook) are public.
|
||||
- It means no jumping on a "quick call" (unless you want to) – see [how we do sales](/sales).
|
||||
- It means our pricing is 100% transparent.
|
||||
- It means engineers make product decisions.
|
||||
- It means [we ship fast](/changelog) and iterate based on user feedback.
|
||||
- It means engineers do support – all product teams have a [weekly support hero](/handbook/engineering/support-hero).
|
||||
- It means we work in the open – [our roadmap](/roadmap) and [company handbook](/handbook) are public.
|
||||
- It means no jumping on a "quick call" (unless you want to) – see [how we do sales](/sales).
|
||||
|
||||
### 2. Affordable and transparent pricing
|
||||
|
||||
@@ -35,7 +35,7 @@ We're committed to [sustainably low pricing](/pricing/philosophy), and every cus
|
||||
|
||||
### 3. Analytics and data warehouse in one
|
||||
|
||||
Use our [built-in data warehouse](/data-warehouse) and SQL insight builder to analyze data from [Stripe](/tutorials/stripe-reports), [Hubspot](/tutorials/hubspot-reports), Salesforce, and [Zendesk](/tutorials/stripe-reports).
|
||||
Use our [built-in data warehouse](/data-warehouse) and SQL insight builder to analyze data from [Stripe](/tutorials/stripe-reports), [Hubspot](/tutorials/hubspot-reports), Salesforce, and [Zendesk](/tutorials/stripe-reports).
|
||||
|
||||
Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to analyze your data in PostHog, and [batch export event and person data](/docs/cdp/batch-exports) from PostHog to your data warehouse.
|
||||
|
||||
@@ -44,20 +44,85 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
### Product analytics
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="1 million events" column2="50k tracked users (Starter plan only)" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Autocapture" description="Capture events without manual logging" />
|
||||
<ComparisonRow column1={true} column2="Add on" feature="Query editor" description="Write your own queries in SQL" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Dashboards" description="Combine insights into shareable dashboards" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Graphs and trends" description="Build custom insights and visualizations" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Funnels" description="Track users through a sequence of events" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Retention" description="Visualize which users stay, for how long" />
|
||||
<ComparisonRow column1={true} column2={true} feature="User paths" description="Track user flows and where they drop-off" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Cohorts" description="Combine users based on properties and events for group analysis" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Group analytics" description="Track metrics at a company and account level" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Lifecycle analysis" description="Understand who is dormant, churning, and thriving" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Stickiness" description="Find out what events keep users coming back." />
|
||||
<ComparisonRow column1={true} column2={true} feature="Custom formulas" description="Use formulas to calculate unique insights" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web analytics" description="Simple dashboard of aggregate traffic, sources, campaigns, and session metrics" />
|
||||
<ComparisonRow
|
||||
column1="1 million events"
|
||||
column2="50k tracked users (Starter plan only)"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Autocapture"
|
||||
description="Capture events without manual logging"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2="Add on" feature="Query editor" description="Write your own queries in SQL" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Dashboards"
|
||||
description="Combine insights into shareable dashboards"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Graphs and trends"
|
||||
description="Build custom insights and visualizations"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Funnels"
|
||||
description="Track users through a sequence of events"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Retention"
|
||||
description="Visualize which users stay, for how long"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User paths"
|
||||
description="Track user flows and where they drop-off"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Cohorts"
|
||||
description="Combine users based on properties and events for group analysis"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Group analytics"
|
||||
description="Track metrics at a company and account level"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Lifecycle analysis"
|
||||
description="Understand who is dormant, churning, and thriving"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Stickiness"
|
||||
description="Find out what events keep users coming back."
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Custom formulas"
|
||||
description="Use formulas to calculate unique insights"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web analytics"
|
||||
description="Simple dashboard of aggregate traffic, sources, campaigns, and session metrics"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** PostHog supports [autocapture](/docs/product-analytics/autocapture), which means you can implement PostHog in mere minutes and ensure you don't miss out on events you haven't manually instrumented. Don't want autocapture? Just [turn it off](/docs/product-analytics/autocapture#disabling-autocapture) – we offer the best of both worlds.
|
||||
@@ -67,17 +132,62 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
### Feature flags
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="1 million API requests" column2="50k tracked users" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Boolean flags" description="Simple flags returning true or flag" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Multivariate flags" description="Flags with multiple customizable values" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Payloads" description="Flags with string, number, or JSON payloads" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Local evaluation" description="Store flag definitions locally" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Percentage rollouts" description="Target percentages of a group" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Custom targeting" description="Target users based on user properties, custom contexts" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
<ComparisonRow column1="Partial" column2={false} feature="Environments" description="Manage flags for dev, staging, prod" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Bootstrapping" description="Flags available on frontend application load" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
<ComparisonRow
|
||||
column1="1 million API requests"
|
||||
column2="50k tracked users"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Boolean flags"
|
||||
description="Simple flags returning true or flag"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Multivariate flags"
|
||||
description="Flags with multiple customizable values"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Payloads"
|
||||
description="Flags with string, number, or JSON payloads"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Local evaluation"
|
||||
description="Store flag definitions locally"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Percentage rollouts"
|
||||
description="Target percentages of a group"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Custom targeting"
|
||||
description="Target users based on user properties, custom contexts"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
<ComparisonRow
|
||||
column1="Partial"
|
||||
column2={false}
|
||||
feature="Environments"
|
||||
description="Manage flags for dev, staging, prod"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Bootstrapping"
|
||||
description="Flags available on frontend application load"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** PostHog's feature flags are tightly integrated with other features, so you can target session replays, surveys, and more using existing feature flags. See our guide on the [benefits of feature flags](/product-engineers/feature-flag-benefits-use-cases) for more.
|
||||
@@ -87,17 +197,67 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
### Experiments
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="1 million API requests" column2="None" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web experiments" description="Run A/B tests on web apps and websites" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Mobile experiments" description="Run A/B tests on Android and iOS apps" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Custom goals" description="Customize metrics that a test tracks" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Secondary metrics" description="Monitor impact on unrelated metrics" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Split testing" description="Split participants into groups" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Multivariate (A/B/n) testing" description="Test multiple variants of a change" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Statistical significance" description="Automatically checks for statistical significance" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Recommended run time" description="Calculates the recommended run time and sample size" />
|
||||
<ComparisonRow column1="Partial" column2={true} feature="Holdout testing" description="Withhold multiple features to measure cumulative impact" />
|
||||
<ComparisonRow column1="Bayesian" column2="Sequential" feature="Statistics engine" description="How the results of an experiment are calculated" />
|
||||
<ComparisonRow
|
||||
column1="1 million API requests"
|
||||
column2="None"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web experiments"
|
||||
description="Run A/B tests on web apps and websites"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Mobile experiments"
|
||||
description="Run A/B tests on Android and iOS apps"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Custom goals"
|
||||
description="Customize metrics that a test tracks"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Secondary metrics"
|
||||
description="Monitor impact on unrelated metrics"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="Split testing" description="Split participants into groups" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Multivariate (A/B/n) testing"
|
||||
description="Test multiple variants of a change"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Statistical significance"
|
||||
description="Automatically checks for statistical significance"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Recommended run time"
|
||||
description="Calculates the recommended run time and sample size"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Partial"
|
||||
column2={true}
|
||||
feature="Holdout testing"
|
||||
description="Withhold multiple features to measure cumulative impact"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Bayesian"
|
||||
column2="Sequential"
|
||||
feature="Statistics engine"
|
||||
description="How the results of an experiment are calculated"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** Amplitude's Web Experiments feature isn't available on any self-serve plan and the price isn't disclosed. You must contact its sales team to use it.
|
||||
@@ -107,20 +267,90 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
### Session replay
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="5,000 recordings" column2="1,000 recordings" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web app recordings" description="Capture recordings from single-page apps" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Mobile app recordings" description="Capture recordings in iOS and Android apps" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Heatmaps" description="Visualize where users click in your app or website" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Identity detection" description="Link recordings to user IDs" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Console logs" description="Capture extra content from a user's browser" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Playlists" description="Sort recordings into static and dynamic playlists" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Performance monitoring" description="Track network events within a session" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Privacy masking" description="Censor personal information from playback" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Conditional recording" description="Only capture the sessions you want" />
|
||||
<ComparisonRow column1={true} column2={false} feature="DOM explorer" description="Explore an interactive snapshot of replays" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Export recordings" description="Save important recordings offline" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Sample recorded sessions" description="Restrict the percentage of sessions that will be recorded" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Record via feature flag" description="Only record sessions for users that have the flag enabled" />
|
||||
<ComparisonRow
|
||||
column1="5,000 recordings"
|
||||
column2="1,000 recordings"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web app recordings"
|
||||
description="Capture recordings from single-page apps"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Mobile app recordings"
|
||||
description="Capture recordings in iOS and Android apps"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Heatmaps"
|
||||
description="Visualize where users click in your app or website"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Identity detection"
|
||||
description="Link recordings to user IDs"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Console logs"
|
||||
description="Capture extra content from a user's browser"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Playlists"
|
||||
description="Sort recordings into static and dynamic playlists"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Performance monitoring"
|
||||
description="Track network events within a session"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Privacy masking"
|
||||
description="Censor personal information from playback"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Conditional recording"
|
||||
description="Only capture the sessions you want"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="DOM explorer"
|
||||
description="Explore an interactive snapshot of replays"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Export recordings"
|
||||
description="Save important recordings offline"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Sample recorded sessions"
|
||||
description="Restrict the percentage of sessions that will be recorded"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Record via feature flag"
|
||||
description="Only record sessions for users that have the flag enabled"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** Replays let you watch how users experience your app, diagnose issues, improve support, and understand real user behavior in a way raw data can't. They are reconstructions of the session, _not_ video recordings of user's screen. Private info, such as passwords, are masked.
|
||||
@@ -130,17 +360,57 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
### Surveys
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="1500" column2="n/a" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Open text" description="Free text answers and feedback" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Product rating" description="Rank using emojis or number" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Single choice" description="Select one answer from multiple" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Multiple choice" description="Select more than one answer from multiple" />
|
||||
<ComparisonRow column1={true} column2={false} feature="NPS surveys" description="Net Promoter Score survey template" />
|
||||
<ComparisonRow column1={true} column2={false} feature="PMF surveys" description="Product-market fit survey template" />
|
||||
<ComparisonRow column1={true} column2={false} feature="User property targeting" description="Target users based on any of their user properties" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom colors & positioning" description="Customize the colors of your surveys to match your brand" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom HTML" description="Add custom HTML to your survey text" />
|
||||
<ComparisonRow column1={true} column2={false} feature="API mode" description="Create surveys via the API" />
|
||||
<ComparisonRow
|
||||
column1="1500"
|
||||
column2="n/a"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Open text" description="Free text answers and feedback" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Product rating" description="Rank using emojis or number" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Single choice"
|
||||
description="Select one answer from multiple"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Multiple choice"
|
||||
description="Select more than one answer from multiple"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="NPS surveys"
|
||||
description="Net Promoter Score survey template"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="PMF surveys"
|
||||
description="Product-market fit survey template"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="User property targeting"
|
||||
description="Target users based on any of their user properties"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Custom colors & positioning"
|
||||
description="Customize the colors of your surveys to match your brand"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Custom HTML"
|
||||
description="Add custom HTML to your survey text"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="API mode" description="Create surveys via the API" />
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** [Survey templates](/templates?filter=type&value=survey) make it easy to run NPS, product-market-fit (PMF), and customer satisfaction (CSAT) surveys in just a few clicks. Read our [guide comparing NPS, CSAT and CES](/product-engineers/nps-vs-csat-vs-ces) to for more on how to use surveys.
|
||||
@@ -150,49 +420,49 @@ Already have a warehouse? You can [link it with ours](/docs/data-warehouse) to a
|
||||
## Price comparison
|
||||
|
||||
<ProductScreenshot
|
||||
imageLight = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog_vs_amplitude_light_6accf68a1d.jpg"
|
||||
imageDark = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog_vs_amplitude_dark_6271c3bfa7.jpg"
|
||||
imageLight="https://res.cloudinary.com/dmukukwp6/image/upload/posthog_vs_amplitude_light_6accf68a1d.jpg"
|
||||
imageDark="https://res.cloudinary.com/dmukukwp6/image/upload/posthog_vs_amplitude_dark_6271c3bfa7.jpg"
|
||||
classes="rounded"
|
||||
alt="product analytics pricing"
|
||||
/>
|
||||
|
||||
PostHog charges for usage – i.e. analytics events, recorded replays, and so on. **Amplitude** charges based on monthly tracked users (MTUs).
|
||||
PostHog charges for usage – i.e. analytics events, recorded replays, and so on. **Amplitude** charges based on monthly tracked users (MTUs).
|
||||
|
||||
In the comparison, we're assuming 75 identified events per monthly tracked user (MTU), which is the typical usage for most PostHog users, though many customers send less than this.
|
||||
|
||||
| **Monthly tracked users** | **Amplitude Growth** | **PostHog** |   |
|
||||
|-------------------------|----------------------|-------------|-------------------------------------------------------------------------|
|
||||
| 1k | $61 | $0 | <strong class="text-green">$732 per year cheaper</strong> |
|
||||
| 2.5k | $99 | $0 | <strong class="text-green">$1,888 per year cheaper</strong> |
|
||||
| 5k | $124 | $0 | <strong class="text-green">$1,488 per year cheaper</strong> |
|
||||
| 10k | $186 | $0 | <strong class="text-green">$2,232 per year cheaper</strong> |
|
||||
| 25k | $249 | $217 | <strong class="text-green">$1,128 per year cheaper</strong> |
|
||||
| 50k | $561 | $430 | <strong class="text-green">$1,572 per year cheaper</strong> |
|
||||
| 75k | $841 | $625 | <strong class="text-green">$2,592 per year cheaper</strong> |
|
||||
| 100k | $1,061 | $820 | <strong class="text-green">$2,892 per year cheaper</strong> |
|
||||
| 150k | $1,584 | $1,207 | <strong class="text-green">$4,524 per year cheaper</strong> |
|
||||
| 200k | $2,100 | $1,600 | <strong class="text-green">$6,000 per year cheaper</strong> |
|
||||
| 300k | $3,150 | $2,091 | <strong class="text-green">$12,708 per year cheaper</strong> |
|
||||
| **Monthly tracked users** | **Amplitude Growth** | **PostHog** |   |
|
||||
| ------------------------- | -------------------- | ----------- | ------------------------------------------------------------ |
|
||||
| 1k | $61 | $0 | <strong class="text-green">$732 per year cheaper</strong> |
|
||||
| 2.5k | $99 | $0 | <strong class="text-green">$1,888 per year cheaper</strong> |
|
||||
| 5k | $124 | $0 | <strong class="text-green">$1,488 per year cheaper</strong> |
|
||||
| 10k | $186 | $0 | <strong class="text-green">$2,232 per year cheaper</strong> |
|
||||
| 25k | $249 | $217 | <strong class="text-green">$1,128 per year cheaper</strong> |
|
||||
| 50k | $561 | $430 | <strong class="text-green">$1,572 per year cheaper</strong> |
|
||||
| 75k | $841 | $625 | <strong class="text-green">$2,592 per year cheaper</strong> |
|
||||
| 100k | $1,061 | $820 | <strong class="text-green">$2,892 per year cheaper</strong> |
|
||||
| 150k | $1,584 | $1,207 | <strong class="text-green">$4,524 per year cheaper</strong> |
|
||||
| 200k | $2,100 | $1,600 | <strong class="text-green">$6,000 per year cheaper</strong> |
|
||||
| 300k | $3,150 | $2,091 | <strong class="text-green">$12,708 per year cheaper</strong> |
|
||||
|
||||
We also provide numerous ways to [control how many events you send](/tutorials/fewer-unwanted-events) and reduce your costs, including the option to send cheaper **anonymous events**.
|
||||
|
||||
### Identified vs anonymous events
|
||||
|
||||
Anonymous events **only include non-identifying data**, such as referral data (UTMs, domains, etc), device type, and basic location information.
|
||||
Anonymous events **only include non-identifying data**, such as referral data (UTMs, domains, etc), device type, and basic location information.
|
||||
|
||||
They're useful if you're tracking a huge number of users and only want to analyze aggregate data, such as on a content website with millions of visitors.
|
||||
They're useful if you're tracking a huge number of users and only want to analyze aggregate data, such as on a content website with millions of visitors.
|
||||
|
||||
Anonymous events are cheaper for us to ingest, so we charge you between 55% and 80% less for them. You'll only be charged the identified event rate when you call identifying functions like `posthog.identify()` or `posthog.group()`, or capture an event from an already-identified user.
|
||||
Anonymous events are cheaper for us to ingest, so we charge you between 55% and 80% less for them. You'll only be charged the identified event rate when you call identifying functions like `posthog.identify()` or `posthog.group()`, or capture an event from an already-identified user.
|
||||
|
||||
| **Monthly events** | **Identified events** | **Anonymous events** | **Change** |
|
||||
|--------------------|--------------------------|-----------------------------------|----------------|
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">1-2 million</strong> | <span class="text-[15px] font-semibold">$0.0002480</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000500</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">80% cheaper</strong> |
|
||||
| <strong class="text-15px">2-15 million</strong> | <span class="text-[15px] font-semibold">$0.0001040</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000343</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">67% cheaper</strong> |
|
||||
| <strong class="text-15px">15-50 million</strong> | <span class="text-[15px] font-semibold">$0.0000655</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000295</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">55% cheaper</strong> |
|
||||
| <strong class="text-15px">50-100 million</strong> | <span class="text-[15px] font-semibold">$0.0000364</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000218</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">40% cheaper</strong> |
|
||||
| <strong class="text-15px">100-250 million</strong> | <span class="text-[15px] font-semibold">$0.0000187</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000150</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">20% cheaper</strong> |
|
||||
| <strong class="text-15px">250+ million</strong> | <span class="text-[15px] font-semibold">$0.0000100</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000090</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">10% cheaper</strong> |
|
||||
| **Monthly events** | **Identified events** | **Anonymous events** | **Change** |
|
||||
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">1-2 million</strong> | <span class="text-[15px] font-semibold">$0.0002480</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000500</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">80% cheaper</strong> |
|
||||
| <strong class="text-15px">2-15 million</strong> | <span class="text-[15px] font-semibold">$0.0001040</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000343</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">67% cheaper</strong> |
|
||||
| <strong class="text-15px">15-50 million</strong> | <span class="text-[15px] font-semibold">$0.0000655</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000295</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">55% cheaper</strong> |
|
||||
| <strong class="text-15px">50-100 million</strong> | <span class="text-[15px] font-semibold">$0.0000364</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000218</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">40% cheaper</strong> |
|
||||
| <strong class="text-15px">100-250 million</strong> | <span class="text-[15px] font-semibold">$0.0000187</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000150</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">20% cheaper</strong> |
|
||||
| <strong class="text-15px">250+ million</strong> | <span class="text-[15px] font-semibold">$0.0000100</span><span class="text-sm opacity-70">/event</span> | <span class="text-[15px] font-semibold">$0.0000090</span><span class="text-sm opacity-70">/event</span> | <strong class="text-green">10% cheaper</strong> |
|
||||
|
||||
See [We've decided to make less money [Part 2]](/blog/analytics-pricing) for more on the difference between anonymous and identified events. You can use the [calculator on our pricing page](/pricing) to estimate how much you'll pay.
|
||||
|
||||
@@ -201,16 +471,36 @@ See [We've decided to make less money [Part 2]](/blog/analytics-pricing) for mor
|
||||
### Integrations
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1={true} column2={true} feature="Imports" description="Import data from data warehouses and other sources" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Exports" description="Export data to data warehouses other destinations" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Segment" description="Send events via Segment" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Zapier" description="Trigger Zapier automations" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Sentry" description="Connect to Sentry data" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Zendesk" description="Two-way integration for customer support" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Slack" description="Alerts for Slack" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Microsoft Teams" description="Alerts for Microsoft Teams" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Community integrations" description="Build your own integration" />
|
||||
<ComparisonRow column1={false} column2={true} feature="Google Ads" description="Import ROI data from Google Ads" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Imports"
|
||||
description="Import data from data warehouses and other sources"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Exports"
|
||||
description="Export data to data warehouses other destinations"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="Segment" description="Send events via Segment" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Zapier" description="Trigger Zapier automations" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Sentry" description="Connect to Sentry data" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Zendesk"
|
||||
description="Two-way integration for customer support"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="Slack" description="Alerts for Slack" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Microsoft Teams" description="Alerts for Microsoft Teams" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Community integrations"
|
||||
description="Build your own integration"
|
||||
/>
|
||||
<ComparisonRow column1={false} column2={true} feature="Google Ads" description="Import ROI data from Google Ads" />
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** This is just a small sample of available integrations. See our [data pipeline docs](/docs/cdp) for a full list of destinations, and our [data warehouse docs](/docs/data-warehouse) for a complete list of sources.
|
||||
@@ -220,16 +510,36 @@ See [We've decided to make less money [Part 2]](/blog/analytics-pricing) for mor
|
||||
### Security and compliance
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1={true} column2={true} feature="User privacy options" description="Anonymize users, drop personal data" />
|
||||
<ComparisonRow column1={true} column2={true} feature="History, audit logs" description="Manage and view flag edits and related users" />
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2 Type II" description="SOC 2 security certification" />
|
||||
<ComparisonRow column1={true} column2={true} feature="2FA" description="Enforce login with two-factor authentication" />
|
||||
<ComparisonRow column1="Enterprise" column2="Enterprise" feature="SAML/SSO" description="Use SAML or single sign-on authentication" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User privacy options"
|
||||
description="Anonymize users, drop personal data"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="History, audit logs"
|
||||
description="Manage and view flag edits and related users"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2 Type II" description="SOC 2 security certification" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="2FA"
|
||||
description="Enforce login with two-factor authentication"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Enterprise"
|
||||
column2="Enterprise"
|
||||
feature="SAML/SSO"
|
||||
description="Use SAML or single sign-on authentication"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** We offer a Business Associate Agreement (BAA) for any customer on our platform add-ons, which also includes priority support, SSO enforcement, and additional collaboration features.
|
||||
> 💡 **Good to know:** We offer a Business Associate Agreement (BAA) for any customer on our platform packages, which also includes priority support, SSO enforcement, and additional collaboration features.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -240,18 +550,48 @@ See [We've decided to make less money [Part 2]](/blog/analytics-pricing) for mor
|
||||
We don't need to. Every customer gets a generous free usage allowance each month, so you can sign up and start using PostHog for nothing. Here's how PostHog and Amplitude's free tiers compare:
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Amplitude">
|
||||
<ComparisonRow column1="1 million events" column2="50k tracked users" feature="Free analytics usage" description="Free tier usage each month" />
|
||||
<ComparisonRow column1="5,000 recordings" column2="1,000 recordings" feature="Free replay usage" description="Free tier usage each month" />
|
||||
<ComparisonRow column1="Unlimited" column2="10 only" feature="Saved insights" description="Number of you charts you can create" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom events" description="Create custom tracking events" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Cohorts" description="Combine users based on properties and events for group analysis" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Formulas" description="Create custom insights using formulas" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Feature flags" description="Release and control features" />
|
||||
<ComparisonRow column1={true} column2={false} feature="A/B testing" description="Run tests on users and groups" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Surveys" description="Gather feedback and book user interviews" />
|
||||
<ComparisonRow
|
||||
column1="1 million events"
|
||||
column2="50k tracked users"
|
||||
feature="Free analytics usage"
|
||||
description="Free tier usage each month"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="5,000 recordings"
|
||||
column2="1,000 recordings"
|
||||
feature="Free replay usage"
|
||||
description="Free tier usage each month"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Unlimited"
|
||||
column2="10 only"
|
||||
feature="Saved insights"
|
||||
description="Number of you charts you can create"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom events" description="Create custom tracking events" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Cohorts"
|
||||
description="Combine users based on properties and events for group analysis"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Formulas"
|
||||
description="Create custom insights using formulas"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="Feature flags" description="Release and control features" />
|
||||
<ComparisonRow column1={true} column2={false} feature="A/B testing" description="Run tests on users and groups" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Surveys"
|
||||
description="Gather feedback and book user interviews"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
Companies that qualify for [our startup program](/startups) also get $50,000 in PostHog credit and a range of additional benefits.
|
||||
Companies that qualify for [our startup program](/startups) also get $50,000 in PostHog credit and a range of additional benefits.
|
||||
|
||||
### Can PostHog replace Google Analytics?
|
||||
|
||||
@@ -275,4 +615,4 @@ Yes. See [Using PostHog with a CDP](/docs/advanced/cdp) in our docs.
|
||||
|
||||
### How does PostHog compare to other Amplitude alternatives?
|
||||
|
||||
Still need some convincing? See our guide to the [most popular Amplitude alternatives](/blog/best-amplitude-alternatives).
|
||||
Still need some convincing? See our guide to the [most popular Amplitude alternatives](/blog/best-amplitude-alternatives).
|
||||
|
||||
@@ -6,13 +6,13 @@ sidebar: Blog
|
||||
showTitle: true
|
||||
hideAnchor: true
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/posthog-vs-heap/posthog-vs-heap.jpeg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/posthog-vs-heap/posthog-vs-heap.jpeg
|
||||
featuredImageType: full
|
||||
author:
|
||||
- andy-vandervell
|
||||
- andy-vandervell
|
||||
category: General
|
||||
tags:
|
||||
- Comparisons
|
||||
- Comparisons
|
||||
---
|
||||
|
||||
import { ComparisonTable } from 'components/ComparisonTable'
|
||||
@@ -24,11 +24,11 @@ import { ComparisonRow } from 'components/ComparisonTable/row'
|
||||
|
||||
What does this mean?
|
||||
|
||||
- It means [we ship fast](/changelog) and iterate based on user feedback.
|
||||
- It means engineers do support – all product teams have a [weekly support hero](/handbook/engineering/support-hero).
|
||||
- It means we have extensive [public and private API endpoints](/docs/api), and a powerful [SQL query builder](/docs/product-analytics/sql).
|
||||
- It means we built [SDKs](/docs/libraries) for all popular (and many unpopular) client-side, backend, and mobile languages and frameworks.
|
||||
- It means we make it easy to [test in production](/product-engineers/testing-in-production), conduct [phased rollouts](/tutorials/phased-rollout), run [beta programs](/tutorials/public-beta-program), and so much more.
|
||||
- It means [we ship fast](/changelog) and iterate based on user feedback.
|
||||
- It means engineers do support – all product teams have a [weekly support hero](/handbook/engineering/support-hero).
|
||||
- It means we have extensive [public and private API endpoints](/docs/api), and a powerful [SQL query builder](/docs/product-analytics/sql).
|
||||
- It means we built [SDKs](/docs/libraries) for all popular (and many unpopular) client-side, backend, and mobile languages and frameworks.
|
||||
- It means we make it easy to [test in production](/product-engineers/testing-in-production), conduct [phased rollouts](/tutorials/phased-rollout), run [beta programs](/tutorials/public-beta-program), and so much more.
|
||||
|
||||
### 2. We're an all-in-one platform
|
||||
|
||||
@@ -36,11 +36,11 @@ Heap is mainly focused on product analytics. This means you need to adopt additi
|
||||
|
||||
### 3. We're totally transparent
|
||||
|
||||
- How much will PostHog cost? Use our [pricing calculator](/pricing).
|
||||
- What are we working on? It's on our [public roadmap](/roadmap)?
|
||||
- How does sales work? We have a [whole page on it](/sales).
|
||||
- What do we care about? We explain everything in our [public company handbook](/handbook).
|
||||
- How do we make money? That's [in the handbook](/handbook/how-we-make-money), too.
|
||||
- How much will PostHog cost? Use our [pricing calculator](/pricing).
|
||||
- What are we working on? It's on our [public roadmap](/roadmap)?
|
||||
- How does sales work? We have a [whole page on it](/sales).
|
||||
- What do we care about? We explain everything in our [public company handbook](/handbook).
|
||||
- How do we make money? That's [in the handbook](/handbook/how-we-make-money), too.
|
||||
|
||||
Oh, we're open source, too. Go take a peak at our code if you like on [our GitHub repo](https://github.com/PostHog).
|
||||
|
||||
@@ -49,37 +49,157 @@ Oh, we're open source, too. Go take a peak at our code if you like on [our GitHu
|
||||
### Platform
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1={true} column2={true} feature="Product analytics" description="Track events and conversion, analyze user behavior" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web analytics" description="Easy to use analytics for marketing websites" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Session replay" description="Watch real users use your product, diagnose bugs" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Feature flags" description="Roll out features safely, toggle features for cohorts or individuals" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Experiments" description="Run tests on new features, optimize conversion funnels" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Surveys" description="Collect and analyze feedback, run NPS and PMF surveys " />
|
||||
<ComparisonRow column1="Beta" column2={false} feature="Customer data platform" description="Sync data with third-party tools" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Data warehouse" description="A single source for all your important data" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Heatmaps" description="Visualize where users click in your app or website" />
|
||||
<ComparisonRow column1="Beta" column2={false} feature="Error tracking" description="Track and monitor errors and exceptions in your code" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Open source" description="Build your own apps and contribute code" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Product analytics"
|
||||
description="Track events and conversion, analyze user behavior"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web analytics"
|
||||
description="Easy to use analytics for marketing websites"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Session replay"
|
||||
description="Watch real users use your product, diagnose bugs"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Feature flags"
|
||||
description="Roll out features safely, toggle features for cohorts or individuals"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Experiments"
|
||||
description="Run tests on new features, optimize conversion funnels"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Surveys"
|
||||
description="Collect and analyze feedback, run NPS and PMF surveys "
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Beta"
|
||||
column2={false}
|
||||
feature="Customer data platform"
|
||||
description="Sync data with third-party tools"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Data warehouse"
|
||||
description="A single source for all your important data"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Heatmaps"
|
||||
description="Visualize where users click in your app or website"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Beta"
|
||||
column2={false}
|
||||
feature="Error tracking"
|
||||
description="Track and monitor errors and exceptions in your code"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Open source"
|
||||
description="Build your own apps and contribute code"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** PostHog can replace multiple tools, such as [Hotjar](/blog/posthog-vs-hotjar), [Google Analytics](/blog/posthog-vs-ga4), and [LaunchDarkly](/blog/posthog-vs-launchdarkly). This makes it a lot easier to extract usable insights, since you don't have to constantly switch between tools. Running PostHog on both your product and website makes it easier to understand how marketing activity influences signups and usage, too.
|
||||
> 💡 **Good to know:** PostHog can replace multiple tools, such as [Hotjar](/blog/posthog-vs-hotjar), [Google Analytics](/blog/posthog-vs-ga4), and [LaunchDarkly](/blog/posthog-vs-launchdarkly). This makes it a lot easier to extract usable insights, since you don't have to constantly switch between tools. Running PostHog on both your product and website makes it easier to understand how marketing activity influences signups and usage, too.
|
||||
|
||||
### Product analytics
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1="1 million events" column2="10k monthly tracked users" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Autocapture" description="Capture events without manual logging" />
|
||||
<ComparisonRow column1={true} column2={false} feature="SQL query editor" description="Write your own queries in SQL" />
|
||||
<ComparisonRow column1={false} column2={true} feature="AI insight builder" description="'Talk to your data' using AI" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Group analytics" description="Track metrics at a company and account level" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Dashboards" description="Combine insights into shareable dashboards" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Graphs and trends" description="Build custom insights and visualizations" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Funnels" description="Track users through a sequence of events" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Retention" description="Visualize which users stay, for how long" />
|
||||
<ComparisonRow column1={true} column2={true} feature="User paths" description="Track user flows and where they drop-off" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Cohorts" description="Combine users based on properties and events for group analysis" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Lifecycle analysis" description="Understand who is dormant, churning, and thriving" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Stickiness" description="Find out what events keep users coming back." />
|
||||
<ComparisonRow
|
||||
column1="1 million events"
|
||||
column2="10k monthly tracked users"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Autocapture"
|
||||
description="Capture events without manual logging"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="SQL query editor"
|
||||
description="Write your own queries in SQL"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={false}
|
||||
column2={true}
|
||||
feature="AI insight builder"
|
||||
description="'Talk to your data' using AI"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Group analytics"
|
||||
description="Track metrics at a company and account level"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Dashboards"
|
||||
description="Combine insights into shareable dashboards"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Graphs and trends"
|
||||
description="Build custom insights and visualizations"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Funnels"
|
||||
description="Track users through a sequence of events"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Retention"
|
||||
description="Visualize which users stay, for how long"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User paths"
|
||||
description="Track user flows and where they drop-off"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Cohorts"
|
||||
description="Combine users based on properties and events for group analysis"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Lifecycle analysis"
|
||||
description="Understand who is dormant, churning, and thriving"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Stickiness"
|
||||
description="Find out what events keep users coming back."
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know** Every PostHog user gets [1 million events for free](/pricing) each month. You can also save money by sending us anonymous events for non-identified users, which are up to 80% cheaper than identified product analytics events. Anonymous events are ideal for tracking behavior on marketing websites, or mobile apps with large consumer audiences. See our docs on [anonymous vs identified events](/docs/data/anonymous-vs-identified-events) for more.
|
||||
@@ -87,20 +207,90 @@ Oh, we're open source, too. Go take a peak at our code if you like on [our GitHu
|
||||
### Session replays
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1="5,000 web recordings, 2,500 mobile recordings" column2="Limited trial" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web app recordings" description="Capture recordings from single-page apps" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Mobile app recordings" description="Capture recordings in iOS and Android apps" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Identity detection" description="Link recordings to user IDs" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Console logs" description="Capture extra content from a user's browser" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Playlists" description="Sort recordings into static and dynamic playlists" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Performance monitoring" description="Track network events within a session" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Privacy masking" description="Censor personal information from playback" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Conditional capture" description="Only capture the sessions you want" />
|
||||
<ComparisonRow column1={true} column2={false} feature="DOM explorer" description="Explore an interactive snapshot of replays" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Export recordings" description="Save important recordings offline" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Minimum duration" description="Only record sessions longer than the minimum duration" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Sample recorded sessions" description="Restrict the percentage of sessions that will be recorded" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Record via feature flag" description="Only record sessions for users that have the flag enabled" />
|
||||
<ComparisonRow
|
||||
column1="5,000 web recordings, 2,500 mobile recordings"
|
||||
column2="Limited trial"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web app recordings"
|
||||
description="Capture recordings from single-page apps"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Mobile app recordings"
|
||||
description="Capture recordings in iOS and Android apps"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Identity detection"
|
||||
description="Link recordings to user IDs"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Console logs"
|
||||
description="Capture extra content from a user's browser"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Playlists"
|
||||
description="Sort recordings into static and dynamic playlists"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Performance monitoring"
|
||||
description="Track network events within a session"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Privacy masking"
|
||||
description="Censor personal information from playback"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Conditional capture"
|
||||
description="Only capture the sessions you want"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="DOM explorer"
|
||||
description="Explore an interactive snapshot of replays"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Export recordings"
|
||||
description="Save important recordings offline"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Minimum duration"
|
||||
description="Only record sessions longer than the minimum duration"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Sample recorded sessions"
|
||||
description="Restrict the percentage of sessions that will be recorded"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Record via feature flag"
|
||||
description="Only record sessions for users that have the flag enabled"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** Session replays are an essential tool for understanding how people use your product, especially for [early-stage companies](/blog/early-stage-analytics) searching for [product-market fit](/founders/product-market-fit-game). Both Heap and PostHog offer session replay, though Heap lacks many developer-facing features like a DOM explorer, performance monitoring, and network events, which are useful for fixing bugs and performance issues.
|
||||
@@ -108,17 +298,62 @@ Oh, we're open source, too. Go take a peak at our code if you like on [our GitHu
|
||||
### Feature flags
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1="1 million API requests" column2="n/a" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Boolean flags" description="Simple flags returning true or flag" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Multivariate flags" description="Flags with multiple customizable values" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Payloads" description="Flags with string, number, or JSON payloads" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Local evaluation" description="Store flag definitions locally" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Percentage rollouts" description="Target percentages of a group" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom targeting" description="Target users based on user properties, custom contexts" />
|
||||
<ComparisonRow column1="Partial" column2={false} feature="Environments" description="Manage flags for dev, staging, prod" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Bootstrapping" description="Flags available on frontend application load" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
<ComparisonRow
|
||||
column1="1 million API requests"
|
||||
column2="n/a"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Boolean flags"
|
||||
description="Simple flags returning true or flag"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Multivariate flags"
|
||||
description="Flags with multiple customizable values"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Payloads"
|
||||
description="Flags with string, number, or JSON payloads"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Local evaluation"
|
||||
description="Store flag definitions locally"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Percentage rollouts"
|
||||
description="Target percentages of a group"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Custom targeting"
|
||||
description="Target users based on user properties, custom contexts"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Partial"
|
||||
column2={false}
|
||||
feature="Environments"
|
||||
description="Manage flags for dev, staging, prod"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Bootstrapping"
|
||||
description="Flags available on frontend application load"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** Feature flags make it easy to roll out features to specific users or groups, and [safely test in production](/product-engineers/testing-in-production). Our feature flags are also tightly integrated with other features so you can target session replays, surveys, and more using existing feature flags. See our guide on the [benefits of feature flags](/product-engineers/feature-flag-benefits-use-cases) for more.
|
||||
@@ -126,15 +361,60 @@ Oh, we're open source, too. Go take a peak at our code if you like on [our GitHu
|
||||
### Experiments
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1="1 million API requests" column2="n/a" feature="Free usage" description="How much free usage do you get each month?" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom goals" description="Customize metrics that a test tracks" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Secondary metrics" description="Monitor impact on unrelated metrics" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Split testing" description="Split participants into groups" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Multivariate (A/B/n) testing" description="Test multiple variants of a change" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Statistical significance" description="Automatically checks for statistical significance" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Recommended run time" description="Calculates the recommended run time and sample size" />
|
||||
<ComparisonRow column1="Partial" column2="n/a" feature="Holdout testing" description="Withhold multiple features to measure cumulative impact" />
|
||||
<ComparisonRow column1="Bayesian" column2="n/a" feature="Statistics engine" description="How the results of an experiment are calculated" />
|
||||
<ComparisonRow
|
||||
column1="1 million API requests"
|
||||
column2="n/a"
|
||||
feature="Free usage"
|
||||
description="How much free usage do you get each month?"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Custom goals"
|
||||
description="Customize metrics that a test tracks"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Secondary metrics"
|
||||
description="Monitor impact on unrelated metrics"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Split testing"
|
||||
description="Split participants into groups"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Multivariate (A/B/n) testing"
|
||||
description="Test multiple variants of a change"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Statistical significance"
|
||||
description="Automatically checks for statistical significance"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Recommended run time"
|
||||
description="Calculates the recommended run time and sample size"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Partial"
|
||||
column2="n/a"
|
||||
feature="Holdout testing"
|
||||
description="Withhold multiple features to measure cumulative impact"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Bayesian"
|
||||
column2="n/a"
|
||||
feature="Statistics engine"
|
||||
description="How the results of an experiment are calculated"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡 **Good to know:** Our experiments integrate seamlessly with our feature flag product. This means you can easily deploy the winning variant of an experiment with a single click from the experiment UI.
|
||||
@@ -142,16 +422,36 @@ Oh, we're open source, too. Go take a peak at our code if you like on [our GitHu
|
||||
### Security and compliance
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Heap">
|
||||
<ComparisonRow column1={true} column2={true} feature="User privacy options" description="Anonymize users, drop personal data" />
|
||||
<ComparisonRow column1={true} column2={true} feature="History, audit logs" description="Manage and view flag edits and related users" />
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2" description="SOC 2 security certification" />
|
||||
<ComparisonRow column1={true} column2={true} feature="2FA" description="Enforce login with two-factor authentication" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SAML/SSO" description="Use SAML or single sign-on authentication" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User privacy options"
|
||||
description="Anonymize users, drop personal data"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="History, audit logs"
|
||||
description="Manage and view flag edits and related users"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2" description="SOC 2 security certification" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="2FA"
|
||||
description="Enforce login with two-factor authentication"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="SAML/SSO"
|
||||
description="Use SAML or single sign-on authentication"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> 💡**Good to know:** Additional compliance features, such as HIPAA Business Associate Agreements, advanced permissions, and audit logs are available on our some of our [platform add-ons](/platform-addons), which also includes our [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy) and white labelling for surveys and shared dashboards.
|
||||
> 💡**Good to know:** Additional compliance features, such as HIPAA Business Associate Agreements, advanced permissions, and audit logs are available on our some of our [platform packages](/platform-packages), which also includes our [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy) and white labelling for surveys and shared dashboards.
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
@@ -177,7 +477,7 @@ Yes. See the [full blocklist in our docs](/docs/product-analytics/troubleshootin
|
||||
|
||||
### What about ad blockers?
|
||||
|
||||
We recommend all users deploy a reverse proxy, which enables you send events to PostHog Cloud using your own domain. Events sent from your own domain and are less likely to be intercepted by tracking blockers, ensuring you capture the best data possible.
|
||||
We recommend all users deploy a reverse proxy, which enables you send events to PostHog Cloud using your own domain. Events sent from your own domain and are less likely to be intercepted by tracking blockers, ensuring you capture the best data possible.
|
||||
|
||||
We offer a managed reverse proxy on our Team plans, and we have [reverse proxy setup guides](/docs/advanced/proxy) for AWS Cloudfront, Caddy, Cloudflare, Netlify, Vercel, and more, in our docs if you want to run your own.
|
||||
|
||||
@@ -187,8 +487,8 @@ Yes. See [Using PostHog with a CDP](/docs/advanced/cdp) in our docs.
|
||||
|
||||
### Can you use PostHog on e-commerce websites?
|
||||
|
||||
Absolutely. PostHog is easy to integrate with [Shopify](/docs/libraries/shopify) and [WooCommerce](/docs/libraries/woocommerce). You can easily install PostHog on other e-commerce platforms [using our Javascript snippet](/docs/integrate) – see our guides to [setting up Webflow analytics](/tutorials/webflow) and [Wordpress](/docs/libraries/wordpress).
|
||||
Absolutely. PostHog is easy to integrate with [Shopify](/docs/libraries/shopify) and [WooCommerce](/docs/libraries/woocommerce). You can easily install PostHog on other e-commerce platforms [using our Javascript snippet](/docs/integrate) – see our guides to [setting up Webflow analytics](/tutorials/webflow) and [Wordpress](/docs/libraries/wordpress).
|
||||
|
||||
### How does PostHog compare to Amplitude and Mixpanel?
|
||||
|
||||
Amplitude and Mixpanel offer similar features to Heap. Read our [PostHog vs Mixpanel](/blog/posthog-vs-mixpanel) and [PostHog vs Amplitude](/blog/posthog-vs-amplitude) guides for more info. You may also find guide to the [most popular Heap alternatives](/blog/best-heap-alternatives) useful.
|
||||
Amplitude and Mixpanel offer similar features to Heap. Read our [PostHog vs Mixpanel](/blog/posthog-vs-mixpanel) and [PostHog vs Amplitude](/blog/posthog-vs-amplitude) guides for more info. You may also find guide to the [most popular Heap alternatives](/blog/best-heap-alternatives) useful.
|
||||
|
||||
@@ -6,13 +6,13 @@ sidebar: Blog
|
||||
showTitle: true
|
||||
hideAnchor: true
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/posthog-vs-mixpanel/posthog-vs-mixpanel.jpeg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/posthog-vs-mixpanel/posthog-vs-mixpanel.jpeg
|
||||
featuredImageType: full
|
||||
author:
|
||||
- andy-vandervell
|
||||
- andy-vandervell
|
||||
category: General
|
||||
tags:
|
||||
- Comparisons
|
||||
- Comparisons
|
||||
---
|
||||
|
||||
import { ComparisonTable } from 'components/ComparisonTable'
|
||||
@@ -25,14 +25,14 @@ import { ComparisonRow } from 'components/ComparisonTable/row'
|
||||
|
||||
PostHog puts all your data in one place and combines it with every tool you need to build a successful product. This means:
|
||||
|
||||
- **Product analytics** for analyzing behavior, funnels, activation, and retention
|
||||
- **Web analytics** for tracking your marketing website and content
|
||||
- **Session replay** for observing how people use your product and diagnosing problems
|
||||
- **Feature flags** for testing in production and shipping new features
|
||||
- **Experiments** for verifying improvements to your product and website
|
||||
- **Error tracking** for monitoring exceptions and problems in your code
|
||||
- **Surveys** for capturing user feedback, tracking NPS, and booking interviews
|
||||
- **A built-in data warehouse** for analyzing your business and event data together
|
||||
- **Product analytics** for analyzing behavior, funnels, activation, and retention
|
||||
- **Web analytics** for tracking your marketing website and content
|
||||
- **Session replay** for observing how people use your product and diagnosing problems
|
||||
- **Feature flags** for testing in production and shipping new features
|
||||
- **Experiments** for verifying improvements to your product and website
|
||||
- **Error tracking** for monitoring exceptions and problems in your code
|
||||
- **Surveys** for capturing user feedback, tracking NPS, and booking interviews
|
||||
- **A built-in data warehouse** for analyzing your business and event data together
|
||||
|
||||
In other words, it's everything you need in one app with a single login and contract. A _genuine_ single source of truth for your product and customer data.
|
||||
|
||||
@@ -51,20 +51,90 @@ As an all-in-one-platform, PostHog isn't just [an alternative to Mixpanel](/blog
|
||||
### Platform
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={true} feature="Product analytics" description="Track events and conversion, analyze user behavior" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Web analytics" description="Easy to use analytics for marketing websites" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Session replay" description="Watch real users use your product, diagnose bugs" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Feature flags" description="Roll out features safely, toggle features for cohorts or individuals" />
|
||||
<ComparisonRow column1={true} column2="Analysis only" feature="Experiments" description="Run tests on new features, optimize conversion funnels" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Surveys" description="Collect and analyze feedback, run NPS and PMF surveys " />
|
||||
<ComparisonRow column1={true} column2={false} feature="Error tracking" description="Track and monitor errors and exceptions in your code" />
|
||||
<ComparisonRow column1={true} column2={false} feature="LLM observability" description="Gather usage and performance data for your AI and LLM product" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Data pipelines" description="Export and import data in warehouses" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Customer data platform" description="Sync customer data between third-party tools" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Data warehouse" description="Centralized data storage for business intelligence" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Group analytics" description="Track metrics at a company and account level" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Managed reverse proxy" description="Send events from your own domain, managed by us" />
|
||||
<ComparisonRow column1={true} column2="Libraries only" feature="Open source" description="Inspect and contribute code" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Product analytics"
|
||||
description="Track events and conversion, analyze user behavior"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Web analytics"
|
||||
description="Easy to use analytics for marketing websites"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Session replay"
|
||||
description="Watch real users use your product, diagnose bugs"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Feature flags"
|
||||
description="Roll out features safely, toggle features for cohorts or individuals"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2="Analysis only"
|
||||
feature="Experiments"
|
||||
description="Run tests on new features, optimize conversion funnels"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Surveys"
|
||||
description="Collect and analyze feedback, run NPS and PMF surveys "
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Error tracking"
|
||||
description="Track and monitor errors and exceptions in your code"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="LLM observability"
|
||||
description="Gather usage and performance data for your AI and LLM product"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Data pipelines"
|
||||
description="Export and import data in warehouses"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Customer data platform"
|
||||
description="Sync customer data between third-party tools"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Data warehouse"
|
||||
description="Centralized data storage for business intelligence"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Group analytics"
|
||||
description="Track metrics at a company and account level"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Managed reverse proxy"
|
||||
description="Send events from your own domain, managed by us"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2="Libraries only"
|
||||
feature="Open source"
|
||||
description="Inspect and contribute code"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** If we don't have something you want now, there's a good chance we're planning on building it already. Visit [our public roadmap](/roadmap) to see what we're considering, and vote for features and products you're interested in. [We ship fast](/changelog/)!
|
||||
@@ -76,23 +146,108 @@ As an all-in-one-platform, PostHog isn't just [an alternative to Mixpanel](/blog
|
||||
PostHog and Mixpanel offer broadly similar product analytics features, including the ability to create insights using natural language.
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={true} feature="AI insight builder" description="Create insights and chat to your data using AI" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Alerts" description="Get notifications when insights fall outside set thresholds" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Autocapture" description="Capture frontend clicks and events automatically" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Cohorts" description="Combine users based on properties and events for group analysis" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Correlation analysis" description="Suggested events and properties that lead to success or failure" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Clickmaps" description="See what elements people click on in your app" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Dashboards" description="Combine insights into shareable dashboards" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Funnels" description="Track users through a sequence of events" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Formulas" description="Use formulas to calculate unique insights" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Graphs and trends" description="Build custom insights and visualizations" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Heatmaps" description="Visualize where users click in your app" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Lifecycle analysis" description="Understand who is dormant, churning, and thriving" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Retention" description="Visualize retention for users and groups" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Scrollmaps" description="Visualize how far users scroll in your app" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Stickiness insights" description="See how many times users perform an event in a period of time." />
|
||||
<ComparisonRow column1={true} column2={false} feature="SQL query editor" description="Write your own queries in SQL" />
|
||||
<ComparisonRow column1={true} column2={true} feature="User paths" description="Track user flows and where they drop-off" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="AI insight builder"
|
||||
description="Create insights and chat to your data using AI"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Alerts"
|
||||
description="Get notifications when insights fall outside set thresholds"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Autocapture"
|
||||
description="Capture frontend clicks and events automatically"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Cohorts"
|
||||
description="Combine users based on properties and events for group analysis"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Correlation analysis"
|
||||
description="Suggested events and properties that lead to success or failure"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Clickmaps"
|
||||
description="See what elements people click on in your app"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Dashboards"
|
||||
description="Combine insights into shareable dashboards"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Funnels"
|
||||
description="Track users through a sequence of events"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Formulas"
|
||||
description="Use formulas to calculate unique insights"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Graphs and trends"
|
||||
description="Build custom insights and visualizations"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Heatmaps"
|
||||
description="Visualize where users click in your app"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Lifecycle analysis"
|
||||
description="Understand who is dormant, churning, and thriving"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Retention"
|
||||
description="Visualize retention for users and groups"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Scrollmaps"
|
||||
description="Visualize how far users scroll in your app"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Stickiness insights"
|
||||
description="See how many times users perform an event in a period of time."
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="SQL query editor"
|
||||
description="Write your own queries in SQL"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User paths"
|
||||
description="Track user flows and where they drop-off"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** Our [generous free tier](/pricing) means every PostHog customer gets 1 million analytics events for free every single month. More than 90% of companies use PostHog for free, and our [startup program](/startups) comes with $50,000 in credit.
|
||||
@@ -120,7 +275,7 @@ PostHog is also a powerful [alternative to Google Analytics](/blog/ga4-alternati
|
||||
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** You can use the [PostHog toolbar](/docs/toolbar) to [view clickmaps, heatmaps, and scrollmaps](/docs/toolbar/heatmaps) for your website. You can also use the toolbar to turn feature flags on and off, debug events, and create no-code experiments.
|
||||
> **Good to know:** You can use the [PostHog toolbar](/docs/toolbar) to [view clickmaps, heatmaps, and scrollmaps](/docs/toolbar/heatmaps) for your website. You can also use the toolbar to turn feature flags on and off, debug events, and create no-code experiments.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -129,21 +284,91 @@ PostHog is also a powerful [alternative to Google Analytics](/blog/ga4-alternati
|
||||
PostHog's session replay can be used by anyone, but it includes numerous developer-level features that make it useful for engineers, product managers, and support engineers who want to diagnose issues, and identify potential improvements.
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={false} feature="Canvas recording" description="Capture canvas elements in your app" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Chat with your recordings" description="Discover useful recordings using AI-powered chat" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Console logs" description="Capture extra content from a user's browser" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Conditional recording" description="Only capture the sessions you want" />
|
||||
<ComparisonRow column1={true} column2={false} feature="DOM explorer" description="Explore an interactive snapshot of replays" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Export recordings" description="Save important recordings offline" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Event timeline" description="See events triggered during recordings" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Iframe recording" description="Record embedded iframes" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Identity detection" description="Link recordings to user IDs" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Minimum duration" description="Only record sessions longer than the minimum duration" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Performance monitoring" description="Track network events within a session" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Playlists" description="Sort recordings into static and dynamic playlists" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Privacy masking" description="Censor personal information from playback" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Record via feature flag" description="Only record sessions for users that have the flag enabled" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Sample recorded sessions" description="Limit the percentage of sessions recorded" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Canvas recording"
|
||||
description="Capture canvas elements in your app"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Chat with your recordings"
|
||||
description="Discover useful recordings using AI-powered chat"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Console logs"
|
||||
description="Capture extra content from a user's browser"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Conditional recording"
|
||||
description="Only capture the sessions you want"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="DOM explorer"
|
||||
description="Explore an interactive snapshot of replays"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Export recordings"
|
||||
description="Save important recordings offline"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Event timeline"
|
||||
description="See events triggered during recordings"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Iframe recording" description="Record embedded iframes" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Identity detection"
|
||||
description="Link recordings to user IDs"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Minimum duration"
|
||||
description="Only record sessions longer than the minimum duration"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Performance monitoring"
|
||||
description="Track network events within a session"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Playlists"
|
||||
description="Sort recordings into static and dynamic playlists"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Privacy masking"
|
||||
description="Censor personal information from playback"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Record via feature flag"
|
||||
description="Only record sessions for users that have the flag enabled"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Sample recorded sessions"
|
||||
description="Limit the percentage of sessions recorded"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
#### Library support for replays
|
||||
@@ -161,27 +386,77 @@ Mixpanel only recently introduced session replay, so its mobile SDKs are still i
|
||||
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** You can use Max AI in PostHog to chat with your recordings using natural language – e.g. "show me sessions over 5 minutes long" or "show me sessions from users in Belgium". You can also ask Max AI to summarize what happened during a session.
|
||||
> **Good to know:** You can use Max AI in PostHog to chat with your recordings using natural language – e.g. "show me sessions over 5 minutes long" or "show me sessions from users in Belgium". You can also ask Max AI to summarize what happened during a session.
|
||||
|
||||
<br />
|
||||
|
||||
### Feature flags
|
||||
|
||||
Feature flags make it easy to roll out features to specific users or groups, and [safely test in production](/product-engineers/testing-in-production). You can also use them [control access to beta features](/docs/feature-flags/early-access-feature-management), and make [scheduled changes to your app](/docs/feature-flags/scheduled-flag-changes).
|
||||
Feature flags make it easy to roll out features to specific users or groups, and [safely test in production](/product-engineers/testing-in-production). You can also use them [control access to beta features](/docs/feature-flags/early-access-feature-management), and make [scheduled changes to your app](/docs/feature-flags/scheduled-flag-changes).
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={false} feature="Boolean flags" description="Simple flags returning true or false" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Bootstrapping" description="Flags available on frontend application load" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Custom targeting" description="Target users based on user properties, custom contexts" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
<ComparisonRow column1="Partial" column2={false} feature="Environments" description="Manage flags for dev, staging, prod" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Flag history" description="Timeline of flag changes and who made them" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Local evaluation" description="Store flag definitions locally" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Multivariate flags" description="Flags with multiple customizable values" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Payloads" description="Flags with string, number, or JSON payloads" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Percentage rollouts" description="Target percentages of a group" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Remote config" description="Pass config without making code changes or redeploying your app" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Boolean flags"
|
||||
description="Simple flags returning true or false"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Bootstrapping"
|
||||
description="Flags available on frontend application load"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Custom targeting"
|
||||
description="Target users based on user properties, custom contexts"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Early access" description="Manage betas, test features" />
|
||||
<ComparisonRow
|
||||
column1="Partial"
|
||||
column2={false}
|
||||
feature="Environments"
|
||||
description="Manage flags for dev, staging, prod"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Flag history"
|
||||
description="Timeline of flag changes and who made them"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Local evaluation"
|
||||
description="Store flag definitions locally"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Multivariate flags"
|
||||
description="Flags with multiple customizable values"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Payloads"
|
||||
description="Flags with string, number, or JSON payloads"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Percentage rollouts"
|
||||
description="Target percentages of a group"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Remote config"
|
||||
description="Pass config without making code changes or redeploying your app"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Scheduling" description="Schedule flags to turn on or off" />
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** Our feature flags are tightly integrated with other tools, meaning you can target session replays, surveys and other features using existing feature flags. See [benefits of feature flags](/product-engineers/feature-flag-benefits-use-cases) for more.
|
||||
@@ -190,23 +465,83 @@ Feature flags make it easy to roll out features to specific users or groups, and
|
||||
|
||||
### Experiments
|
||||
|
||||
Experiments in PostHog are billed with feature flags.
|
||||
Experiments in PostHog are billed with feature flags.
|
||||
|
||||
You **can't run A/B tests using Mixpanel**, but you can analyze the results of experiments created using third-party testing tools.
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={false} feature="Built-in A/B testing" description="Setup and run A/B tests using feature flags" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Experiment analysis" description="Analyze results of A/B tests" />
|
||||
<ComparisonRow column1="Beta" column2={false} feature="No-code experiments" description="Modify your website and run experiments without writing code." />
|
||||
<ComparisonRow column1={true} column2={true} feature="Custom goals" description="Customize metrics that a test tracks" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Secondary metrics" description="Monitor impact on unrelated metrics" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Statistical significance" description="Automatically checks for statistical significance" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Split testing" description="Split participants into groups" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Multivariate (A/B/n) testing" description="Test multiple variants of a change" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Recommended run time" description="Automatically calculate the recommended run time and sample size" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Dynamic cohorts" description="Add new users to an experiment automatically by setting a user property" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Holdout testing" description="Withhold multiple features to measure cumulative impact" />
|
||||
<ComparisonRow column1="Bayesian" column2="Frequentist" feature="Statistics engine" description="How the results of an experiment are calculated" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Built-in A/B testing"
|
||||
description="Setup and run A/B tests using feature flags"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Experiment analysis"
|
||||
description="Analyze results of A/B tests"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Beta"
|
||||
column2={false}
|
||||
feature="No-code experiments"
|
||||
description="Modify your website and run experiments without writing code."
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Custom goals"
|
||||
description="Customize metrics that a test tracks"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Secondary metrics"
|
||||
description="Monitor impact on unrelated metrics"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Statistical significance"
|
||||
description="Automatically checks for statistical significance"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Split testing"
|
||||
description="Split participants into groups"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Multivariate (A/B/n) testing"
|
||||
description="Test multiple variants of a change"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Recommended run time"
|
||||
description="Automatically calculate the recommended run time and sample size"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Dynamic cohorts"
|
||||
description="Add new users to an experiment automatically by setting a user property"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Holdout testing"
|
||||
description="Withhold multiple features to measure cumulative impact"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Bayesian"
|
||||
column2="Frequentist"
|
||||
feature="Statistics engine"
|
||||
description="How the results of an experiment are calculated"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** You can evaluate the results of experiments using events tracked using PostHog, or [event tables stored in our data warehouse](/docs/experiments/data-warehouse). This means you can include all kinds of business event data as primary or secondary metrics in your experiments.
|
||||
@@ -238,7 +573,7 @@ You can't build a successful product on data alone. Surveys are useful for [gath
|
||||
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** Surveys are great for tracking customer satisfaction scores like Net Promoter Score (NPS), customer satisfaction (CSAT), and customer effort score (CES). We include survey templates for all these and more. Read our [guide comparing NPS, CSAT, and CES](/product-engineers/nps-vs-csat-vs-ces) to see which survey type you should use and when.
|
||||
> **Good to know:** Surveys are great for tracking customer satisfaction scores like Net Promoter Score (NPS), customer satisfaction (CSAT), and customer effort score (CES). We include survey templates for all these and more. Read our [guide comparing NPS, CSAT, and CES](/product-engineers/nps-vs-csat-vs-ces) to see which survey type you should use and when.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -246,43 +581,43 @@ You can't build a successful product on data alone. Surveys are useful for [gath
|
||||
|
||||
PostHog and Mixpanel both charge based on the number of events ingested, however:
|
||||
|
||||
- **Mixpanel** charges the same for events generated by identified and anonymous users.
|
||||
- **PostHog** charges up to 80% less for events generated by anonymous users.
|
||||
- **Mixpanel** charges the same for events generated by identified and anonymous users.
|
||||
- **PostHog** charges up to 80% less for events generated by anonymous users.
|
||||
|
||||
Anonymous events are the default event type in PostHog, so you only get charged for identified events when you call `identify` in your code – see our [anonymous vs identified events explainer](/docs/data/anonymous-vs-identified-events) for more on this.
|
||||
|
||||
As the below table shows, however, PostHog is cheaper than Mixpanel even if you're only tracking identified users.
|
||||
|
||||
| **Monthly events** | **PostHog (100% identified events)** | **Mixpanel** |
|
||||
|--------------------|--------------------------|-----------------------------------|
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$352</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$560</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$1,080</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$1,600</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$1,927</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
| **Monthly events** | **PostHog (100% identified events)** | **Mixpanel** |
|
||||
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----- |
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$352</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$560</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$1,080</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$1,600</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$1,927</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
|
||||
And it becomes even cheaper if 20% of your events are from anonymous users, which is typical for many of our customers.
|
||||
|
||||
| **Monthly events** | **PostHog (20% anonymous events)** | **Mixpanel** |
|
||||
|--------------------|--------------------------|-----------------------------------|
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$310</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$490</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$940</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$1,391</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$1,783</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
| **Monthly events** | **PostHog (20% anonymous events)** | **Mixpanel** |
|
||||
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----- |
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$310</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$490</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$940</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$1,391</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$1,783</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
|
||||
We recommend tracking your marketing website and product in a single project, and you can track all events on your website anonymously to save money.
|
||||
|
||||
| **Monthly events** | **PostHog (100% anonymous events)** | **Mixpanel** |
|
||||
|--------------------|--------------------------|-----------------------------------|
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$84</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$153</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$324</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$496</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$643</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
| **Monthly events** | **PostHog (100% anonymous events)** | **Mixpanel** |
|
||||
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ----- |
|
||||
| <strong class="text-15px">0-1 million</strong> | Free | Free |   |
|
||||
| <strong class="text-15px">3 million</strong> | <span class="text-[15px] font-semibold">$84</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$378</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">5 million</strong> | <span class="text-[15px] font-semibold">$153</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$612</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">10 million</strong> | <span class="text-[15px] font-semibold">$324</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,465</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">15 million</strong> | <span class="text-[15px] font-semibold">$496</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$1,722</span><span class="text-sm opacity-70">/month</span> |
|
||||
| <strong class="text-15px">20 million</strong> | <span class="text-[15px] font-semibold">$643</span><span class="text-sm opacity-70">/month</span> | <span class="text-[15px] font-semibold">$2,289</span><span class="text-sm opacity-70">/month</span> |
|
||||
|
||||
> **Good to know:** Web analytics makes it easy to track and monitor high-level website metrics, like page views, bounce rate, and the top sources of traffic, but you can still create custom product analytics insights and dashboards using anonymous events. See our [web vs product analytics explainer](/docs/web-analytics/web-vs-product-analytics) for more.
|
||||
|
||||
@@ -290,22 +625,37 @@ We recommend tracking your marketing website and product in a single project, an
|
||||
|
||||
### Data integrations
|
||||
|
||||
**PostHog** has a built-in data warehouse, so you can import and query data directly from our other sources like Stripe and Zendesk, or from an existing warehouse.
|
||||
**PostHog** has a built-in data warehouse, so you can import and query data directly from our other sources like Stripe and Zendesk, or from an existing warehouse.
|
||||
|
||||
**Mixpanel** relies on data warehouse connectors to combine customer and product data. This means you don't import data directly from third-party tools. You need to get them into a third-party warehouse and then import that data into Mixpanel for analysis.
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={false} feature="Data warehouse" description="Query customer and product data together" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Warehouse import" description="Import data from third-party warehouse" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Stripe" description="Stripe customer data connector" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Zendesk" description="Send and receive data from Zendesk" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Hubspot" description="Send and receive data from Hubspot" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Sentry" description="Send and receive data from Sentry" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Segment" description="Send events via Segment" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Rudderstack" description="Send events via Rudderstack" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Zapier" description="Trigger Zapier automations" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Customer.io" description="Messaging and marketing automation" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Intercom" description="Messaging and marketing automation" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={false}
|
||||
feature="Data warehouse"
|
||||
description="Query customer and product data together"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Warehouse import"
|
||||
description="Import data from third-party warehouse"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={false} feature="Stripe" description="Stripe customer data connector" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Zendesk" description="Send and receive data from Zendesk" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Hubspot" description="Send and receive data from Hubspot" />
|
||||
<ComparisonRow column1={true} column2={false} feature="Sentry" description="Send and receive data from Sentry" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Segment" description="Send events via Segment" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Rudderstack" description="Send events via Rudderstack" />
|
||||
<ComparisonRow column1={true} column2={true} feature="Zapier" description="Trigger Zapier automations" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="Customer.io"
|
||||
description="Messaging and marketing automation"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="Intercom" description="Messaging and marketing automation" />
|
||||
</ComparisonTable>
|
||||
|
||||
See our docs for full lists of [destinations](/docs/cdp) and [data warehouse sources](/docs/cdp/sources).
|
||||
@@ -313,16 +663,36 @@ See our docs for full lists of [destinations](/docs/cdp) and [data warehouse sou
|
||||
### Security and compliance
|
||||
|
||||
<ComparisonTable column1="PostHog" column2="Mixpanel">
|
||||
<ComparisonRow column1={true} column2={true} feature="User privacy options" description="Anonymize users, drop personal data" />
|
||||
<ComparisonRow column1={true} column2={true} feature="History, audit logs" description="Manage and view flag edits and related users" />
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2" description="SOC 2 security certification" />
|
||||
<ComparisonRow column1={true} column2={true} feature="2FA" description="Enforce login with two-factor authentication" />
|
||||
<ComparisonRow column1="Enterprise" column2="Enterprise" feature="SAML/SSO" description="Use SAML or single sign-on authentication" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="User privacy options"
|
||||
description="Anonymize users, drop personal data"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="History, audit logs"
|
||||
description="Manage and view flag edits and related users"
|
||||
/>
|
||||
<ComparisonRow column1={true} column2={true} feature="GDPR-ready" description="Can be compliant with GDPR" />
|
||||
<ComparisonRow column1={true} column2={true} feature="HIPAA-ready" description="Can be compliant with HIPAA" />
|
||||
<ComparisonRow column1={true} column2={true} feature="SOC 2" description="SOC 2 security certification" />
|
||||
<ComparisonRow
|
||||
column1={true}
|
||||
column2={true}
|
||||
feature="2FA"
|
||||
description="Enforce login with two-factor authentication"
|
||||
/>
|
||||
<ComparisonRow
|
||||
column1="Enterprise"
|
||||
column2="Enterprise"
|
||||
feature="SAML/SSO"
|
||||
description="Use SAML or single sign-on authentication"
|
||||
/>
|
||||
</ComparisonTable>
|
||||
|
||||
> **Good to know:** A Business Associate Agreement for HIPAA compliance is available for customers with our [platforms add-ons](/platform-addons). The add-on also includes our managed reverse proxy, priority support, SSO and 2FA enforcement, numerous collaboration features, and support multiple environments within projects so you can separate dev and production data, but use the same insights and dashboards across them all.
|
||||
> **Good to know:** A Business Associate Agreement for HIPAA compliance is available for customers with our [platforms add-ons](/platform-packages). The add-on also includes our managed reverse proxy, priority support, SSO and 2FA enforcement, numerous collaboration features, and support multiple environments within projects so you can separate dev and production data, but use the same insights and dashboards across them all.
|
||||
|
||||
<br />
|
||||
|
||||
@@ -338,7 +708,7 @@ Yes. See our [Mixpanel to PostHog migration guide](/docs/migrate/mixpanel).
|
||||
<details>
|
||||
<summary>Can PostHog replace Google Analytics?</summary>
|
||||
|
||||
Yes. PostHog can replace Google Analytics for many use cases – [our marketing team uses PostHog](/blog/posthog-marketing), for example. You can also integrate PostHog into your website using Google Tag Manager.
|
||||
Yes. PostHog can replace Google Analytics for many use cases – [our marketing team uses PostHog](/blog/posthog-marketing), for example. You can also integrate PostHog into your website using Google Tag Manager.
|
||||
|
||||
See our comparison of [PostHog and Google Analytics 4](/blog/posthog-vs-ga4) and [An intro to PostHog for Google Analytics users](/blog/google-analytics-to-posthog) for more.
|
||||
|
||||
@@ -349,14 +719,14 @@ See our comparison of [PostHog and Google Analytics 4](/blog/posthog-vs-ga4) and
|
||||
|
||||
Every PostHog user gets a generous amount of free usage each month:
|
||||
|
||||
| | **Free usage per month**
|
||||
|-----------------------|--------------------------
|
||||
| **Product analytics** | 1 million events
|
||||
| **Data warehouse** | 1 million synced rows
|
||||
| **Session replay** | 5,000 recordings
|
||||
| **Feature flags** | 1 million API requests
|
||||
| **A/B testing** | 1 million API requests
|
||||
| **Surveys** | 1500 responses
|
||||
| | **Free usage per month** |
|
||||
| --------------------- | ------------------------ |
|
||||
| **Product analytics** | 1 million events |
|
||||
| **Data warehouse** | 1 million synced rows |
|
||||
| **Session replay** | 5,000 recordings |
|
||||
| **Feature flags** | 1 million API requests |
|
||||
| **A/B testing** | 1 million API requests |
|
||||
| **Surveys** | 1500 responses |
|
||||
|
||||
You'll never pay anything if you stay within these limits and you can set billing limits to avoid surprise bills.
|
||||
|
||||
@@ -374,7 +744,7 @@ Yes. See [Using PostHog with a CDP](/docs/advanced/cdp) in our docs.
|
||||
<details>
|
||||
<summary>What about ad blockers?</summary>
|
||||
|
||||
We recommend all users deploy a reverse proxy, which enables you to send events to PostHog Cloud using your own domain. Events sent from your own domain and are less likely to be intercepted by tracking blockers, ensuring you capture the best data possible.
|
||||
We recommend all users deploy a reverse proxy, which enables you to send events to PostHog Cloud using your own domain. Events sent from your own domain and are less likely to be intercepted by tracking blockers, ensuring you capture the best data possible.
|
||||
|
||||
We make this super easy by offering a [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy) – a no code solution that takes minutes to setup. We also have [reverse proxy setup guides](/docs/advanced/proxy) for AWS Cloudfront, Caddy, Cloudflare, Netlify, Vercel, and more in our docs.
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ You may have spotted some handy filtering and search capabilities. It's not rock
|
||||
- `type:` like `type:insight`
|
||||
- `name:` like `name:marketing`
|
||||
|
||||
It even supports negative keywords so you can exclude items that contain a string, like <code class="text-inherit p-1 rounded bg-accent dark:bg-accent-dark border border-light dark:border-dark !text-[13px] whitespace-nowrap">-this</code>. You can also multi-select items for bulk actions.
|
||||
It even supports negative keywords so you can exclude items that contain a string, like <code class="text-inherit p-1 rounded bg-accent border border-primary !text-[13px] whitespace-nowrap">-this</code>. You can also multi-select items for bulk actions.
|
||||
|
||||
<ProductScreenshot
|
||||
imageLight={Filtering}
|
||||
|
||||
67
contents/blog/why-os.mdx
Normal file
67
contents/blog/why-os.mdx
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: 'Why our website looks like an operating system'
|
||||
date: 2025-09-10
|
||||
author:
|
||||
- cory-watilo
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/default_2d8c0bdf90.png
|
||||
featuredImageType: full
|
||||
tags:
|
||||
- PostHog news
|
||||
---
|
||||
|
||||
I have a problem with many large, technical websites.
|
||||
|
||||
Often times, I’ll want to refer to different pages at the same time. So I’ll `CMD` + click “a couple times” while browsing around and before I know it, I have 12 new tabs open – all indistinguishable from each other because they share the same favicon.
|
||||
|
||||
PostHog.com has the same problem – especially as the site has grown from supporting a handful of paid products to over a dozen.
|
||||
|
||||
As I looked for ways to solve this explosion of pages, I started to question many of the typical patterns that marketing & docs websites have today.
|
||||
|
||||
Long-form scrolling. Oversized footers. Absurd whitespace.
|
||||
|
||||
These website _encourage_ scrolling, but just to get people to the bottom of the page? And then what?
|
||||
|
||||
Why are we doing this? What if we just made better ways to consume content?
|
||||
|
||||
That’s the idea behind the new PostHog.com. You can multitask, open a few articles simultaneously, and move them around as you please. If anything there's a whitespace deficiency, and your fingers will be jealous you're not scrolling with them as much (because you're so engaged with our content).
|
||||
|
||||
It has window snapping, keyboard shortcuts, and a bookmark app. It works as well as you’d expect an operating system to work in a browser.
|
||||
|
||||
You can be reading the latest newsletter from Product for Engineers while watching a demo video in the corner and also playing Hedgehog Mode, the game.
|
||||
|
||||
I’ll be the first to admit it – an OS interface for a “website” is initially a jarring experience. I felt this as I built it. The human brain expects certain patterns within the confines of a browser viewport, and when it doesn’t get that assurance, it revolts.
|
||||
|
||||
But the more I used the new site, the more I started to like it. And the experience was the same for colleagues. And now I can’t imagine using anything else.
|
||||
|
||||
I had a lot of fun in building it with <TeamMember name="Eli Kinsey" />. Throughout the site you’ll find:
|
||||
|
||||
- A [Windows File Explorer](/products) clone that also acts as the UI for [our merch store](/merch)
|
||||
- [Product pages](/llm-analytics) that resemble PowerPoint presentations
|
||||
- A [document editor](/customers) where you can actually edit content
|
||||
- [Forums](/questions) designed to look like you’re reading newsgroups in Outlook Express
|
||||
- A [QuickTime clone](/demo)
|
||||
- A lot of pages you’d expect to be well-designed that are… just [formatted as spreadsheets](/changelog)
|
||||
- A screensaver and a [library of desktop backgrounds](/display-options)
|
||||
- A plethora of [keyboard shortcuts](/kbd)
|
||||
|
||||
It was also an interesting learning curve for me in figuring out how to organize five years worth of content while making it scalable for the future. Some of the technical highlights:
|
||||
|
||||
- Separation of visual layer from content
|
||||
- All product pages are now powered from JSON files (<a to="https://github.com/PostHog/posthog.com/blob/windows-n-such/src/hooks/productData/session_replay.tsx" external>example</a>). This means that JSON dictates page layouts, content presentation, feature-level competitor comparison charts, and more. It also contains an array of screenshots used in various places (both in light and dark mode, of course).
|
||||
- Eventually this will move to a repository that’s shared with the PostHog app, so all the information is powered from the same source.
|
||||
- Skinning a site with themes _and_ color schemes
|
||||
- How do you maintain light and dark mode, along with themes across a handful of accent variations (primary, secondary, tertiary) in a way that all play well together? (I found this out, and I’ll write about it sometime!)
|
||||
- A reference customer database
|
||||
- I’ve created a single customer record <a to="https://github.com/PostHog/posthog.com/blob/61ad1a9ea079d6e0422a95ab453acbddf4cdd5a4/src/hooks/useCustomers.tsx#L364" external>in code</a> that contains: a) which products they use, b) quotes from specific people about individual products c) SVG logos that work in light and dark mode
|
||||
- This means that any quote can be presented on any page for any product without having to be hard-coded. It pulls in their name and photo, quote, and company logo, and can be filtered in reference to a specific product.
|
||||
|
||||
For a lot of this site, I was designing it _while_ I was building UIs in Typescript and Tailwind. (The entire site is just a Git branch off our current site – it's all technically the same codebase. I just merged along the way over the last few months.)
|
||||
|
||||
Prototyping in a production-level environment was a great way to ideate and develop features along the way – stuff I never would have built if I were just going off of mockups. I did find myself [popping open Balsamiq <a to="https://x.com/ninepixelgrid/status/1936994050625679692" external>while I was building</a> – but just long enough to flesh out some ideas.
|
||||
|
||||
So how will this pan out? Well, we’re about to find out. This feels like an early MVP – there’s a ton of stuff to improve upon from here.
|
||||
|
||||
But in the meantime, I hope you enjoy the new PostHog.com. Be curious, click around, and have some fun. I hope you enjoy your time here as much as we enjoyed building it.
|
||||
|
||||
If you're curious, [read more about how the site technically works](/handbook/engineering/posthog-com/how-posthog-website-works).
|
||||
@@ -39,19 +39,19 @@ import CloudinaryImage from 'components/CloudinaryImage'
|
||||
<h3 className="text-2xl lg:text-4xl m-0 md:text-center mb-6">Here's how we support organizers</h3>
|
||||
<div className="flex justify-center">
|
||||
<ul className="m-0 p-0 list-none inline-grid sm:grid-cols-2 lg:grid-cols-3 gap-[10px] justify-evenly relative md:text-center sm:text-left">
|
||||
<li className="bg-accent dark:bg-accent-dark relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<li className="bg-accent relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 className="text-xl font-extrabold !m-0 pb-1 pr-4 text-black dark:text-white">$800 cash grant</h5>
|
||||
<p className="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
This will get you going and is to be used at the organizer's discretion. You can use it for food, coffees, or an activity. We'll also send merch.
|
||||
</p>
|
||||
</li>
|
||||
<li className="bg-accent dark:bg-accent-dark relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<li className="bg-accent relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 className="text-xl font-extrabold !m-0 pb-1 pr-4 text-black dark:text-white">Help attracting attendees</h5>
|
||||
<p className="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
The people you gather are the sparks of your community. We'll help you find the builders we'd be glad to work alongside on any day.
|
||||
</p>
|
||||
</li>
|
||||
<li className="bg-accent dark:bg-accent-dark relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<li className="bg-accent relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 className="text-xl font-extrabold !m-0 pb-1 pr-4 text-black dark:text-white">Help finding a venue</h5>
|
||||
<p className="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
We've been remote working in coffee shops and co-working spaces for four years. We can help you find a space for your group.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
title: Why AssemblyAI switched from Mixpanel to PostHog
|
||||
customer: AssemblyAI
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/assemblyai/logo.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/assemblyai_light_d0e0d6627e.svg
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/assemblyai/logo_dark.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/assemblyai_dark_9961eafc2c.svg
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog_assembly_AI_ef178ab0da.png
|
||||
industries:
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
title: How ElevenLabs uses every tool PostHog has to launch new features
|
||||
customer: ElevenLabs
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711377704/posthog.com/contents/images/customers/elevenlabs/ElevenLabs_logo.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/elevenlabs_light_d0ac4d4c6d.svg
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711377739/posthog.com/contents/images/customers/elevenlabs/ElevenLabs_logo-dark.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/elevenlabs_dark_0cf1dca507.svg
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/eleven_labs_b5853d00b7.png
|
||||
industries:
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
title: How Hasura improved conversion rates by 10-20% with PostHog
|
||||
customer: Hasura
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/hasura/logo.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/hasura_light_eb1a4a4bba.svg
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/hasura/logo_dark.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/hasura_dark_661038a2fd.svg
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/hasura_posthog_efc51e8a25.png
|
||||
industries:
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
---
|
||||
title: How Headshot Pro analyzes Google Adwords data in PostHog
|
||||
customer: Headshot Pro
|
||||
title: How HeadshotPro analyzes Google Adwords data in PostHog
|
||||
customer: HeadshotPro
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_light_22c5a2ce27.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_light_22c5a2ce27.png
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_dark_b36935a453.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_dark_b36935a453.png
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_pro_posthog_56e4ed68be.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/headshot_pro_posthog_56e4ed68be.png
|
||||
industries:
|
||||
- AI
|
||||
- AI
|
||||
users:
|
||||
- Growth
|
||||
- Engineering
|
||||
- Product
|
||||
- Growth
|
||||
- Engineering
|
||||
- Product
|
||||
toolsUsed:
|
||||
- Data warehouse
|
||||
- Product analytics
|
||||
- Data warehouse
|
||||
- Product analytics
|
||||
date: 2024-06-02
|
||||
---
|
||||
|
||||
Founded by serial AI entrepreneur Danny Postma, [Headshot Pro](https://www.headshotpro.com/) has rapidly grown to become one of the most popular AI photo generation tools. Despite only launching earlier this year, the platform has already gathered over 80,000 users and generated more than 13 million images.
|
||||
Founded by serial AI entrepreneur Danny Postma, [HeadshotPro](https://www.headshotpro.com/) has rapidly grown to become one of the most popular AI photo generation tools. Despite only launching earlier this year, the platform has already gathered over 80,000 users and generated more than 13 million images.
|
||||
|
||||
“I used to have a whole bunch of side projects,” says Danny, “But Headshot Pro was so successful it’s become my main focus. I’ve started to build a team around it and that’s where our need for product analytics came from — I needed one source of truth for both marketing and developers to share.”
|
||||
“I used to have a whole bunch of side projects,” says Danny, “But HeadshotPro was so successful it’s become my main focus. I’ve started to build a team around it and that’s where our need for product analytics came from — I needed one source of truth for both marketing and developers to share.”
|
||||
|
||||
After asking for recommendations from other founders, Danny narrowed his list to just two contenders — [Mixpanel and PostHog](/blog/posthog-vs-mixpanel). Both platforms enabled in-depth analytics, but with PostHog this was only the start of what was possible.
|
||||
After asking for recommendations from other founders, Danny narrowed his list to just two contenders — [Mixpanel and PostHog](/blog/posthog-vs-mixpanel). Both platforms enabled in-depth analytics, but with PostHog this was only the start of what was possible.
|
||||
|
||||
“We looked at Mixpanel but it was always too expensive,” says Danny. “Plus, I wanted an analytics tool where I could look at different types of data. If I get concerned about something I want to dig into it — and that’s why I joined the data warehouse beta when it first launched.”
|
||||
|
||||
@@ -31,7 +31,7 @@ After asking for recommendations from other founders, Danny narrowed his list to
|
||||
|
||||
During the beta [our Data Warehouse team](/teams/data-warehouse) were naturally curious for feedback, so it wasn’t long before they reached out to speak with Danny about what he needed.
|
||||
|
||||
“Headshot Pro wasn’t using a data warehouse before PostHog,” says [Eric](/community/profiles/30209), our data warehouse team lead. “Instead, they were analyzing data in the respective platforms — and they really wanted to analyze their marketing data alongside product data. So, we helped them [get data from Google Adwords into PostHog](/docs/data-warehouse/sources/google-ads).”
|
||||
“HeadshotPro wasn’t using a data warehouse before PostHog,” says [Eric](/community/profiles/30209), our data warehouse team lead. “Instead, they were analyzing data in the respective platforms — and they really wanted to analyze their marketing data alongside product data. So, we helped them [get data from Google Adwords into PostHog](/docs/data-warehouse/sources/google-ads).”
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
@@ -43,18 +43,16 @@ During the beta [our Data Warehouse team](/teams/data-warehouse) were naturally
|
||||
/>
|
||||
</BorderWrapper>
|
||||
|
||||
The process for getting Adwords data into PostHog is simple: three times a day Google Adwords automatically exports data in JSON format to a Google storage location. The data warehouse then syncs with this location as a custom source, giving Danny’s team all the data they need to make decisions about where to focus resources.
|
||||
The process for getting Adwords data into PostHog is simple: three times a day Google Adwords automatically exports data in JSON format to a Google storage location. The data warehouse then syncs with this location as a custom source, giving Danny’s team all the data they need to make decisions about where to focus resources.
|
||||
|
||||
### Creating a single source of truth in PostHog
|
||||
### Creating a single source of truth in PostHog
|
||||
|
||||
“It’s been amazing having everything in one place,” says Danny. “We had previously decided to scale down one of our distribution channels because we couldn’t analyze data properly in the native platform and we didn’t believe it was working.”
|
||||
“It’s been amazing having everything in one place,” says Danny. “We had previously decided to scale down one of our distribution channels because we couldn’t analyze data properly in the native platform and we didn’t believe it was working.”
|
||||
|
||||
“However, once we had the data in PostHog, we realized it was actually a very profitable channel for us and we quickly started it back up. Now, we make sure to put everything in PostHog.”
|
||||
|
||||
Even in situations where it was already possible to analyze data in the original platforms, it’s still often been faster and more valuable to have the data in PostHog.
|
||||
Even in situations where it was already possible to analyze data in the original platforms, it’s still often been faster and more valuable to have the data in PostHog.
|
||||
|
||||
“We’ve gone as far as just pulling in our bank data too,” says Danny. “Before, if I wanted to analyze business data, I may have to wait two months for my accountant to come up with it. Now, I see it day-by-day on a dashboard.”
|
||||
|
||||
“Honestly, my advice to new users would be: pull in everything you can. Avoid the clutter and the platform switching. Get it all into PostHog and it makes it so much easier to work with.”
|
||||
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
title: 'How Octomind’s marketing team uses PostHog with ease'
|
||||
customer: Octomind
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/octomind_logo_673e0ed777.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/octomind_logo_dark_a89deeee90.png
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/octomind_logo_dark_a89deeee90.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/octomind_logo_673e0ed777.png
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog_octomind_bb047603a6.jpg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog_octomind_bb047603a6.jpg
|
||||
featuredCustomer: false
|
||||
industries:
|
||||
- 'Devtool, SaaS'
|
||||
- 'Devtool, SaaS'
|
||||
users:
|
||||
- Marketing
|
||||
- Marketing
|
||||
toolsUsed:
|
||||
- Experiments
|
||||
- Surveys
|
||||
- PostHog Cloud
|
||||
- Insights
|
||||
- Web analytics
|
||||
- Product analytics
|
||||
- Experiments
|
||||
- Surveys
|
||||
- PostHog Cloud
|
||||
- Insights
|
||||
- Web analytics
|
||||
- Product analytics
|
||||
date: 2024-11-10
|
||||
---
|
||||
|
||||
@@ -33,7 +33,8 @@ Maria knew she needed a way to track marketing metrics, but also knew that Googl
|
||||
“Sometimes it can be difficult to persuade engineers to even implement a simple cookie banner, but in this case? Our developers love PostHog and quickly got started with no-cookie tracking and EU servers. GDPR compliance was just really easy and our engineers knew they had a real partner in the choice of analytics platform.”
|
||||
|
||||
### PostHog + Hubspot = A marketer's dream
|
||||
Following the initial implementation, Maria enabled autocapture to get data flowing into PostHog straight away, and got started with [web analytics](/web-analytics) and [pre-built dashboard templates](/templates). These enabled her to track the high-level data immediately, and as she’s become more familiar with the data she’s started building her own insights too.
|
||||
|
||||
Following the initial implementation, Maria enabled autocapture to get data flowing into PostHog straight away, and got started with [web analytics](/web-analytics) and [pre-built dashboard templates](/templates). These enabled her to track the high-level data immediately, and as she’s become more familiar with the data she’s started building her own insights too.
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
@@ -47,12 +48,13 @@ Following the initial implementation, Maria enabled autocapture to get data flow
|
||||
|
||||
“Analysis is always kind of funky because marketing data is so volatile,” says Maria. “Our content has gone viral a few times and that puts all sorts of peaks and dips onto the charts. When I don’t need to make adjustments I can just use web analytics, but other times I need to change the data and filter stuff out — it’s all easily done though.”
|
||||
|
||||
In addition to setting up these initial dashboards and insights, Maria also integrated PostHog with Hubspot so data could flow seamlessly between the two platforms.
|
||||
In addition to setting up these initial dashboards and insights, Maria also integrated PostHog with Hubspot so data could flow seamlessly between the two platforms.
|
||||
|
||||
“We don’t have a sales team, so we use Hubspot for automations based on sign-ups. We have different workflows which depend on how far people get with the product, where people get stuck. We’re still in an exploratory phase with this, but connecting PostHog and Hubspot was very useful.”
|
||||
|
||||
### Just ask PostHog
|
||||
Even though Maria is building her own queries and piping data to other platforms, there’s still plenty of room for Octomind to achieve more with PostHog — and Maria has taken the learning curve in stride.
|
||||
|
||||
Even though Maria is building her own queries and piping data to other platforms, there’s still plenty of room for Octomind to achieve more with PostHog — and Maria has taken the learning curve in stride.
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
@@ -66,6 +68,6 @@ Even though Maria is building her own queries and piping data to other platforms
|
||||
|
||||
“All the [tutorials and guides](/docs/product-analytics/tutorials) make it really easy,” says Maria. “Everything I need is right there and if I have questions then I can ask at [the bottom of any docs page](/docs/product-analytics/trends/overview) or look through the comments. I actually sometimes need to kick our guys when they say they’re stuck on something — I tell them: Ask PostHog! They’re really good at answering this stuff!”
|
||||
|
||||
Armed with this knowledge, Maria is planning to start using [PostHog’s A/B testing tools](/docs/experiments) on her landing pages, as well as no-code user surveys to gather user feedback. Again, [templates and guides for enabling users to book their own feedback calls](/templates/user-interview) will prove useful — though Maria saves her biggest praise for a different feature altogether.
|
||||
Armed with this knowledge, Maria is planning to start using [PostHog’s A/B testing tools](/docs/experiments) on her landing pages, as well as no-code user surveys to gather user feedback. Again, [templates and guides for enabling users to book their own feedback calls](/templates/user-interview) will prove useful — though Maria saves her biggest praise for a different feature altogether.
|
||||
|
||||
“I always have [hedgehog mode](/blog/rome-hackathon#hedgehog-mode) enabled,” says Maria. “I really love that hedgehog!”
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
title: How Purplewave reached a 25% response rate with PostHog surveys
|
||||
customer: Purplewave
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/purplewave/purplewave_logo.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/purplewave/purplewave_logo.png
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/purplewave/purplewave_logo_dark.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/purplewave/purplewave_logo_dark.png
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/purple_wave_014d7446a1.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/purple_wave_014d7446a1.png
|
||||
industries:
|
||||
- ECommerce
|
||||
- ECommerce
|
||||
users:
|
||||
- Product
|
||||
- Product
|
||||
toolsUsed:
|
||||
- Surveys
|
||||
- Surveys
|
||||
date: 2023-09-15
|
||||
---
|
||||
|
||||
[Purple Wave](https://www.purplewave.com/) is the world’s leading two-way marketplace for heavy duty equipment, such as construction and agriculture fleets. The team of 220+ people maintains a platform trusted by millions of annual visitors, with more than 150 fleet-scale auctions each year.
|
||||
[Purple Wave](https://www.purplewave.com/) is the world’s leading two-way marketplace for heavy duty equipment, such as construction and agriculture fleets. The team of 220+ people maintains a platform trusted by millions of annual visitors, with more than 150 fleet-scale auctions each year.
|
||||
|
||||
Now, the team plans to 3x that growth — something it can only do by adopting more scalable systems for collecting and handling user feedback about the platform.
|
||||
Now, the team plans to 3x that growth — something it can only do by adopting more scalable systems for collecting and handling user feedback about the platform.
|
||||
|
||||
“Previously a lot of teams operated on gut decisions and intuition,” says Purple Wave’s Product Owner, Matt Amick. “We had data, but it wasn’t mobilized well because it was accessed through a business intelligence tool which wasn’t the easiest to use. We started looking around for something that could help us make decisions based on data — and that’s when we found PostHog!”
|
||||
|
||||
@@ -26,34 +26,29 @@ Now, the team plans to 3x that growth — something it can only do by adopting m
|
||||
|
||||
Purple Wave began using many PostHog features, including [analytics](/product-analytics), [flags](/feature-flags), and [replays](/session-replay) — and when user surveys launched in their first beta state, the team adopted that too.
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
imageSource="/images/customers/purplewave_matt.jpg"
|
||||
size="md"
|
||||
name="Matt Amick"
|
||||
title="Product Owner, Purple Wave"
|
||||
quote={`“I love everything about PostHog from the design to the culture, just everything. When the team launched the surveys beta and we could make no-code surveys and have everything in one place too? That was just phenomenal.”`}
|
||||
/>
|
||||
</BorderWrapper>
|
||||
<OSQuote
|
||||
customer="purplewave"
|
||||
author="matt_amick"
|
||||
product="surveys"
|
||||
/>
|
||||
|
||||
### How Purple Wave reached a 25% response rate for user surveys
|
||||
|
||||
Before switching to PostHog, Purple Wave had previously attempted to solicit feedback over email using other tools. Response rates were poor, leading the team to consider more innovative ways to collect feedback.
|
||||
Before switching to PostHog, Purple Wave had previously attempted to solicit feedback over email using other tools. Response rates were poor, leading the team to consider more innovative ways to collect feedback.
|
||||
|
||||
“We were only getting a 14% response rate on NPS surveys previously,” says Matt. “So, I ran a test with in-app surveys using PostHog. I was still able to target identified users, and the response rate jumped to 25% — almost twice as good!”
|
||||
|
||||
Conducting surveys with PostHog also enabled Purple Wave to centralize data into a single platform. Responses could be analyzed using insights, linked to feature flags, or observed with session replays — all in one place.
|
||||
|
||||
“I really hate having to switch between separate software,” says Matt. “I want it all in one platform so it’s easy to access. Ultimately everything comes back to the [data warehouse](/docs/data-warehouse). You have to have your data centralized in order to use it effectively.”
|
||||
Conducting surveys with PostHog also enabled Purple Wave to centralize data into a single platform. Responses could be analyzed using insights, linked to feature flags, or observed with session replays — all in one place.
|
||||
|
||||
“I really hate having to switch between separate software,” says Matt. “I want it all in one platform so it’s easy to access. Ultimately everything comes back to the [data warehouse](/docs/data-warehouse). You have to have your data centralized in order to use it effectively.”
|
||||
|
||||

|
||||
<Caption>Survey templates help you get started quickly, or you can build your own from scratch</Caption>
|
||||
|
||||
<Caption>Survey templates help you get started quickly, or you can build your own from scratch</Caption>
|
||||
|
||||
### Collecting NPS scores, organizing interviews, and more
|
||||
|
||||
Armed with PostHog’s surveys, Purple Wave is now able to collect all the information it needs to build better products. The team uses the full range of question types to collect NPS scores, monitor satisfaction, and more, and even customizes each survey to appear consistently and only target relevant users.
|
||||
Armed with PostHog’s surveys, Purple Wave is now able to collect all the information it needs to build better products. The team uses the full range of question types to collect NPS scores, monitor satisfaction, and more, and even customizes each survey to appear consistently and only target relevant users.
|
||||
|
||||
“We have about 50 people using PostHog now so being able to launch no-code surveys is just phenomenal,” says Matt. “I don’t want to have to use any code for surveys, so having the customization options and the granularity of targeting options is just great. Really simple, really easy.”
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
title: 'How ResearchGate tests product changes for over 25M users'
|
||||
customer: ResearchGate
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/researchgate_logo_1627258295.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/researchgate_light_b4db4cc5d5.svg
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/resaerchgate_logo_dark_e8ea7ae745.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/researchgate_dark_502e1077d4.svg
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/researchgate_posthog_7a5a2cf3ac.png
|
||||
featuredCustomer: false
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
title: Why Significa switched from Plausible to PostHog
|
||||
customer: Significa
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711025316/posthog.com/contents/images/customers/significa/wordmark.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711025316/posthog.com/contents/images/customers/significa/wordmark.png
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711025316/posthog.com/contents/images/customers/significa/wordmark.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/v1711025316/posthog.com/contents/images/customers/significa/wordmark.png
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/significa_ef952b52a3.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/significa_ef952b52a3.png
|
||||
industries:
|
||||
- Agency
|
||||
- Agency
|
||||
users:
|
||||
- Marketing
|
||||
- Marketing
|
||||
toolsUsed:
|
||||
- Web analytics
|
||||
- Product analytics
|
||||
- Web analytics
|
||||
- Product analytics
|
||||
date: 2024-03-20
|
||||
---
|
||||
|
||||
@@ -21,7 +21,7 @@ date: 2024-03-20
|
||||
|
||||
“We offer a range of services, but we’re design focused,” said Tomás Gouveia, Significa’s Digital Marketer. “We like to think about the product first, assemble a unique strategy, then design bespoke solutions. We don’t use templates. We always design from scratch, and the whole process is customized to the client.”
|
||||
|
||||
When it came to web analytics, Significa used to rely on [Plausible](/blog/posthog-vs-plausible). But, as the company grew, the team began to find Plausible too simplistic. After less than a year on Plausible, they made the decision to switch to PostHog.
|
||||
When it came to web analytics, Significa used to rely on [Plausible](/blog/posthog-vs-plausible). But, as the company grew, the team began to find Plausible too simplistic. After less than a year on Plausible, they made the decision to switch to PostHog.
|
||||
|
||||
“We knew that PostHog was a much more powerful product and could handle other sorts of analytics,” said Tomás. “When we saw that it also offered web analytics, we decided to switch.”
|
||||
|
||||
@@ -31,28 +31,24 @@ Web analytics in PostHog is similar to Plausible – it’s centered around [a s
|
||||
|
||||
“We were using Plausible but it doesn’t really have any cool features to analyze data more deeply,” said Tomás. “PostHog, on the other hand, enables us to analyze our traffic in more ways and to set up funnels when we need to.”
|
||||
|
||||
Tomás is currently focused on tracking typical user interactions and uses [funnel and path insights](/product-analytics) to see which pages people move through, including their entry and exit points, and form submissions. In the future he envisions using additional tools, such as [A/B testing](/experiments) to learn even more.
|
||||
Tomás is currently focused on tracking typical user interactions and uses [funnel and path insights](/product-analytics) to see which pages people move through, including their entry and exit points, and form submissions. In the future he envisions using additional tools, such as [A/B testing](/experiments) to learn even more.
|
||||
|
||||
“We’re planning to deploy different landing pages across the site,” said Tomás. “A/B testing is one of the other features we’re going to start using first, so we can get an idea of what works and what helps us get more leads.”
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
imageSource="/images/customers/significa-tomas.jpg"
|
||||
size="md"
|
||||
name="Tomás Gouveia"
|
||||
title="Digital Marketer at Significa"
|
||||
quote={`“PostHog gives me all the same information Plausible used to give us, and a lot more. It’s way more powerful and insightful than Plausible.”`}
|
||||
/>
|
||||
</BorderWrapper>
|
||||
<OSQuote
|
||||
customer="significa"
|
||||
author="tomas_gouveia"
|
||||
product="web_analytics"
|
||||
/>
|
||||
|
||||
## Cookie-less tracking and Google Analytics
|
||||
## Cookie-less tracking and Google Analytics
|
||||
|
||||
Before Plausible, Significa used Google Analytics to track their traffic. While this had the advantage of deep integration with other Google tools, it wasn’t a good fit for Significa’s goals.
|
||||
Before Plausible, Significa used Google Analytics to track their traffic. While this had the advantage of deep integration with other Google tools, it wasn’t a good fit for Significa’s goals.
|
||||
|
||||
“Google Analytics is not intuitive at all and requires you to use cookies across your site,” explained Tomás. “We switched away from it and now the only thing we use from Google is AdWords. Users hate cookie banners, so we prefer not to use any cookies at all — and PostHog is much, much easier to use.”
|
||||
|
||||
The [toolbar](/docs/toolbar) in particular has made PostHog more accessible than other tools, said Tomás. With it, the team can both create new events and also visualize user interactions on a [heatmap](/docs/toolbar/heatmaps). The latter is especially useful when dealing with client proposals.
|
||||
The [toolbar](/toolbar) in particular has made PostHog more accessible than other tools, said Tomás. With it, the team can both create new events and also visualize user interactions on a [heatmap](/heatmaps). The latter is especially useful when dealing with client proposals.
|
||||
|
||||
“When we work with a new client we create an online proposal that exists as a private page on our site,” said Tomás. “We send this URL to them and then, because we know it’s only gone to that client, we can see how they interact with the proposal and learn from that.”
|
||||
|
||||
“These sorts of insights are really helpful for us, especially when we can also track traffic data and UTM sources too. There’s nothing missing from PostHog for us – it has everything we want. It’s really the perfect platform us.”
|
||||
“These sorts of insights are really helpful for us, especially when we can also track traffic data and UTM sources too. There’s nothing missing from PostHog for us – it has everything we want. It’s really the perfect platform us.”
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
title: How Supabase 10Xed with the help of PostHog
|
||||
customer: Supabase
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/supabase_light_30e9fe4a90.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/supabase_light_30e9fe4a90.png
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/supabase_dark_91fbc944e4.png
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/supabase_dark_91fbc944e4.png
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/445225882_d7aa6795_3350_4e88_9ca7_091c61e86e39_0ed5ee1f16.jpg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/445225882_d7aa6795_3350_4e88_9ca7_091c61e86e39_0ed5ee1f16.jpg
|
||||
industries:
|
||||
- Devtool
|
||||
- Devtool
|
||||
users:
|
||||
- Engineering
|
||||
- Growth
|
||||
- Marketing
|
||||
- Engineering
|
||||
- Growth
|
||||
- Marketing
|
||||
toolsUsed:
|
||||
- Max AI
|
||||
- Experimentation
|
||||
- Product analytics
|
||||
- Max AI
|
||||
- Experimentation
|
||||
- Product analytics
|
||||
date: 2025-06-15
|
||||
---
|
||||
|
||||
When he joined Supabase’s marketing team, Aleksi Immonen says most of the data he needed was fragmented across a handful of different tools and point solutions. The team used [Plausible](https://posthog.com/blog/posthog-vs-plausible) to track website traffic, for example, and internal tools for some of the event tracking.
|
||||
When he joined Supabase’s marketing team, Aleksi Immonen says most of the data he needed was fragmented across a handful of different tools and point solutions. The team used [Plausible](/blog/posthog-vs-plausible) to track website traffic, for example, and internal tools for some of the event tracking.
|
||||
|
||||
“The result was that it was quite challenging to do even basic attribution or usage-pattern analysis with the data,” says Aleksi. “We were self-hosting Plausible, and we had some data there, but it was quite limited, and the UI was just a little too slow for people to want to use it. So we did basically everything through BigQuery.”
|
||||
|
||||
@@ -28,7 +28,7 @@ When he joined Supabase’s marketing team, Aleksi Immonen says most of the data
|
||||
|
||||
Data wasn’t just fragmented — it was also incomplete due to the limitations of each individual platform and differences in their interoperability. Events tracked in internal tools, for example, didn’t always match 1:1 with data from Plausible, and no individual team had ownership of it all.
|
||||
|
||||
“None of us really had a full view of what event data we were tracking or the event definitions,” he explains. “But I’d used PostHog at my previous company at [Twice Commerce](https://www.twicecommerce.com/), really liked it, and knew it could help us a lot with attribution, funnel analysis, and A/B testing. PostHog’s open-source nature was also a plus.”
|
||||
“None of us really had a full view of what event data we were tracking or the event definitions,” he explains. “But I’d used PostHog at my previous company at [Twice Commerce](https://www.twicecommerce.com/), really liked it, and knew it could help us a lot with attribution, funnel analysis, and A/B testing. PostHog’s open-source nature was also a plus.”
|
||||
|
||||
<BorderWrapper>
|
||||
<Quote
|
||||
@@ -48,11 +48,12 @@ Now, every Supabase team can use the same set of data and interact with it effor
|
||||
|
||||
"PostHog has proven to be easy to use and adopt for product engineers. It’s also very easy to slice and dice data and to trace events back to a user, project, or an organization. PostHog also comes with built-in analysis tools—like funnels, retention, and user journey breakdowns—that make digging into the data easy."
|
||||
|
||||
Max AI, PostHog’s built-in AI assistant, is especially useful for complex investigations. Not only can Max easily write SQL queries on your behalf (or fix errors if you want to work alongside it), but it can be given access to your product data to help you find what you need.
|
||||
Max AI, PostHog’s built-in AI assistant, is especially useful for complex investigations. Not only can Max easily write SQL queries on your behalf (or fix errors if you want to work alongside it), but it can be given access to your product data to help you find what you need.
|
||||
|
||||
“I like Max as an AI helper because it knows PostHog terminology, as well as the data model, and schemas. It can fix my mistakes, help me join the right tables, and more. It makes everything a lot easier and faster.”
|
||||
|
||||

|
||||
|
||||
<Caption>Supabase's growth in user sign-ups over time. Can you tell when data started helping them grow?</Caption>
|
||||
|
||||
## How PostHog helped Supabase 10X weekly new user acquisition
|
||||
@@ -69,4 +70,4 @@ As soon as the team spotted the early trickle of sign-ups generated by AI builde
|
||||
|
||||
"Once we see a new one has appeared (weekly occurence), we can then look at all the other stats and make decisions about how to partner with them,” says Aleksi. “As a result—with AI builders as an important piece of the puzzle—we have already 10Xed our weekly user acquisition.”
|
||||
|
||||
“So, yeah, PostHog has literally helped us get 10X more weekly new users than we did a year ago.”
|
||||
“So, yeah, PostHog has literally helped us get 10X more weekly new users than we did a year ago.”
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
title: How Y Combinator used PostHog experiments to boost engagement by 40%
|
||||
customer: Y Combinator
|
||||
logo: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/ycombinator/logo.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/ycombinator_light_86e121ca81.svg
|
||||
logoDark: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/ycombinator/logo_dark.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/ycombinator_dark_926586dfe2.svg
|
||||
featuredImage: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog_YC_68ed8fa1bb.png
|
||||
featuredCustomer: true
|
||||
@@ -20,6 +20,7 @@ toolsUsed:
|
||||
- PostHog Cloud
|
||||
- Insights
|
||||
date: 2022-10-05
|
||||
notes: ""
|
||||
---
|
||||
|
||||
Y Combinator is the world’s top startup accelerator, helping to fund, train and nurture the next generation of innovative businesses. Since 2005, thousands of successful companies have emerged from Y Combinator, including Dropbox, Airbnb, PagerDuty, Reddit, Amplitude... and PostHog.
|
||||
|
||||
@@ -4,7 +4,7 @@ sidebar: Docs
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
import ProxyPathNamesWarning from "./_snippets/proxy-path-names-warning.mdx"
|
||||
import ProxyPathNamesWarning from './_snippets/proxy-path-names-warning.mdx'
|
||||
|
||||
A reverse proxy enables you to send events to PostHog Cloud using your own domain.
|
||||
|
||||
@@ -22,32 +22,32 @@ You'll be able to capture more usage data without having to self-host PostHog, e
|
||||
|
||||
Using our [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy) is the easiest way to do this.
|
||||
|
||||
It's available as part of our [platforms add-ons](/platform-addons), which includes automatic provisioning, SSO and 2FA enforcement, priority support, and additional collaboration features.
|
||||
It's available as part of our [platforms add-ons](/platform-packages), which includes automatic provisioning, SSO and 2FA enforcement, priority support, and additional collaboration features.
|
||||
|
||||
Other documented options for deploying a reverse proxy include:
|
||||
|
||||
- [AWS CloudFront](/docs/advanced/proxy/cloudfront)
|
||||
- [Caddy](/docs/advanced/proxy/caddy)
|
||||
- [Cloudflare](/docs/advanced/proxy/cloudflare)
|
||||
- [Kubernetes Ingress Controller](/docs/advanced/proxy/kubernetes-ingress-controller)
|
||||
- [Netlify](/docs/advanced/proxy/netlify)
|
||||
- [Next.js rewrites](/docs/advanced/proxy/nextjs)
|
||||
- [Next.js middleware](/docs/advanced/proxy/nextjs-middleware)
|
||||
- [nginx](/docs/advanced/proxy/nginx)
|
||||
- [node](/docs/advanced/proxy/node)
|
||||
- [Railway](/docs/advanced/proxy/railway)
|
||||
- [Remix](/docs/advanced/proxy/remix)
|
||||
- [SvelteKit](/docs/advanced/proxy/sveltekit)
|
||||
- [Vercel](/docs/advanced/proxy/vercel)
|
||||
- [Nuxt](/docs/advanced/proxy/nuxt)
|
||||
- [Pomerium](/docs/advanced/proxy/pomerium)
|
||||
- [AWS CloudFront](/docs/advanced/proxy/cloudfront)
|
||||
- [Caddy](/docs/advanced/proxy/caddy)
|
||||
- [Cloudflare](/docs/advanced/proxy/cloudflare)
|
||||
- [Kubernetes Ingress Controller](/docs/advanced/proxy/kubernetes-ingress-controller)
|
||||
- [Netlify](/docs/advanced/proxy/netlify)
|
||||
- [Next.js rewrites](/docs/advanced/proxy/nextjs)
|
||||
- [Next.js middleware](/docs/advanced/proxy/nextjs-middleware)
|
||||
- [nginx](/docs/advanced/proxy/nginx)
|
||||
- [node](/docs/advanced/proxy/node)
|
||||
- [Railway](/docs/advanced/proxy/railway)
|
||||
- [Remix](/docs/advanced/proxy/remix)
|
||||
- [SvelteKit](/docs/advanced/proxy/sveltekit)
|
||||
- [Vercel](/docs/advanced/proxy/vercel)
|
||||
- [Nuxt](/docs/advanced/proxy/nuxt)
|
||||
- [Pomerium](/docs/advanced/proxy/pomerium)
|
||||
|
||||
## Best practices
|
||||
|
||||
- We require that the proxy sets the `Host` header to the same host it's calling. Check the guides above on how to do that for several proxies.
|
||||
- Don't use a subdomain that includes `posthog`, `analytics`, `tracking`, or other similar words which might cause events to be blocked.
|
||||
- Make sure to [pass the proper `ui_host` parameter](/docs/libraries/js/config) when initializing PostHog, so that links to PostHog point to the correct host (like `us.posthog.com`). This is required for tasks like authenticating the toolbar.
|
||||
- <ProxyPathNamesWarning />
|
||||
- We require that the proxy sets the `Host` header to the same host it's calling. Check the guides above on how to do that for several proxies.
|
||||
- Don't use a subdomain that includes `posthog`, `analytics`, `tracking`, or other similar words which might cause events to be blocked.
|
||||
- Make sure to [pass the proper `ui_host` parameter](/docs/libraries/js/config) when initializing PostHog, so that links to PostHog point to the correct host (like `us.posthog.com`). This is required for tasks like authenticating the toolbar.
|
||||
- <ProxyPathNamesWarning />
|
||||
|
||||
## Reverse proxy requirements
|
||||
|
||||
@@ -64,5 +64,7 @@ If you want to use an alternative reverse proxy that we have not documented, it
|
||||
```
|
||||
|
||||
<CalloutBox icon="IconWarning" title="Beware of size limits" type="caution">
|
||||
Some systems have size limits (e.g. AWS WAF defaults to 8kb) which can cause problems if they are used as or with a reverse proxy. PostHog events can be up to 1MB and session recordings can be up to 64MB per message, so you may need to adjust your limits.
|
||||
Some systems have size limits (e.g. AWS WAF defaults to 8kb) which can cause problems if they are used as or with a
|
||||
reverse proxy. PostHog events can be up to 1MB and session recordings can be up to 64MB per message, so you may need
|
||||
to adjust your limits.
|
||||
</CalloutBox>
|
||||
|
||||
@@ -9,8 +9,9 @@ PostHog's managed reverse proxy service enables you to route traffic through Pos
|
||||
## Prerequisites
|
||||
|
||||
Before setting up the managed reverse proxy, ensure you have the following:
|
||||
- A PostHog Cloud account with our [platforms add-ons](https://posthog.com/platform-addons)
|
||||
- Access to your domain's DNS settings.
|
||||
|
||||
- A PostHog Cloud account with our [platforms add-ons](https://posthog.com/platform-packages)
|
||||
- Access to your domain's DNS settings.
|
||||
|
||||
## Creating a managed reverse proxy
|
||||
|
||||
@@ -18,8 +19,10 @@ Before setting up the managed reverse proxy, ensure you have the following:
|
||||
2. Click "New Managed Proxy"
|
||||
3. Enter a subdomain that you control. For example if you run posthog on `myapp.com`, you could use `ph.myapp.com`
|
||||
4. Go to your DNS provider and create a new CNAME record:
|
||||
- The `@` or target should be set to the subdomain you chose in the previous step
|
||||
- You will be shown a domain to use as the CNAME value when creating the record. It will look something like `4854cf84789d8596ad01.proxy-us.posthog.com.`
|
||||
|
||||
- The `@` or target should be set to the subdomain you chose in the previous step
|
||||
- You will be shown a domain to use as the CNAME value when creating the record. It will look something like `4854cf84789d8596ad01.proxy-us.posthog.com.`
|
||||
|
||||
5. Wait for the proxy to be created. It will go from "Waiting", to "Issuing" and finally "Live" once everything is set up. There is no further action required after creating the DNS record.
|
||||
6. Update your PostHog snippet or SDK to use the subdomain chosen in step 3 as the `api_host`. Make sure to also update the PostHog SDK's `ui_host` config property to `https://us.posthog.com` or `https://eu.posthog.com` depending on your Cloud region.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Realtime analytics data exports
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
<DestinationsLibraryCallout />
|
||||
<!-- <DestinationsLibraryCallout /> -->
|
||||
|
||||
> Destinations require the data pipeline add-on in [your billing settings](https://us.posthog.com/organization/billing).
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ You'll also need access to the relevant Zapier account.
|
||||
|
||||
## Installation
|
||||
|
||||
### Option 1: Via the PostHog app in Zapier <span class="bg-gray-accent-light dark:bg-gray-accent-dark text-gray font-semibold align-middle text-sm p-1 rounded">Recommended</span>
|
||||
### Option 1: Via the PostHog app in Zapier <span class="bg-accent text-gray font-semibold align-middle text-sm p-1 rounded">Recommended</span>
|
||||
|
||||
1. In your Zapier dashboard, go to your [zaps](https://zapier.com/app/assets/zaps) and create a new zap.
|
||||
2. Add the [PostHog app](https://zapier.com/apps/posthog/integrations/webhook) as a trigger.
|
||||
|
||||
@@ -73,7 +73,7 @@ These rules are applied in order, and the first one that matches is used to dete
|
||||
| Paid Social | Traffic is paid, and `referring_domain` matches our list of social sources (e.g. `facebook.com`, `linkedin.com`, `twitter.com`) |
|
||||
| Paid Video | Traffic is paid, and `referring_domain` matches our list of video sources (e.g. `youtube.com`, `twitch.tv`, `disneyplus.com`) |
|
||||
| Paid Shopping | Traffic is paid, and `referring_domain` matches our list of shopping sources (e.g. `amazon.com`, `etsy.com`, `ebay.co.uk`) |
|
||||
| Paid Shopping | Traffic is paid, and `utm_campaign` matches the regular expression <code class="text-inherit p-1 rounded bg-accent dark:bg-accent-dark border border-light dark:border-dark !text-[13px]">^(.*(([^a-df-z]|^)shop|shopping).*)$</code> |
|
||||
| Paid Shopping | Traffic is paid, and `utm_campaign` matches the regular expression <code class="text-inherit p-1 rounded bg-accent border border-primary !text-[13px]">^(.*(([^a-df-z]|^)shop|shopping).*)$</code> |
|
||||
| Paid Social | Traffic is paid, and `utm_medium` matches our list of social mediums (e.g. `sm`, `social-media`, `social-network`) |
|
||||
| Paid Video | Traffic is paid, and `utm_medium` matches our list of video mediums (e.g. `video`) |
|
||||
| Display | Traffic is paid, and `utm_medium` matches our list of display mediums (e.g. `display`, `interstitial`, `banner`) |
|
||||
@@ -92,7 +92,7 @@ These rules are applied in order, and the first one that matches is used to dete
|
||||
| Organic Social | `referring_domain` matches our list of social sources (e.g. `facebook.com`, `linkedin.com`, `twitter.com`) |
|
||||
| Organic Video | `referring_domain` matches our list of video sources (e.g. `youtube.com`, `twitch.tv`, `disneyplus.com`) |
|
||||
| Organic Shopping | `referring_domain` matches our list of shopping sources (e.g. `amazon.com`, `etsy.com`, `ebay.co.uk`) |
|
||||
| Organic Shopping | `utm_campaign` matches the regular expression <code class="text-inherit p-1 rounded bg-accent dark:bg-accent-dark border border-light dark:border-dark !text-[13px]">^(.*(([^a-df-z]|^)shop|shopping).*)$</code>|
|
||||
| Organic Shopping | `utm_campaign` matches the regular expression <code class="text-inherit p-1 rounded bg-accent border border-primary !text-[13px]">^(.*(([^a-df-z]|^)shop|shopping).*)$</code>|
|
||||
| Organic Social | `utm_medium` matches our list of social mediums (e.g. `sm`, `social-media`, `social-network`) |
|
||||
| Organic Video | `utm_medium` matches our list of video mediums (e.g. `video`) |
|
||||
| Affiliate | `utm_medium` matches our list of affiliate mediums (e.g. `affiliate`) |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Before proceeding, let's make sure exception events are being captured and sent to PostHog. You should see events appear in the activity feed.
|
||||
|
||||
<br/>
|
||||
<br />
|
||||
<ProductScreenshot
|
||||
imageLight="https://res.cloudinary.com/dmukukwp6/image/upload/SCR_20250729_ouxl_f788dd8cd2.png"
|
||||
imageDark="https://res.cloudinary.com/dmukukwp6/image/upload/SCR_20250729_owae_7c3490822c.png"
|
||||
@@ -12,8 +12,8 @@ Before proceeding, let's make sure exception events are being captured and sent
|
||||
padding={false}
|
||||
/>
|
||||
|
||||
<CallToAction className="my-2" size="sm" type="secondary" to="https://app.posthog.com/activity/explore" external={true}>
|
||||
Check for exceptions in PostHog
|
||||
</CallToAction>
|
||||
<OSButton asLink size="sm" variant="secondary" to="https://app.posthog.com/activity/explore" external={true}>
|
||||
Check for exceptions in PostHog
|
||||
</OSButton>
|
||||
|
||||
</Step>
|
||||
</Step>
|
||||
|
||||
@@ -1,6 +1,33 @@
|
||||
---
|
||||
title: Web error tracking installation
|
||||
showStepsToc: true
|
||||
tableOfContents: [
|
||||
{
|
||||
url: 'install-posthog-web-sdk',
|
||||
value: 'Install PostHog web SDK',
|
||||
depth: 1,
|
||||
},
|
||||
{
|
||||
url: 'set-up-exception-autocapture',
|
||||
value: 'Set up exception autocapture',
|
||||
depth: 1,
|
||||
},
|
||||
{
|
||||
url: 'manually-capture-exceptions',
|
||||
value: 'Manually capture exceptions',
|
||||
depth: 1,
|
||||
},
|
||||
{
|
||||
url: 'verify-error-tracking',
|
||||
value: 'Verify error tracking',
|
||||
depth: 1,
|
||||
},
|
||||
{
|
||||
url: 'upload-source-maps',
|
||||
value: 'Upload source maps',
|
||||
depth: 1,
|
||||
}
|
||||
]
|
||||
---
|
||||
|
||||
import { Steps, Step } from 'components/Docs/Steps'
|
||||
|
||||
@@ -3,6 +3,7 @@ title: Feature flag best practices
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
## 1. Use a reverse proxy
|
||||
|
||||
Ad blockers have the potential to disable your feature flags, which can lead to bad experiences, such as users seeing the wrong version of your app, or missing a new feature rollout.
|
||||
@@ -11,7 +12,7 @@ To avoid this, deploy a reverse proxy, which enables you to make requests and se
|
||||
|
||||
This means that requests are less likely to be intercepted by tracking blockers, and your feature flags are more likely to work as intended. You'll also capture more usage data.
|
||||
|
||||
PostHog customers on one of our [platforms add-ons](/platform-addons) can use our [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy), but there are numerous methods to run your own. See our [reverse proxy docs](/docs/advanced/proxy/managed-reverse-proxy) for more.
|
||||
PostHog customers on one of our [platforms add-ons](/platform-packages) can use our [managed reverse proxy](/docs/advanced/proxy/managed-reverse-proxy), but there are numerous methods to run your own. See our [reverse proxy docs](/docs/advanced/proxy/managed-reverse-proxy) for more.
|
||||
|
||||
## 2. Call your flag in as few places as possible
|
||||
|
||||
@@ -49,13 +50,13 @@ See our docs on [bootstrapping](/docs/feature-flags/bootstrapping) for more deta
|
||||
|
||||
Good naming conventions for your flags makes them easier to understand and maintain. Below are tips for naming your flags:
|
||||
|
||||
- **Use descriptive names.** For example, `is_v2_billing_dashboard_enabled` is much clearer than `is_dashboard_enabled`.
|
||||
- **Use descriptive names.** For example, `is_v2_billing_dashboard_enabled` is much clearer than `is_dashboard_enabled`.
|
||||
|
||||
- **Use name "types".** This helps organize them and makes their purpose clear. Types might include experiments, releases, and permissions. For example, instead of `new-billing`, they would be `new-billing-experiment` or `new-billing-release`.
|
||||
- **Use name "types".** This helps organize them and makes their purpose clear. Types might include experiments, releases, and permissions. For example, instead of `new-billing`, they would be `new-billing-experiment` or `new-billing-release`.
|
||||
|
||||
- **Name flags to reflect their return type.** For example, `is_premium_user` for a boolean, `enabled_integrations` for an array, or `selected_theme` for a single string.
|
||||
- **Name flags to reflect their return type.** For example, `is_premium_user` for a boolean, `enabled_integrations` for an array, or `selected_theme` for a single string.
|
||||
|
||||
- **Use positive language for boolean flags.** For example, `is_premium_user` instead of `is_not_premium_user`. This helps avoid double negatives when checking the flag value (e.g. `if !is_not_premium_user` is confusing).
|
||||
- **Use positive language for boolean flags.** For example, `is_premium_user` instead of `is_not_premium_user`. This helps avoid double negatives when checking the flag value (e.g. `if !is_not_premium_user` is confusing).
|
||||
|
||||
## 7. Roll out progressively
|
||||
|
||||
@@ -64,11 +65,12 @@ When testing a change behind a feature flag, it is best to roll it out to a smal
|
||||
For example, at PostHog we often roll out the flag to just the responsible developer. It then moves on to the internal team, then beta users, and finally into a full rollout. This enables us to [test in production](/product-engineers/testing-in-production), get multiple rounds of feedback, identify issues, and polish the feature before the full release.
|
||||
|
||||
## 8. Clean up after yourself
|
||||
|
||||
Leaving flags in your code for too long can confuse future developers and create technical debt, especially if it's already rolled out and integrated. Be sure to remove stale flags once they are completely rolled out or no longer needed.
|
||||
|
||||
## 9. Fallback to working code
|
||||
|
||||
It's possible that a feature flag will return an [unexpected value](/docs/feature-flags/common-questions#my-feature-flag-called-events-show-none-empty-string-or-false-instead-of-my-variant-names). For example, if the flag is disabled or failed to load due to a network error.
|
||||
It's possible that a feature flag will return an [unexpected value](/docs/feature-flags/common-questions#my-feature-flag-called-events-show-none-empty-string-or-false-instead-of-my-variant-names). For example, if the flag is disabled or failed to load due to a network error.
|
||||
|
||||
In this case, its best to check that the feature flag returns a valid expected value before using it. If it isn't, fallback to working code.
|
||||
|
||||
@@ -76,12 +78,12 @@ In this case, its best to check that the feature flag returns a valid expected v
|
||||
|
||||
For sophisticated feature rollouts, consider using [feature flag dependencies](/docs/feature-flags/dependencies) where one flag's activation depends on another flag's state. This is useful for:
|
||||
|
||||
- Enabling complex features only after foundational components are active
|
||||
- Running experiments only on users with specific features enabled
|
||||
- Creating safety mechanisms where critical flags must be enabled first
|
||||
- Enabling complex features only after foundational components are active
|
||||
- Running experiments only on users with specific features enabled
|
||||
- Creating safety mechanisms where critical flags must be enabled first
|
||||
|
||||
When using dependencies, keep the dependency chains simple and avoid circular dependencies.
|
||||
|
||||
## 11. Reducing your bill
|
||||
|
||||
We aim to be significantly cheaper than our competitors. To help you reduce your bill, we've created a [dedicated guide](/docs/feature-flags/cutting-costs) to estimating and reducing your feature flag costs.
|
||||
We aim to be significantly cheaper than our competitors. To help you reduce your bill, we've created a [dedicated guide](/docs/feature-flags/cutting-costs) to estimating and reducing your feature flag costs.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<details>
|
||||
<summary>Set up a reverse proxy (recommended)</summary>
|
||||
|
||||
We recommend [setting up a reverse proxy](/docs/advanced/proxy), so that events are less likely to be intercepted by tracking blockers.
|
||||
|
||||
We have our [own managed reverse proxy service included in the platform add-ons](/docs/advanced/proxy/managed-reverse-proxy), which routes through our infrastructure and makes setting up your proxy easy.
|
||||
We recommend [setting up a reverse proxy](/docs/advanced/proxy), so that events are less likely to be intercepted by tracking blockers.
|
||||
|
||||
If you don't want to use our managed service then there are several other options for creating a reverse proxy, including using [Cloudflare](/docs/advanced/proxy/cloudflare), [AWS Cloudfront](/docs/advanced/proxy/cloudfront), and [Vercel](/docs/advanced/proxy/vercel).
|
||||
</details>
|
||||
We have our [own managed reverse proxy service included in the platform packages](/docs/advanced/proxy/managed-reverse-proxy), which routes through our infrastructure and makes setting up your proxy easy.
|
||||
|
||||
If you don't want to use our managed service then there are several other options for creating a reverse proxy, including using [Cloudflare](/docs/advanced/proxy/cloudflare), [AWS Cloudfront](/docs/advanced/proxy/cloudfront), and [Vercel](/docs/advanced/proxy/vercel).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Snippet from "./install-js-snippet.mdx"
|
||||
|
||||
### Option 1: Add the JavaScript snippet to your HTML <span class="bg-gray-accent-light dark:bg-gray-accent-dark text-gray font-semibold align-middle text-sm p-1 rounded">Recommended</span>
|
||||
### Option 1: Add the JavaScript snippet to your HTML <span class="bg-accent text-gray font-semibold align-middle text-sm p-1 rounded">Recommended</span>
|
||||
|
||||
<Snippet />
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
---
|
||||
title: JavaScript Web setup
|
||||
title: JavaScript Web
|
||||
sidebarTitle: JavaScript Web
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
github: 'https://github.com/PostHog/posthog-js'
|
||||
icon: >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/integrate/js.svg
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/integrate/js.svg
|
||||
features:
|
||||
eventCapture: true
|
||||
userIdentification: true
|
||||
autoCapture: true
|
||||
sessionRecording: true
|
||||
featureFlags: true
|
||||
groupAnalytics: true
|
||||
surveys: true
|
||||
llmAnalytics: false
|
||||
errorTracking: true
|
||||
eventCapture: true
|
||||
userIdentification: true
|
||||
autoCapture: true
|
||||
sessionRecording: true
|
||||
featureFlags: true
|
||||
groupAnalytics: true
|
||||
surveys: true
|
||||
llmAnalytics: false
|
||||
errorTracking: true
|
||||
---
|
||||
|
||||
> **Note:** This doc refers to our [posthog-js](https://github.com/PostHog/posthog-js) library for use on the browser. For server-side JavaScript, see our [Node SDK](/docs/libraries/node).
|
||||
@@ -80,9 +80,10 @@ posthog.init('<ph_project_api_key>', {}, 'project2')
|
||||
You can then call these different instances by accessing it on the global `posthog` object
|
||||
|
||||
```ts
|
||||
posthog.project1.capture("some_event")
|
||||
posthog.project2.capture("other_event")
|
||||
posthog.project1.capture('some_event')
|
||||
posthog.project2.capture('other_event')
|
||||
```
|
||||
|
||||
> **Note:** You'll probably want to disable autocapture (and some other events) to avoid them from being sent to both instances. Check all of our [config options](/docs/libraries/js/config) to better understand that.
|
||||
|
||||
## Debugging
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
import React from 'react'
|
||||
import List from 'components/List'
|
||||
import { OSList } from 'components/OSList'
|
||||
import { IconOpenAI, IconAnthropic, IconGemini, IconLangChain, IconVercel, IconOpenRouter } from 'components/OSIcons'
|
||||
|
||||
const LLMInstallationPlatforms = () => {
|
||||
const platforms = [
|
||||
{
|
||||
label: 'OpenAI',
|
||||
url: '/docs/llm-analytics/installation/openai',
|
||||
image: 'https://res.cloudinary.com/dmukukwp6/image/upload/openai_d86c68d66f.svg',
|
||||
icon: <IconOpenAI />,
|
||||
},
|
||||
{
|
||||
label: 'Anthropic',
|
||||
url: '/docs/llm-analytics/installation/anthropic',
|
||||
image: 'https://res.cloudinary.com/dmukukwp6/image/upload/anthropic_093714e898.svg',
|
||||
icon: <IconAnthropic />,
|
||||
},
|
||||
{
|
||||
label: 'Google',
|
||||
label: 'Google Gemini',
|
||||
url: '/docs/llm-analytics/installation/google',
|
||||
image: 'https://res.cloudinary.com/dmukukwp6/image/upload/gemini_3b2348da64.svg',
|
||||
icon: <IconGemini />,
|
||||
},
|
||||
{
|
||||
label: 'LangChain',
|
||||
url: '/docs/llm-analytics/installation/langchain',
|
||||
image: 'https://res.cloudinary.com/dmukukwp6/image/upload/langchain_bb97e9da36.svg',
|
||||
icon: <IconLangChain />,
|
||||
},
|
||||
{
|
||||
label: 'Vercel AI SDK',
|
||||
url: '/docs/llm-analytics/installation/vercel-ai',
|
||||
image: 'https://res.cloudinary.com/dmukukwp6/image/upload/vercel_ded5edb1ef.svg',
|
||||
icon: <IconVercel />,
|
||||
},
|
||||
{
|
||||
label: 'OpenRouter',
|
||||
url: '/docs/llm-analytics/installation/openrouter',
|
||||
icon: <IconOpenRouter />,
|
||||
},
|
||||
{
|
||||
label: 'OpenRouter',
|
||||
@@ -35,6 +41,6 @@ const LLMInstallationPlatforms = () => {
|
||||
},
|
||||
]
|
||||
|
||||
return <List className="grid sm:grid-cols-2" items={platforms} />
|
||||
return <OSList className="grid" items={platforms} />
|
||||
}
|
||||
export default LLMInstallationPlatforms
|
||||
|
||||
@@ -9,13 +9,13 @@ import { CalloutBox } from 'components/Docs/CalloutBox'
|
||||
|
||||
<CalloutBox type="caution" title="Important">
|
||||
|
||||
PostHog only offers Business Associate Agreements (BAAs) for PostHog Cloud to users with [Boost, Scale or Enterprise add-ons](/platform-addons). You can use [our BAA generator](/baa) to create a BAA for us to countersign.
|
||||
PostHog only offers Business Associate Agreements (BAAs) for PostHog Cloud to users with [Boost, Scale or Enterprise add-ons](/platform-packages). You can use [our BAA generator](/baa) to create a BAA for us to countersign.
|
||||
|
||||
</CalloutBox>
|
||||
|
||||
HIPAA is the Health Insurance Portability and Accountability Act. It’s a piece of legislation that applies to certain [covered entities](https://www.hhs.gov/hipaa/for-professionals/covered-entities/index.html) operating in the United States of America (e.g. healthcare providers).
|
||||
|
||||
A key goal of this legislation is to ["assure that individuals' health information is properly protected while allowing the flow of health information needed to provide and promote high quality health care and to protect the public's health and well being.""](https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html)
|
||||
A key goal of this legislation is to ["assure that individuals' health information is properly protected while allowing the flow of health information needed to provide and promote high quality health care and to protect the public's health and well being.""](https://www.hhs.gov/hipaa/for-professionals/privacy/laws-regulations/index.html)
|
||||
|
||||
In other words, it stops anyone from using or sharing a persons data improperly.
|
||||
|
||||
@@ -23,7 +23,7 @@ The consequences of violating HIPAA are severe. It can lead to fines of over $1M
|
||||
|
||||
<CalloutBox type="info" title="This guide is not legal advice">
|
||||
|
||||
It is up to you to ensure you're compliant with regulations. We strongly recommend reading the relevant regulations in full and seeking independent legal advice regarding your obligations.
|
||||
It is up to you to ensure you're compliant with regulations. We strongly recommend reading the relevant regulations in full and seeking independent legal advice regarding your obligations.
|
||||
|
||||
</CalloutBox>
|
||||
|
||||
@@ -31,7 +31,7 @@ It is up to you to ensure you're compliant with regulations. We strongly recomme
|
||||
|
||||
Data which is protected under HIPAA is called Protected Health Information (PHI), or ePHI if it exists specifically in electronic format. It includes any identifying information related to a past, present or future health status. That includes individual diagnoses, medical test results and prescription info, as well as birthdays, gender, ethnicity and contact information.
|
||||
|
||||
In short, any information which is tied to a specific individual can be considered PHI, from their social security number or license plate number to photos, emails, URLs or formal medical information.
|
||||
In short, any information which is tied to a specific individual can be considered PHI, from their social security number or license plate number to photos, emails, URLs or formal medical information.
|
||||
|
||||
## What is the impact of HIPAA on product analytics?
|
||||
|
||||
@@ -44,14 +44,14 @@ Most product analytics tools require you to send your captured user data to a th
|
||||
There are downsides to these two solutions:
|
||||
|
||||
1. **Anonymization**: You can easily limit the data so much that it becomes meaningless and makes it impossible to perform standard and critical analyses of your product and users. There's no point reducing the data to an unusable state.
|
||||
|
||||
|
||||
2. **Business Associate Agreement**: Business Associate Agreements are often expensive and/or require you to pay for a higher tier of product than you actually require.
|
||||
|
||||
PostHog offers a third approach without either of these downsides: hosting the product analytics systems yourself.
|
||||
|
||||
## Does PostHog offer a BAA for PostHog Cloud?
|
||||
|
||||
Yes. If you're interested in a BAA for HIPAA compliance, please [contact us with information about your requirements](/talk-to-a-human).
|
||||
Yes. If you're interested in a BAA for HIPAA compliance, please [contact us with information about your requirements](/talk-to-a-human).
|
||||
|
||||
## How to set PostHog up for HIPAA compliance
|
||||
|
||||
@@ -61,22 +61,22 @@ We strongly recommend teams which need HIPAA compliance use PostHog Cloud under
|
||||
|
||||
</CalloutBox>
|
||||
|
||||
The best way to use PostHog in a way which is HIPAA compliant is with a BAA covering a PostHog Cloud instance. This ensures that PostHog remains scalable and that you have access to all premium features and security enhancements. BAAs are only available to users with a [platform add-on for our standard BAA, or the Enterprise plan for a custom BAA](/platform-addons).
|
||||
The best way to use PostHog in a way which is HIPAA compliant is with a BAA covering a PostHog Cloud instance. This ensures that PostHog remains scalable and that you have access to all premium features and security enhancements. BAAs are only available to users with a [platform add-on for our standard BAA, or the Enterprise plan for a custom BAA](/platform-packages).
|
||||
|
||||
However, it is possible to host PostHog yourself using our open-source hobby deployment. It is important to note that the hobby deployment is **only suitable for smaller event volumes** and provided without guarantee. It also lacks many of the advanced features available under PostHog Cloud.
|
||||
However, it is possible to host PostHog yourself using our open-source hobby deployment. It is important to note that the hobby deployment is **only suitable for smaller event volumes** and provided without guarantee. It also lacks many of the advanced features available under PostHog Cloud.
|
||||
|
||||
If you wish to attempt self-hosting PostHog in a HIPAA compliant manner despite the limitations, please follow the steps below.
|
||||
If you wish to attempt self-hosting PostHog in a HIPAA compliant manner despite the limitations, please follow the steps below.
|
||||
|
||||
**Step 1: Choose a hosting provider**
|
||||
We recommend hosting PostHog on your own infrastructure. If you're leveraging a private cloud you will need a Business Associate Agreement with your provider first.
|
||||
We recommend hosting PostHog on your own infrastructure. If you're leveraging a private cloud you will need a Business Associate Agreement with your provider first.
|
||||
|
||||
**Step 2: Deploy PostHog**
|
||||
Follow our [standard deployment guides](/docs/self-host) to get started deploying PostHog. This is a technical task which requires some engineering knowledge.
|
||||
Follow our [standard deployment guides](/docs/self-host) to get started deploying PostHog. This is a technical task which requires some engineering knowledge.
|
||||
|
||||
**Step 3: Security configuration**
|
||||
We strongly recommend that you use HTTPS to secure data in transmission, whether or not your instance has access to the wider internet. We also have a [guide for securing PostHog](/docs/self-host/configure/securing-posthog) which you should follow to further protect your instance. We recommend you limit access to your self-hosted deployment, including shared dashboard links and subscriptions, as well as caution when installing, building and enabling [apps](/docs/apps).
|
||||
|
||||
### Further reading
|
||||
|
||||
- [A simple guide to personal data & PII](/blog/what-is-personal-data-pii)
|
||||
- [Is Google Analytics HIPAA compliant?](/blog/is-google-analytics-hipaa-compliant)
|
||||
- [A simple guide to personal data & PII](/blog/what-is-personal-data-pii)
|
||||
- [Is Google Analytics HIPAA compliant?](/blog/is-google-analytics-hipaa-compliant)
|
||||
|
||||
@@ -99,13 +99,13 @@ Clicking the dropdown on the 'Add insight button' reveals the option to add a te
|
||||
|
||||
Text cards support Markdown formatting for text. You can also drag and drop images.
|
||||
|
||||
You can use text cards to annotate your dashboard – useful for adding context for other users of the dashboard. For more in-depth analysis, however, we recommend [creating a notebook](/docs/notebooks).
|
||||
You can use text cards to annotate your dashboard – useful for adding context for other users of the dashboard. For more in-depth analysis, however, we recommend [creating a notebook](/docs/notebooks).
|
||||
|
||||
### Sharing a dashboard
|
||||
|
||||
By clicking 'Share' in the top right corner you can:
|
||||
|
||||
- Restrict edit access to certain members within a project. Dashboards can be shared either by members with administrator privileges or by the dashboard creator ([platforms add-ons](/platform-addons) required).
|
||||
- Restrict edit access to certain members within a project. Dashboards can be shared either by members with administrator privileges or by the dashboard creator ([platforms add-ons](/platform-packages) required).
|
||||
|
||||
- Create a link to share your dashboard publicly, or embed your dashboard on a website. Read more about this in our [sharing and embedding docs](/docs/product-analytics/sharing).
|
||||
|
||||
|
||||
@@ -3,34 +3,34 @@ title: Single sign-on authentication
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
availability:
|
||||
free: partial
|
||||
selfServe: partial
|
||||
enterprise: full
|
||||
features:
|
||||
jitUserProvisioning:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
ssoEnforcement:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
github: true
|
||||
gitlab: true
|
||||
google:
|
||||
openSource: false
|
||||
free: true
|
||||
selfServe: true
|
||||
enterprise: true
|
||||
saml:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
free: partial
|
||||
selfServe: partial
|
||||
enterprise: full
|
||||
features:
|
||||
jitUserProvisioning:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
ssoEnforcement:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
github: true
|
||||
gitlab: true
|
||||
google:
|
||||
openSource: false
|
||||
free: true
|
||||
selfServe: true
|
||||
enterprise: true
|
||||
saml:
|
||||
free: false
|
||||
selfServe: false
|
||||
enterprise: true
|
||||
---
|
||||
|
||||
SSO makes logging in easier for users to log and compliance easier for administrators.
|
||||
|
||||
We also allow support just-in-time provisioning of users with our platform add-ons, which means that team members can self-serve creating their account, while still enforcing log in through a specified SSO provider.
|
||||
We also allow support just-in-time provisioning of users with our platform packages, which means that team members can self-serve creating their account, while still enforcing log in through a specified SSO provider.
|
||||
|
||||
Some SSO features are add-ons. Please review each section below for details.
|
||||
|
||||
@@ -66,7 +66,7 @@ To enable just-in-time user provisioning, navigate to Authentication domains in
|
||||
|
||||
<FeatureAvailability availability={_frontmatter.availability.features.ssoEnforcement} />
|
||||
|
||||
You may want to force users log in and/or sign up to your organization using a specific SSO provider.
|
||||
You may want to force users log in and/or sign up to your organization using a specific SSO provider.
|
||||
|
||||
When SSO enforcement is enabled, users cannot:
|
||||
|
||||
@@ -140,6 +140,7 @@ To set up Google SSO please follow these instructions:
|
||||
2. Navigate to the [Credentials](https://console.cloud.google.com/projectselector2/apis/credentials) section.
|
||||
|
||||
3. Click on "Create credentials" and select "OAuth client ID" to generate your credentials.
|
||||
|
||||
- On Application Type select "Web application" and enter a meaningful name (e.g. PostHog Self-hosted).
|
||||
- On the "Authorized JavaScript origins" section add the root domain (with protocol) for your PostHog instance (e.g. `https://us.posthog.com`)
|
||||
- On the "Authorized redirect URIs" section add the following URI (**replace with your hostname**): `https://{hostname}/complete/google-oauth2/`.
|
||||
@@ -180,6 +181,7 @@ For SAML to work your IdP and PostHog (SP) need to exchange information. To do t
|
||||
2. If you are on self-hosted, you will need to be running your PostHog instance over TLS.
|
||||
|
||||
3. Register a new SAML 2.0 application with your IdP. If you need to pass PostHog's information to your provider first, set the following values below (alternatively if your IdP supports it, you can obtain our XML metadata from `<yourdomain>/api/saml/metadata/`)
|
||||
|
||||
- **Single Sign On URL** (also called ACS Consumer URL): `<yourdomain>/complete/saml/` or `https://us.posthog.com/complete/saml/` for PostHog Cloud US or `https://eu.posthog.com/complete/saml/` for PostHog Cloud EU.
|
||||
- **Audience or Entity ID**: _Your Site URL_ value (verbatim), on PostHog Cloud this is `https://us.posthog.com` or `https://eu.posthog.com`
|
||||
- **RelayState**: On PostHog cloud, get your RelayState value from the SAML configuration modal in your PostHog Organization settings. For self hosted, _empty or default_ (will be set on every request).
|
||||
@@ -225,7 +227,7 @@ For SAML to work your IdP and PostHog (SP) need to exchange information. To do t
|
||||
3. You will now need to obtain some parameters from your IdP and configure them in PostHog for the appropriate domain in Authentication domains. Depending on your provider, they may only provide this information as an XML metadata file. If this is the case, you can open the file in a text editor and obtain the required values from there.
|
||||
|
||||
- **SAML Entity ID**: Will be identified as EntityID or IdP issuer. This can vary greatly between providers, but it usually looks like a URL.
|
||||
- If using Azure AD the setting to use for this field is called `Azure AD Identifier`.
|
||||
- If using Azure AD the setting to use for this field is called `Azure AD Identifier`.
|
||||
- **SAML ACS URL**: The endpoint to which the SAML requests are posted. It's usually called SAML endpoint or IdP sign-on URL.
|
||||
- **SAML X.509 certificate**: The public certificate used to validate SAML assertions from your IdP. It must be in X509 (almost all providers will provide it in this format). If your provider gives you the certificate as a file (usually `.pem`), just open it with a text editor to get the contents. When setting this certificate be sure to **keep any spaces and new lines** (don't format it). The first and last line of the certificate (e.g. `-----BEGIN CERTIFICATE-----`) are optional.
|
||||
|
||||
@@ -250,6 +252,7 @@ You can quickly connect OneLogin and PostHog by using the prebuilt integration.
|
||||
2. Go to the "Configuration" tab and where it says "PostHog domain name" enter your PostHog's instance domain (as it's also specified in the `SITE_URL` [environment variable][env-vars]), **but don't include any protocol or trailing slashes.** Examples: `playground.posthog.com`, `myposthog.mydomain.com`, `myposthogdomain.com`.
|
||||
|
||||
3. Go to the "SSO" tab. This is where you'll obtain the information you need to pass to PostHog.
|
||||
|
||||
- "Issuer URL" needs to be set as SAML Entity ID.
|
||||
- "SAML 2.0 Endpoint (HTTP)" needs to be set as SAML ACS URL.
|
||||
- On "X.509 Certificate" click on "View Details". Copy the full certificate and set it as SAML X.509 certificate.
|
||||
@@ -265,20 +268,23 @@ Use this option if you want to add additional configurations to your app that ar
|
||||
2. Search for "SAML" and select "SAML Custom Connector (Advanced)". Set name to "PostHog".
|
||||
|
||||
3. Go to the "Configuration" tab and edit the following attributes (leave everything else as default)
|
||||
|
||||
- Audience (EntityID): enter `https://us.posthog.com`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com`.
|
||||
- If you are self-hosting, enter the exact same value as your `SITE_URL` [environment variable][env-vars].
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com`.
|
||||
- If you are self-hosting, enter the exact same value as your `SITE_URL` [environment variable][env-vars].
|
||||
- ACS (Consumer) URL Validator: Set to a regex that only matches `<yourdomain>/complete/saml/`. For instance: `^https:\/\/us.posthog.com\/complete\/saml\/$` (or use `eu` for an EU instance)
|
||||
- ACS (Consumer) URL: Set to `https://us.posthog.com/complete/saml/`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com/complete/saml/`.
|
||||
- If you are self-hosting, use `<yourdomain>/complete/saml/`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com/complete/saml/`.
|
||||
- If you are self-hosting, use `<yourdomain>/complete/saml/`.
|
||||
|
||||
4. Go to the "Parameters" tab. You will add the following parameters. **Be sure to check "Include in SAML assertion"**.
|
||||
|
||||
- `email` to match the user's email ("Email")
|
||||
- `first_name` to match the user's first name ("First Name")
|
||||
- `last_name` to match the user's last name ("Last Name")
|
||||
|
||||
5. Go to the "SSO" tab. This is where you'll obtain the information you need to pass to PostHog.
|
||||
|
||||
- "Issuer URL" needs to be set as SAML Entity ID.
|
||||
- "SAML 2.0 Endpoint (HTTP)" needs to be set as SAML ACS URL.
|
||||
- On "X.509 Certificate" click on "View Details". Copy the full certificate, removing the first and last lines and set it as SAML X.509 certificate.
|
||||
@@ -293,14 +299,15 @@ Use this option if you want to add additional configurations to your app that ar
|
||||
|
||||
3. Fill in the following attributes in the SAML settings. Do not click next yet.
|
||||
- In "Single sign on URL" enter `https://us.posthog.com/complete/saml/`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com/complete/saml/`.
|
||||
- If you are self-hosting, use `<yourdomain>/complete/saml/`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com/complete/saml/`.
|
||||
- If you are self-hosting, use `<yourdomain>/complete/saml/`.
|
||||
- In "Audience URI (SP Entity ID)" enter `https://us.posthog.com`.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com`.
|
||||
- If you are self-hosting, enter the exact same value as your `SITE_URL` environment variable.
|
||||
- If you are using our EU deployment, use `https://eu.posthog.com`.
|
||||
- If you are self-hosting, enter the exact same value as your `SITE_URL` environment variable.
|
||||
4. In the Default Relay State field, enter the RelayState value you obtain from your [PostHog Organization Settings page](https://us.posthog.com/organization/settings) in the SAML configuration modal.
|
||||
|
||||
5. In the "Attribute Statements" section, add the following attributes:
|
||||
|
||||
- `email` with value `user.email`
|
||||
- `first_name` with value `user.firstName`
|
||||
- `last_name` with value `user.lastName`
|
||||
@@ -312,7 +319,6 @@ Use this option if you want to add additional configurations to your app that ar
|
||||
- "Identity Provider Single Sign-on URL" needs to be set as SAML ACS URL.
|
||||
- "Identity Provider Issuer" needs to be set as SAML Entity ID (use the complete URL).
|
||||
- "X.509 Certificate" needs to be set as SAML X.509 certificate.
|
||||
|
||||
8. You're good to go! Click on "Login with SSO" in the login page.
|
||||
|
||||
[env-vars]: /docs/self-host/configure/environment-variables
|
||||
|
||||
@@ -3,30 +3,41 @@ title: Creating surveys
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
availability:
|
||||
free: none
|
||||
selfServe: full
|
||||
enterprise: full
|
||||
free: none
|
||||
selfServe: full
|
||||
enterprise: full
|
||||
---
|
||||
|
||||
export const newSurveyLight = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/surveys/new-survey-light-mode.png"
|
||||
export const newSurveyDark = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/surveys/new-survey-dark-mode.png"
|
||||
export const delaySurveyLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_06_25_at_11_09_57_AM_fb3b007108.png"
|
||||
export const delaySurveyDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_06_25_at_11_09_41_AM_52fd4a8e34.png"
|
||||
export const displayConditionsLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_07_10_at_9_52_48_AM_6287f11b96.png"
|
||||
export const displayConditionsDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_07_10_at_9_52_35_AM_3fefd0b9cc.png"
|
||||
export const surveyTriggeredByEventLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_11_31_42_2x_98d85d5b3f.jpg"
|
||||
export const surveyTriggeredByEventDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_11_30_53_2x_03ab445fae.jpg"
|
||||
export const repeatingSurveyLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_13_57_07_2x_ed762875ba.jpg"
|
||||
export const repeatingSurveyDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_13_58_16_2x_c988952434.jpg"
|
||||
export const presentationTypesLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_32_2x_87293a9164.jpg"
|
||||
export const presentationTypesDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_19_2x_13141dad74.jpg"
|
||||
export const copySurveyLinkLight = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_56_2x_91fd773df9.jpg"
|
||||
export const copySurveyLinkDark = "https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_39_26_2x_11ecb9914d.jpg"
|
||||
export const newSurveyLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/surveys/new-survey-light-mode.png'
|
||||
export const newSurveyDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/docs/surveys/new-survey-dark-mode.png'
|
||||
export const delaySurveyLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_06_25_at_11_09_57_AM_fb3b007108.png'
|
||||
export const delaySurveyDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_06_25_at_11_09_41_AM_52fd4a8e34.png'
|
||||
export const displayConditionsLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_07_10_at_9_52_48_AM_6287f11b96.png'
|
||||
export const displayConditionsDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Screenshot_2024_07_10_at_9_52_35_AM_3fefd0b9cc.png'
|
||||
export const surveyTriggeredByEventLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_11_31_42_2x_98d85d5b3f.jpg'
|
||||
export const surveyTriggeredByEventDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_11_30_53_2x_03ab445fae.jpg'
|
||||
export const repeatingSurveyLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_13_57_07_2x_ed762875ba.jpg'
|
||||
export const repeatingSurveyDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_05_27_at_13_58_16_2x_c988952434.jpg'
|
||||
export const presentationTypesLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_32_2x_87293a9164.jpg'
|
||||
export const presentationTypesDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_19_2x_13141dad74.jpg'
|
||||
export const copySurveyLinkLight =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_38_56_2x_91fd773df9.jpg'
|
||||
export const copySurveyLinkDark =
|
||||
'https://res.cloudinary.com/dmukukwp6/image/upload/Clean_Shot_2025_08_04_at_11_39_26_2x_11ecb9914d.jpg'
|
||||
|
||||
<iframe
|
||||
src="https://www.youtube-nocookie.com/embed/2jQco8hEvTI?start=900"
|
||||
className="rounded shadow-xl"
|
||||
/>
|
||||
<iframe src="https://www.youtube-nocookie.com/embed/2jQco8hEvTI?start=900" className="rounded shadow-xl" />
|
||||
|
||||
To create a new survey, go to the [surveys tab](https://us.posthog.com/surveys) in the PostHog app, and click on the "New survey" button in the top right. This presents you with a collection of [survey templates](/templates?filter=type&value=survey) or you can click "Create blank survey" in the top right to create your own.
|
||||
|
||||
@@ -39,27 +50,23 @@ To create a new survey, go to the [surveys tab](https://us.posthog.com/surveys)
|
||||
|
||||
After choosing one, you are brought to a form where you can complete the details of your new survey:
|
||||
|
||||
<ProductScreenshot
|
||||
imageLight={newSurveyLight}
|
||||
imageDark={newSurveyDark}
|
||||
alt="Create a survey"
|
||||
classes="rounded"
|
||||
/>
|
||||
<ProductScreenshot imageLight={newSurveyLight} imageDark={newSurveyDark} alt="Create a survey" classes="rounded" />
|
||||
|
||||
## MaxAI and Surveys
|
||||
## Max AI and surveys
|
||||
|
||||
[Max](/docs/max-ai), PostHog's AI-powered product analyst, can help you create surveys quickly using natural language. Max understands different question types and can:
|
||||
[Max](/max), PostHog's AI-powered assistant, can help you create surveys quickly using natural language. Max understands different question types and can:
|
||||
|
||||
- Generate complete surveys based on your research goals
|
||||
- Suggest appropriate question types (freeform text, rating scales, multiple choice, etc.)
|
||||
- Help you set up display conditions and targeting
|
||||
- Recommend survey templates for common use cases
|
||||
- Generate complete surveys based on your research goals
|
||||
- Suggest appropriate question types (freeform text, rating scales, multiple choice, etc.)
|
||||
- Help you set up display conditions and targeting
|
||||
- Recommend survey templates for common use cases
|
||||
|
||||
You can ask Max things like:
|
||||
- "Create an NPS survey for my mobile app users"
|
||||
- "Build a product satisfaction survey with rating questions"
|
||||
- "Help me create a survey to understand why users churn"
|
||||
- "Generate a post-purchase feedback survey"
|
||||
|
||||
- "Create an NPS survey for my mobile app users"
|
||||
- "Build a product satisfaction survey with rating questions"
|
||||
- "Help me create a survey to understand why users churn"
|
||||
- "Generate a post-purchase feedback survey"
|
||||
|
||||
To get started, click "Max" in the top right corner of the PostHog app and describe what kind of survey you want to create.
|
||||
|
||||
@@ -88,7 +95,7 @@ There are three options for displaying a survey:
|
||||
classes="rounded"
|
||||
/>
|
||||
|
||||
Popover, API, and feedback button surveys are considered *in-app* surveys, meaning they are displayed directly in your application using our SDKs. Hosted surveys are displayed via an external URLs, hosted by PostHog.
|
||||
Popover, API, and feedback button surveys are considered _in-app_ surveys, meaning they are displayed directly in your application using our SDKs. Hosted surveys are displayed via an external URLs, hosted by PostHog.
|
||||
|
||||
#### Identifying respondents on hosted surveys
|
||||
|
||||
@@ -115,26 +122,26 @@ You can also add [conditional logic](/docs/surveys/conditional-questions) to dis
|
||||
|
||||
PostHog supports multiple question types which are all available for both popover and API display modes.
|
||||
|
||||
| Type | Preview |
|
||||
|------------------------|-------------------------------------------------------------------------------------------------------|
|
||||
| **Freeform text** |  |
|
||||
| **Link/Notification** |  |
|
||||
| **Rating emoji** |  |
|
||||
| **Rating - number** |  |
|
||||
| **Single choice select** |  |
|
||||
| **Multiple choice select** |  |
|
||||
| Type | Preview |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Freeform text** |  |
|
||||
| **Link/Notification** |  |
|
||||
| **Rating emoji** |  |
|
||||
| **Rating - number** |  |
|
||||
| **Single choice select** |  |
|
||||
| **Multiple choice select** |  |
|
||||
|
||||
### Customization
|
||||
|
||||
Customization enables you to change the look, feel, and timing of your popover survey:
|
||||
|
||||
- The color of the background, border, and buttons.
|
||||
- The position of the popover at the bottom of the screen.
|
||||
- The placeholder text.
|
||||
- The visibility of the PostHog branding.
|
||||
- Whether to shuffle the order of the choices and questions.
|
||||
- The delay (in seconds) before the survey appears on the page.
|
||||
- Whether the confirmation message auto disappears after 5 seconds.
|
||||
- The color of the background, border, and buttons.
|
||||
- The position of the popover at the bottom of the screen.
|
||||
- The placeholder text.
|
||||
- The visibility of the PostHog branding.
|
||||
- Whether to shuffle the order of the choices and questions.
|
||||
- The delay (in seconds) before the survey appears on the page.
|
||||
- Whether the confirmation message auto disappears after 5 seconds.
|
||||
|
||||
<ProductScreenshot
|
||||
imageLight={delaySurveyLight}
|
||||
@@ -153,19 +160,19 @@ This specifies the conditions a user must meet to be shown an in-app survey. A u
|
||||
|
||||
You can display your survey to specific users based on:
|
||||
|
||||
- **Linked feature flag:** Whether a user has a specific [feature flag](/docs/feature-flags) enabled. For example, if you're rolling out a new landing page using a feature flag `new-landing-page`, you can gather feedback only from users who have that flag enabled. This is also a way to show surveys to cohorts (but it must be a [non-behavioral one](/docs/feature-flags/common-questions#why-cant-i-use-a-cohort-with-behavioral-filters-in-my-feature-flag)).
|
||||
- **Linked feature flag:** Whether a user has a specific [feature flag](/docs/feature-flags) enabled. For example, if you're rolling out a new landing page using a feature flag `new-landing-page`, you can gather feedback only from users who have that flag enabled. This is also a way to show surveys to cohorts (but it must be a [non-behavioral one](/docs/feature-flags/common-questions#why-cant-i-use-a-cohort-with-behavioral-filters-in-my-feature-flag)).
|
||||
|
||||
- **URL targeting:** Show when URL either contains a string, exactly matches a string, matches a regex. The URL targeting is evaluated against `window.location.href`.
|
||||
- **URL targeting:** Show when URL either contains a string, exactly matches a string, matches a regex. The URL targeting is evaluated against `window.location.href`.
|
||||
|
||||
- **Device types targeting:** Show when the device type either contains a string, exactly matches a string or matches a regex. The device type targeting is evaluated by parsing the [userAgent](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent) on the client-side, possible values are: Desktop, Mobile, Tablet, Console, and Wearable. You can also target device types using *Person and group properties* (Latest or Initial Device type), but these properties aren't immediately available on the first page load for unidentified persons. Only available from posthog-js version 1.214.0 forward.
|
||||
- **Device types targeting:** Show when the device type either contains a string, exactly matches a string or matches a regex. The device type targeting is evaluated by parsing the [userAgent](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent) on the client-side, possible values are: Desktop, Mobile, Tablet, Console, and Wearable. You can also target device types using _Person and group properties_ (Latest or Initial Device type), but these properties aren't immediately available on the first page load for unidentified persons. Only available from posthog-js version 1.214.0 forward.
|
||||
|
||||
- **Selector matches:** Whether a specific element exists or appears on the page with the specified class name or ID. For example, you can display a survey with `#my-button` or `.my-button` selector. This is useful for showing a survey after a user action.
|
||||
- **Selector matches:** Whether a specific element exists or appears on the page with the specified class name or ID. For example, you can display a survey with `#my-button` or `.my-button` selector. This is useful for showing a survey after a user action.
|
||||
|
||||
- **Wait period**: Hide surveys from users who have seen any survey in the last X days. A user who completes a survey are never shown the same survey again, even if no wait period is set ([but there are exceptions to this rule](#repeating-surveys)).
|
||||
- **Wait period**: Hide surveys from users who have seen any survey in the last X days. A user who completes a survey are never shown the same survey again, even if no wait period is set ([but there are exceptions to this rule](#repeating-surveys)).
|
||||
|
||||
- **Person and group properties:** If you are capturing identified events, you can display a survey to users who have specific [person](/docs/product-analytics/person-properties) or [group properties](/docs/product-analytics/group-analytics#how-to-set-group-properties). For example, you can target a survey to users who have a property `is_paying=true`. This also includes a percentage rollout option. The person and group properties are evaluated with internal feature flags.
|
||||
- **Person and group properties:** If you are capturing identified events, you can display a survey to users who have specific [person](/docs/product-analytics/person-properties) or [group properties](/docs/product-analytics/group-analytics#how-to-set-group-properties). For example, you can target a survey to users who have a property `is_paying=true`. This also includes a percentage rollout option. The person and group properties are evaluated with internal feature flags.
|
||||
|
||||
- **User sends events:** Display a survey to users who have sent a specific event during their session.
|
||||
- **User sends events:** Display a survey to users who have sent a specific event during their session.
|
||||
|
||||
<ProductScreenshot
|
||||
imageLight={displayConditionsLight}
|
||||
@@ -174,7 +181,6 @@ You can display your survey to specific users based on:
|
||||
classes="rounded"
|
||||
/>
|
||||
|
||||
|
||||
### Completion conditions
|
||||
|
||||
This enables you to stop your survey once you receive a specific number of responses. Note that because it takes time for PostHog to process responses, this is a rough guideline. Your survey might receive slightly more responses than you set. The completion conditions properties are evaluated with internal feature flags.
|
||||
@@ -196,13 +202,12 @@ If you want to trigger a survey on a specific event, but only show it once per u
|
||||
classes="rounded"
|
||||
/>
|
||||
|
||||
|
||||
### Complete conditions
|
||||
|
||||
Under complete conditions, there's two options that can be configured so the survey is shown again:
|
||||
|
||||
- `Repeat on a schedule`
|
||||
- `Every time the display conditions are met`
|
||||
- `Repeat on a schedule`
|
||||
- `Every time the display conditions are met`
|
||||
|
||||
#### Repeat on a schedule
|
||||
|
||||
@@ -216,18 +221,19 @@ You can also configure in-app surveys to repeat at specific intervals, which is
|
||||
/>
|
||||
|
||||
For example, you can configure settings like:
|
||||
- **Repeat this survey `3` times, once every `30` days**: The survey will be shown to a user up to 3 times total, with a 30-day gap between each showing.
|
||||
|
||||
| Date | Event | Explanation |
|
||||
|------|-------|-------------|
|
||||
| Jan 1 | Survey shown and completed | First showing of the survey. User completes it, starting the 30-day timer |
|
||||
| Jan 2-30 | No survey shown | Within 30-day waiting period after first completion |
|
||||
| Jan 31 | Survey becomes eligible | 30 days have passed since first completion |
|
||||
| Feb 15 | Survey shown and completed | User visits site and completes survey for the second time |
|
||||
| Feb 16-Mar 16 | No survey shown | Within 30-day waiting period after second completion |
|
||||
| Mar 17 | Survey becomes eligible | 30 days have passed since second completion |
|
||||
| Apr 1 | Survey shown and completed | User completes survey for the third and final time |
|
||||
| After Apr 1 | Survey never shown again for this user | Maximum number of repetitions (3) reached |
|
||||
- **Repeat this survey `3` times, once every `30` days**: The survey will be shown to a user up to 3 times total, with a 30-day gap between each showing.
|
||||
|
||||
| Date | Event | Explanation |
|
||||
| ------------- | -------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| Jan 1 | Survey shown and completed | First showing of the survey. User completes it, starting the 30-day timer |
|
||||
| Jan 2-30 | No survey shown | Within 30-day waiting period after first completion |
|
||||
| Jan 31 | Survey becomes eligible | 30 days have passed since first completion |
|
||||
| Feb 15 | Survey shown and completed | User visits site and completes survey for the second time |
|
||||
| Feb 16-Mar 16 | No survey shown | Within 30-day waiting period after second completion |
|
||||
| Mar 17 | Survey becomes eligible | 30 days have passed since second completion |
|
||||
| Apr 1 | Survey shown and completed | User completes survey for the third and final time |
|
||||
| After Apr 1 | Survey never shown again for this user | Maximum number of repetitions (3) reached |
|
||||
|
||||
A survey is considered "shown" when a user either completes or dismisses it. The repeat interval timer starts from that moment. For example, if you set a survey to repeat every 90 days and a user completes it on January 1st, they won't see it again until April 1st, regardless of how many times they visit your site in between.
|
||||
|
||||
@@ -268,7 +274,7 @@ You can enable partial responses in the "Completion conditions" section of the s
|
||||
If partial responses are enabled, PostHog tracks user progress as follows:
|
||||
|
||||
1. **Initial Response:** The first `survey sent` event is triggered as soon as the user answers at least one question. This initial event includes the answer(s) provided up to that point. The `$survey_completed` property in this event will be `false`.
|
||||
2. **Subsequent Responses:** For each *additional* question the user answers, another `survey sent` event is captured. Each of these events will contain *all* responses submitted by the user for that survey instance up to that point, and `$survey_completed` will remain `false`.
|
||||
2. **Subsequent Responses:** For each _additional_ question the user answers, another `survey sent` event is captured. Each of these events will contain _all_ responses submitted by the user for that survey instance up to that point, and `$survey_completed` will remain `false`.
|
||||
3. **Full Completion:** When the user fully completes and submits the survey, a final `survey sent` event is sent. This event will again include all their answers, and the `$survey_completed` property will now be `true`.
|
||||
|
||||
**The `$survey_submission_id`:**
|
||||
|
||||
@@ -132,7 +132,7 @@ export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-3 sm:mb-8 lg:mb-2">Recommended by the world's leading startup accelerators</h3>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-primary/75 dark:text-primary-dark/75 text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-secondary text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
<div class="flex justify-center">
|
||||
<ul class="m-0 p-0 list-none inline-grid sm:grid-cols-3 lg:grid-cols-3 justify-evenly relative text-center sm:text-left">
|
||||
<li class="relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8">
|
||||
@@ -161,71 +161,71 @@ export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.
|
||||
<div className="overflow-x-auto -mx-5 flex justify-start lg:justify-center px-4 lg:px-0">
|
||||
<table className="w-400 mt-4" style="max-width: 1100px; font-size: 15px;">
|
||||
<thead>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td className="w-3/12"></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-pendo">Pendo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-amplitude">Amplitude</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-mixpanel">Mixpanel</a></td>
|
||||
<td className="w-2/12 text-center bg-accent dark:bg-accent-dark"><strong>PostHog</strong></td>
|
||||
<td className="w-2/12 text-center bg-accent"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Eligibility criteria</strong></td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center"><$5m in funding and <20 staff members</td>
|
||||
<td className="text-center"><$8m in funding and less than 5 years old</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><$5m in funding and less than 2 years old</td>
|
||||
<td className="bg-accent text-center"><$5m in funding and less than 2 years old</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Limitations</strong></td>
|
||||
<td className="text-center">500 monthly users</td>
|
||||
<td className="text-center">1,000 monthly sessions</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">One year duration</td>
|
||||
<td className="bg-accent text-center">One year duration</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Benefits</strong></td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">200,000 MTUs</td>
|
||||
<td className="text-center">$50,000 credit</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">$50,000 credit</td>
|
||||
<td className="bg-accent text-center">$50,000 credit</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Open source product</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Free gifts (incl. stickers)</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Partnership opportunities</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<tr class="border-b border-primary">
|
||||
<td><strong>Referral bonuses</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -137,74 +137,74 @@ On July 1st 2023, Google sunset Universal Analytics and forced users to beging u
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td className="w-1/12"></td>
|
||||
<td className="w-1/12 text-center"><strong>Google Analytics (GA4)</strong></td>
|
||||
<td className="w-1/12 text-center bg-gray-accent bg-opacity-50"><strong>PostHog</strong></td>
|
||||
<td className="w-1/12 text-center bg-accent bg-opacity-50"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Free to get started</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Open source platform</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>GDPR ready</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Events-based tracking</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Website analytics</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Dashboard and report templates</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Funnels analysis</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Path templates</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>SQL access</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>A/B experimentation</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Session replays</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Feature flags</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr style="border-bottom: 1px dashed; border-color: #bfbfbc">
|
||||
<td><strong>Requires 3rd party cookies</strong></td>
|
||||
<td className="text-center"><span className="text-green text-lg">✔</span></td>
|
||||
<td className="bg-gray-accent bg-opacity-50 text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent bg-opacity-50 text-center"><span className="text-red text-lg">✖</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -6,27 +6,27 @@ showTitle: true
|
||||
|
||||
We run two special programs for early-stage teams. The primary place for discussing both programs is the [#project-startups-and-yc](https://posthog.slack.com/archives/C088RSQKH2T) channel in Slack.
|
||||
|
||||
| Feature | Startups | Y Combinator |
|
||||
|----------------------------|-------------------------------|----------------------------------|
|
||||
| Eligibility | <2 years old, <$5M raised | Must be in YC (any batch) |
|
||||
| Credit | $50,000 for 12 months | $50k (recent batches) or $25k |
|
||||
| Can use credit for add-ons? | ⚠️ Yes, but cannot use credit for BAA in Boost add-on | ✅ Yes, and can use credit for BAA in Boost add-on |
|
||||
| Founder merch | Welcome pack (max 1) | Different welcome pack (max 4) |
|
||||
| Community | — | Private YC founder Slack |
|
||||
| Apply via… | [Startup page](/startups) | [Secret YC page](https://app.posthog.com/startups/yc) |
|
||||
| Feature | Startups | Y Combinator |
|
||||
| --------------------------- | ----------------------------------------------------- | ----------------------------------------------------- |
|
||||
| Eligibility | <2 years old, <$5M raised | Must be in YC (any batch) |
|
||||
| Credit | $50,000 for 12 months | $50k (recent batches) or $25k |
|
||||
| Can use credit for add-ons? | ⚠️ Yes, but cannot use credit for BAA in Boost add-on | ✅ Yes, and can use credit for BAA in Boost add-on |
|
||||
| Founder merch | Welcome pack (max 1) | Different welcome pack (max 4) |
|
||||
| Community | — | Private YC founder Slack |
|
||||
| Apply via… | [Startup page](/startups) | [Secret YC page](https://app.posthog.com/startups/yc) |
|
||||
|
||||
## PostHog for Startups
|
||||
|
||||
Any company that is <2 years old and has raised less than $5M in funding is eligible to apply and claim the following:
|
||||
|
||||
- $50,000 in PostHog credits (valid for 12 months)
|
||||
- One unique welcome pack for founders
|
||||
- Partner benefits with Speakeasy and Mintlify (50% off for 6 months)
|
||||
- A monthly newsletter for founders
|
||||
- $50,000 in PostHog credits (valid for 12 months)
|
||||
- One unique welcome pack for founders
|
||||
- Partner benefits with Speakeasy and Mintlify (50% off for 6 months)
|
||||
- A monthly newsletter for founders
|
||||
|
||||
> ❗Credits **cannot** be used toward a BAA under the Boost plan.
|
||||
|
||||
All applications are **automatically approved**, then **manually reviewed** for eligibility.
|
||||
All applications are **automatically approved**, then **manually reviewed** for eligibility.
|
||||
|
||||
We track all PostHog for Startups applications in [this Zapier table](http://tables.zapier.com/app/tables/t/01JRARGWTSDYCGNS12HXN3B6DY).
|
||||
|
||||
@@ -34,13 +34,13 @@ We track all PostHog for Startups applications in [this Zapier table](http://tab
|
||||
|
||||
This program is similar to our startup program but has some key differences for YC teams. Teams can be in any YC batch, with any amount of funding raised, and can claim the following:
|
||||
|
||||
- A variable amount of PostHog credit:
|
||||
- $50,000 for teams in the current, upcoming, or last 4 YC batches
|
||||
- $25,000 for older batches
|
||||
- Up to 4 unique founder merch packs (different from the startup program)
|
||||
- Access to [our private YC Founder Slack](https://posthog.slack.com/archives/C04J1TJ11UZ)
|
||||
- Partner benefits with Speakeasy and Mintlify (50% off for 6 months)
|
||||
- A monthly founder newsletter
|
||||
- A variable amount of PostHog credit:
|
||||
- $50,000 for teams in the current, upcoming, or last 4 YC batches
|
||||
- $25,000 for older batches
|
||||
- Up to 4 unique founder merch packs (different from the startup program)
|
||||
- Access to [our private YC Founder Slack](https://posthog.slack.com/archives/C04J1TJ11UZ)
|
||||
- Partner benefits with Speakeasy and Mintlify (50% off for 6 months)
|
||||
- A monthly founder newsletter
|
||||
|
||||
> ✅ Credits **can** be used to claim a BAA under the Boost plan.
|
||||
|
||||
@@ -67,10 +67,10 @@ We track all PostHog for YC applications in [this Zapier table](https://tables.z
|
||||
~12 hours later, a third email (via [Customer.io](https://fly.customer.io/workspaces/127208/journeys/composer/actions/2185)) is sent by [Joe](community/profiles/29070) welcoming them and explaining perks.
|
||||
|
||||
6. **Milestones**
|
||||
When teams reach 50%, 75%, or 100% of their credit usage — or when credits expire — they receive milestone emails. These come from Customer.io and are managed by [Joe](community/profiles/29070).
|
||||
When teams reach 50%, 75%, or 100% of their credit usage — or when credits expire — they receive milestone emails. These come from Customer.io and are managed by [Joe](community/profiles/29070).
|
||||
|
||||
7. **Post-credit**
|
||||
Once credit is fully used or expired, teams are moved to a standard paid plan automatically.
|
||||
Once credit is fully used or expired, teams are moved to a standard paid plan automatically.
|
||||
We automatically email users to let them know and offer a one-time $500 credit bonus to help soften the transition.
|
||||
|
||||
## Reviewing applications
|
||||
@@ -82,10 +82,10 @@ If we don’t hear back in a week or confirm ineligibility, we remove the credit
|
||||
|
||||
All merch is fulfilled through the [PostHog store](/merch) by Micromerch.
|
||||
|
||||
- Founders receive unique codes via email to claim merch.
|
||||
- They can request up to 4 merch packs for co-founders during signup.
|
||||
- If a team has more than 4 founders, they can [submit a support ticket](http://app.posthog.com/home#supportModal) to request more.
|
||||
- Additional merch is occasionally granted at our discretion.
|
||||
- Founders receive unique codes via email to claim merch.
|
||||
- They can request up to 4 merch packs for co-founders during signup.
|
||||
- If a team has more than 4 founders, they can [submit a support ticket](http://app.posthog.com/home#supportModal) to request more.
|
||||
- Additional merch is occasionally granted at our discretion.
|
||||
|
||||
Issues? Reach out in [#merch Slack](https://posthog.slack.com/archives/C04DWKH7DM3). Founders can also email [merch@posthog.com](mailto:merch@posthog.com).
|
||||
|
||||
@@ -95,10 +95,10 @@ We send a short, founder-focused newsletter once per month to all program partic
|
||||
|
||||
## Credit usage
|
||||
|
||||
Credits can be used for almost all PostHog products and add-ons, including [platform add-ons](/platform-addons).
|
||||
Credits can be used for almost all PostHog products and add-ons, including [platform packages](/platform-packages).
|
||||
|
||||
- **Startups**: ❌ Cannot use credits toward a BAA due to legal risk.
|
||||
- **YC teams**: ✅ Can use credits for a BAA under the Boost plan.
|
||||
- **Startups**: ❌ Cannot use credits toward a BAA due to legal risk.
|
||||
- **YC teams**: ✅ Can use credits for a BAA under the Boost plan.
|
||||
|
||||
Credits are valid are not transferable, and don’t carry over or convert to cash. They are valid for 12 months and that timer begins at application. Once expired or fully used, teams are moved to standard billing.
|
||||
|
||||
@@ -106,22 +106,23 @@ Credits are valid are not transferable, and don’t carry over or convert to cas
|
||||
|
||||
We currently partner with:
|
||||
|
||||
- **Mintlify** — 50% off for 6 months
|
||||
- **Speakeasy** — 50% off for 6 months
|
||||
- **Mintlify** — 50% off for 6 months
|
||||
- **Speakeasy** — 50% off for 6 months
|
||||
|
||||
Discount codes are sent in the welcome email after signup.
|
||||
|
||||
If users run into issues with redemption, we can help liaise — though all offers are ultimately at partner discretion.
|
||||
|
||||
Contacts:
|
||||
- Mintlify: Tiffany Chen
|
||||
- Speakeasy: Nolan Di Mare Sullivan
|
||||
|
||||
- Mintlify: Tiffany Chen
|
||||
- Speakeasy: Nolan Di Mare Sullivan
|
||||
|
||||
We previously offered DigitalOcean credits ($25k), but this was retired in Q2 2025.
|
||||
|
||||
## Program extensions
|
||||
|
||||
We don’t usually extend credits — the 12-month window is intended to be firm and fair. However, we’re open to requests in exceptional cases.
|
||||
We don’t usually extend credits — the 12-month window is intended to be firm and fair. However, we’re open to requests in exceptional cases.
|
||||
|
||||
Founders must clearly explain why they couldn’t use the credit in time and provide evidence of recent progress or changes. Requests are reviewed manually by the Customer Success team.
|
||||
|
||||
|
||||
@@ -69,14 +69,14 @@ Fonts are hosted outside of our posthog.com GitHub repo (due to licensing reason
|
||||
|
||||
Restricted to PostHog employees, it's possible to reference the font locally to see an exact replication of what will be published on posthog.com.
|
||||
|
||||
[Layout.scss](https://github.com/PostHog/posthog.com/blob/master/src/components/Layout/Layout.scss) contains some commented out code which can be used, in conjunction with the [variable webfont files](https://github.com/PostHog/company-internal/blob/master/MatterSQVF.zip) (restricted to PostHog organization members). Here's how to use them:
|
||||
[global.css](https://github.com/PostHog/posthog.com/blob/master/src/styles.css) contains some commented out code which can be used, in conjunction with the [variable webfont files](https://github.com/PostHog/company-internal/blob/master/MatterSQVF.zip) (restricted to PostHog organization members). Here's how to use them:
|
||||
|
||||
1. Download the webfont files from the zip above
|
||||
1. Extract the files and place them in `/public/fonts`
|
||||
1. In `Layout.scss`, comment out the `src` for both fonts with production (Cloudfront) URLs and uncomment the relative URLs.
|
||||
1. In `global.css`, comment out the `src` for both fonts with production (Cloudfront) URLs and uncomment the relative URLs.
|
||||
1. Optionally use `.gitignore` to keep the files locally without inadvertently checking them in
|
||||
|
||||
Note: When submitting a PR, be sure to revert changes made to `Layout.scss`
|
||||
Note: When submitting a PR, be sure to revert changes made to `global.css`
|
||||
|
||||
### Designing on desktop
|
||||
|
||||
|
||||
@@ -9,29 +9,35 @@ Many customers have never spoken to PostHog – some happily welcome our help, o
|
||||
[Get people to talk to you](/handbook/growth/sales/expansion-and-retention#1-get-people-to-talk-to-you) also has good helpful tactics.
|
||||
|
||||
# Introduce yourself
|
||||
You likely won't have an established contact so introduce yourself to the widest blast range: org owner, org admin, users who have recently raised tickets, and users who have logged in in the last month. Even if there *seems* to be a point of contact, things probably changed – multi-thread!
|
||||
|
||||
Your intro message should:
|
||||
- Introduce yourself as their new CSM
|
||||
- Describe value of CSM – dedicated point of contact, go-to person for help or questions, help customer use PostHog effectively e.g. through training or strategic guidance. Many customers misunderstand the CSM role as 'just support', so make sure to distinguish your role as CSM apart from that.
|
||||
- Value nugget: show how you can help by delivering value-add
|
||||
You likely won't have an established contact so introduce yourself to the widest blast range: org owner, org admin, users who have recently raised tickets, and users who have logged in in the last month. Even if there _seems_ to be a point of contact, things probably changed – multi-thread!
|
||||
|
||||
Your intro message should:
|
||||
|
||||
- Introduce yourself as their new CSM
|
||||
- Describe value of CSM – dedicated point of contact, go-to person for help or questions, help customer use PostHog effectively e.g. through training or strategic guidance. Many customers misunderstand the CSM role as 'just support', so make sure to distinguish your role as CSM apart from that.
|
||||
- Value nugget: show how you can help by delivering value-add
|
||||
|
||||
### Examples of a value nugget
|
||||
|
||||
Take a look at your customer's account in Vitally and Metabase to identify ways you can be helpful. Some examples include:
|
||||
- Increase / decrease in events: make sure this is expected and things are implemented correctly
|
||||
- Recently opened a support ticket: follow up to make sure their issue is resolved
|
||||
- Concrete ways a customer can [optimize their spending](/handbook/cs-and-onboarding/health-checks#are-they-paying-for-things-they-dont-need) or [improve their implementation](/handbook/cs-and-onboarding/health-checks#have-they-implemented-tracking-incorrectly)
|
||||
- Invitation to a shared Slack channel so it's easier to connect with our team.
|
||||
- Lots of new users or low user engagement: offer a training session on how to use PostHog effectively
|
||||
- On a legacy pricing plan: "we've moved off legacy plan for more than a year and I'd like to transition you to standard pricing. Happy to discuss the changes"
|
||||
|
||||
- Increase / decrease in events: make sure this is expected and things are implemented correctly
|
||||
- Recently opened a support ticket: follow up to make sure their issue is resolved
|
||||
- Concrete ways a customer can [optimize their spending](/handbook/cs-and-onboarding/health-checks#are-they-paying-for-things-they-dont-need) or [improve their implementation](/handbook/cs-and-onboarding/health-checks#have-they-implemented-tracking-incorrectly)
|
||||
- Invitation to a shared Slack channel so it's easier to connect with our team.
|
||||
- Lots of new users or low user engagement: offer a training session on how to use PostHog effectively
|
||||
- On a legacy pricing plan: "we've moved off legacy plan for more than a year and I'd like to transition you to standard pricing. Happy to discuss the changes"
|
||||
|
||||
If there's an established Slack channel you are inheriting, do it in Slack.
|
||||
|
||||
### Example subject lines:
|
||||
### Example subject lines:
|
||||
|
||||
You should find what you're comfortable with whilst keeping a sense of PostHog's tone of voice. Some examples include:
|
||||
- Hello 👋 from your new CSM at PostHog + hook
|
||||
- hi from PostHog
|
||||
- Checking in from PostHog
|
||||
|
||||
- Hello 👋 from your new CSM at PostHog + hook
|
||||
- hi from PostHog
|
||||
- Checking in from PostHog
|
||||
|
||||
In Vitally, you can see how other team members have reached out to customers in the past by going to an account's Active conversations tab for inspiration.
|
||||
|
||||
@@ -53,9 +59,9 @@ Aim: establish long term relationship, point of contact
|
||||
|
||||
Call structure:
|
||||
|
||||
1. Understand customer’s PostHog usage:
|
||||
1. Understand customer’s PostHog usage:
|
||||
1. What products are they using? How are they using it? What metrics do they care about from those products?
|
||||
2. What products are they **not** using? This has to be products that would make sense for them to use and you want to understand why they aren’t using it.
|
||||
2. What products are they **not** using? This has to be products that would make sense for them to use and you want to understand why they aren’t using it.
|
||||
1. For example, product analytics and web analytics are closely coupled. If customer is using product analytics but not web analytics, understand why. Is there a reason for that? What’s the objection?
|
||||
2. Call out feature preview ✨
|
||||
1. Explain what feature preview is and how to enable them
|
||||
@@ -66,10 +72,10 @@ Call structure:
|
||||
|
||||
# Customer Prioritization
|
||||
|
||||
- Consider a separate approach for monthly and annual customers:
|
||||
- Annual plans: prioritize accounts with contract renewals in the next 3-4 months
|
||||
- Monthly plans: look for significant growth within the last quarter
|
||||
- Accounts with platform add-ons
|
||||
- Customers on legacy "Teams" add-on ($450/month) could save $200 by switching to the "Boost" add-on if they do not require SAML SSO or managed reserve proxy. The teams add-on has now been split into:
|
||||
- [Boost add-on](/platform-addons#boost-add-on) ($250/month)
|
||||
- [Scale add-on](/platform-addons#scale-add-on) ($750/month)
|
||||
- Consider a separate approach for monthly and annual customers:
|
||||
- Annual plans: prioritize accounts with contract renewals in the next 3-4 months
|
||||
- Monthly plans: look for significant growth within the last quarter
|
||||
- Accounts with platform packages
|
||||
- Customers on legacy "Teams" add-on ($450/month) could save $200 by switching to the "Boost" add-on if they do not require SAML SSO or managed reserve proxy. The teams add-on has now been split into:
|
||||
- [Boost add-on](/platform-packages#boost-add-on) ($250/month)
|
||||
- [Scale add-on](/platform-packages#scale-add-on) ($750/month)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
title: How PostHog.com works
|
||||
sidebar: Handbook
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
PostHog.com is built and maintained in-house by the [Brand & Vibes team](/teams/brand-vibes).
|
||||
|
||||
| Service | Purpose |
|
||||
|--- |--- |
|
||||
| Vercel | Hosting |
|
||||
| Gatsby | Static site framework |
|
||||
| GitHub | Source code repository |
|
||||
| Ashby (API) | Applicant tracking system |
|
||||
| Algolia (API) | Site search |
|
||||
| Strapi | Headless CMS |
|
||||
| PostHog | Analytics, feature flags |
|
||||
| Inkeep | AI-powered community answers |
|
||||
|
||||

|
||||
|
||||
Website content is stored in two places:
|
||||
|
||||
1. Markdown/MDX files (in the [GitHub repo](https://github.com/posthog/posthog.com/)) - _most website content_
|
||||
- Docs, handbook, most pages
|
||||
1. Strapi - _user-generated content_
|
||||
- Community forum posts, community profiles
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: How PostHog.com works
|
||||
sidebar: Handbook
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
PostHog.com is built and maintained in-house by the <SmallTeam slug="brand-vibes" />. You've probably never seen a Gatsby.js site like this before. <TeamMember name="Eli Kinsey" photo /> is the mastermind behind how the site is structured.
|
||||
|
||||
For more context, [read why we designed our website to look like an operating system](/blog/why-os).
|
||||
|
||||
## The "operating system"
|
||||
|
||||
1. At the top level, `gatsby-browser.tsx` loads `<Wrapper />`
|
||||
1. `<Wrapper />` renders the chrome of the "operating system"
|
||||
1. `<TaskBarMenu />` – the MacOS-style menu bar
|
||||
1. `<Desktop />` – the desktop app icons and desktop background
|
||||
1. `<AppWindow />` – the chrome for each app and where the content renders
|
||||
1. `<CookieBannerToast />`
|
||||
1. `<AppWindow />` loads `<WindowProvider />` and `<WindowContainer />`.
|
||||
- This contains the window's top bar with the minimize, maximize, and close buttons. It also supports window resizing.
|
||||
- Inside here is where the contents of each app renders
|
||||
|
||||
## The apps
|
||||
|
||||
Each "app" is simply a page like a normal Gatsby site. There are a handful of apps:
|
||||
|
||||
1. `<ReaderView />` – used for all long-form content like the docs, handbook, blog
|
||||
1. `<Editor />` – a WYSIWYG page editor
|
||||
1. `<Explorer />` – an OS-style file explorer
|
||||
1. `<Inbox />` – an email-like app
|
||||
1. `<Presentation />` – a slide deck
|
||||
|
||||
Each app can reference shared components like `<HeaderBar />` which contains the necessary navigational elements (like the back button, search, and filters).
|
||||
|
||||
Let's look at a product page to see how it uses the `<Presentation />` template.
|
||||
|
||||
### Example: `posthog.com/session-replay`
|
||||
|
||||
This page (`/src/pages/session-replay/index.tsx`) includes two critical pieces:
|
||||
|
||||
1. `<SlidesTemplate />` – the views where the content will display
|
||||
1. Defines the `PRODUCT_HANDLE`
|
||||
1. Specifies which slides should appear in this presentation using `createSlideConfig`
|
||||
|
||||
`<SlidesTemplate />` loads up all the various templates needed (like `<OverviewComponent />`, `<CustomersSlide />`, `<FeaturesSlide />`) and sources the content using the `useProduct` hook.
|
||||
|
||||
**`useProduct`** hook
|
||||
|
||||
Each product's data is defined in a JSON file like:
|
||||
|
||||
**`/src/hooks/productData/session_replay.tsx`**
|
||||
|
||||
When the `session_replay` handle is passed into `useProduct`, it looks up the product's data like:
|
||||
|
||||
- icon
|
||||
- color
|
||||
- category
|
||||
- SEO data
|
||||
- screenshots array
|
||||
- feature customers
|
||||
- features array
|
||||
- feature comparison chart
|
||||
- etcc
|
||||
|
||||
> Note: The <SmallTeam slug="billing" /> maintains a billing API that contains pricing tiers and entitlements. This is how pricing data and usage tiers stay in sync between the website and product. The plan is to eventually move the product data into the billing API so there's a single source of truth for every product.
|
||||
|
||||
---
|
||||
|
||||
## Services we use
|
||||
|
||||
| Service | Purpose |
|
||||
| ------------- | ------------------------------------------------------ |
|
||||
| Vercel | Hosting |
|
||||
| Gatsby | Static site framework |
|
||||
| GitHub | Source code repository |
|
||||
| Ashby (API) | Applicant tracking system |
|
||||
| Algolia (API) | Site search |
|
||||
| Strapi | Headless CMS for community profiles and changelog data |
|
||||
| PostHog | Analytics, feature flags |
|
||||
| Inkeep | AI-powered community answers |
|
||||
|
||||

|
||||
|
||||
Website content is stored in two places:
|
||||
|
||||
1. Markdown/MDX files (in the [GitHub repo](https://github.com/posthog/posthog.com/)) - _most website content_
|
||||
- Docs, handbook, most pages
|
||||
1. Strapi - _user-generated content_
|
||||
- Community forum posts, community profiles
|
||||
@@ -14,9 +14,9 @@ You use it by passing image URLs to the `imageLight` and `imageDark` props like
|
||||
|
||||
```
|
||||
<ProductScreenshot
|
||||
imageLight="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/handbook/images/tutorials/limit-session-recordings/sampling-config-light.png"
|
||||
imageDark="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/handbook/images/tutorials/limit-session-recordings/sampling-config-dark.png"
|
||||
alt="Sampling config shown set to 100% i.e. no sampling"
|
||||
imageLight="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/handbook/images/tutorials/limit-session-recordings/sampling-config-light.png"
|
||||
imageDark="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/handbook/images/tutorials/limit-session-recordings/sampling-config-dark.png"
|
||||
alt="Sampling config shown set to 100% i.e. no sampling"
|
||||
classes="rounded"
|
||||
/>
|
||||
```
|
||||
@@ -47,45 +47,45 @@ Th `<ProductVideo />` component works the same as product screenshots (above) bu
|
||||
|
||||
1. Import the video(s) at the top of the post (directly following the MDX file's frontmatter and dashes):
|
||||
|
||||
```
|
||||
---
|
||||
```
|
||||
---
|
||||
export const NewFunnelLight = "https://res.cloudinary.com/dmukukwp6/video/upload/posthog.com/contents/handbook/images/docs/user-guides/funnels/new-funnel.mp4"
|
||||
export const NewFunnelDark = "https://res.cloudinary.com/dmukukwp6/video/upload/posthog.com/contents/handbook/images/docs/user-guides/funnels/new-funnel-dark.mp4"
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
1. Use the component wherever you want the video(s) to appear.
|
||||
|
||||
```
|
||||
<ProductVideo
|
||||
videoLight={NewFunnelLight}
|
||||
videoDark={NewFunnelDark}
|
||||
classes="rounded"
|
||||
/>
|
||||
```
|
||||
```
|
||||
<ProductVideo
|
||||
videoLight={NewFunnelLight}
|
||||
videoDark={NewFunnelDark}
|
||||
classes="rounded"
|
||||
/>
|
||||
```
|
||||
|
||||
_Note: If you don't have a dark video, just leave out the `videoDark` prop and the light video will be used for both color modes._
|
||||
_Note: If you don't have a dark video, just leave out the `videoDark` prop and the light video will be used for both color modes._
|
||||
|
||||
## Codeblocks
|
||||
|
||||
The PostHog website has a custom codeblock component that comes with a number of useful features built-in:
|
||||
|
||||
- [Syntax highDarking](#adding-syntax-highlighting)
|
||||
- [Multiple snippets in a single codeblock](#multiple-code-snippets-in-one-block)
|
||||
- [Specifying which file a snippet is from](#specifying-which-file-a-snippet-is-from)
|
||||
- [Syntax highDarking](#adding-syntax-highlighting)
|
||||
- [Multiple snippets in a single codeblock](#multiple-code-snippets-in-one-block)
|
||||
- [Specifying which file a snippet is from](#specifying-which-file-a-snippet-is-from)
|
||||
|
||||
### Basic codeblock
|
||||
|
||||
Codeblocks in PostHog are created by enclosing your snippet using three backticks (\`\`\`) or three tildes (\~\~\~), as shown below:
|
||||
|
||||
~~~mdx
|
||||
````mdx
|
||||
```
|
||||
{
|
||||
"name": "Max, Hedgehog in Residence",
|
||||
"age": 2
|
||||
}
|
||||
```
|
||||
~~~
|
||||
````
|
||||
|
||||
This will produce the following codeblock:
|
||||
|
||||
@@ -100,14 +100,14 @@ This will produce the following codeblock:
|
||||
|
||||
Syntax highlighting can be added by specifying a language for the codeblock, which is done by appending the name of the language directly after the opening backticks or tildes as shown below.
|
||||
|
||||
~~~mdx
|
||||
````mdx
|
||||
```json
|
||||
{
|
||||
"name": "Max, Hedgehog in Residence",
|
||||
"age": 2
|
||||
}
|
||||
```
|
||||
~~~
|
||||
````
|
||||
|
||||
This will produce the following output:
|
||||
|
||||
@@ -124,57 +124,56 @@ Here is a list of all the languages that are supported in codeblocks:
|
||||
|
||||
##### Frontend
|
||||
|
||||
| | |
|
||||
| -- | -- |
|
||||
| HTML | `html` |
|
||||
| | |
|
||||
| ----------------- | -------------- |
|
||||
| HTML | `html` |
|
||||
| CSS / SCSS / LESS | `css` / `less` |
|
||||
| JavaScript | `js` |
|
||||
| JSX | `jsx` |
|
||||
| TypeScript | `ts` |
|
||||
| TSX | `tsx` |
|
||||
| Swift | `swift` |
|
||||
| Dart | `dart` |
|
||||
| Objective-C | `objectivec` |
|
||||
| JavaScript | `js` |
|
||||
| JSX | `jsx` |
|
||||
| TypeScript | `ts` |
|
||||
| TSX | `tsx` |
|
||||
| Swift | `swift` |
|
||||
| Dart | `dart` |
|
||||
| Objective-C | `objectivec` |
|
||||
|
||||
##### Backend
|
||||
|
||||
| | |
|
||||
| -- | -- |
|
||||
| Node.js | `node` |
|
||||
| Elixir | `elixir` |
|
||||
| Golang | `go` |
|
||||
| Java | `java` |
|
||||
| PHP | `php` |
|
||||
| Ruby | `ruby` |
|
||||
| Python | `python` |
|
||||
| C / C++ | `c` / `cpp`
|
||||
| | |
|
||||
| ------- | ----------- |
|
||||
| Node.js | `node` |
|
||||
| Elixir | `elixir` |
|
||||
| Golang | `go` |
|
||||
| Java | `java` |
|
||||
| PHP | `php` |
|
||||
| Ruby | `ruby` |
|
||||
| Python | `python` |
|
||||
| C / C++ | `c` / `cpp` |
|
||||
|
||||
##### Misc.
|
||||
|
||||
| | |
|
||||
| -- | -- |
|
||||
| | |
|
||||
| -------- | ----------------- |
|
||||
| Terminal | `bash` or `shell` |
|
||||
| JSON | `json` |
|
||||
| XML | `xml` |
|
||||
| SQL | `sql` |
|
||||
| GraphQL | `graphql` |
|
||||
| Markdown | `markdown` |
|
||||
| MDX | `mdx` |
|
||||
| YAML | `yaml` |
|
||||
| Git | `git` |
|
||||
| JSON | `json` |
|
||||
| XML | `xml` |
|
||||
| SQL | `sql` |
|
||||
| GraphQL | `graphql` |
|
||||
| Markdown | `markdown` |
|
||||
| MDX | `mdx` |
|
||||
| YAML | `yaml` |
|
||||
| Git | `git` |
|
||||
|
||||
> **Note:** If you want syntax highlighting for a snippet in another language, feel free to add your language to the imports [here](https://github.com/PostHog/posthog.com/blob/149c7c2a99d66c4f961b538edb864c63ce186967/src/components/CodeBlock/languages.tsx#L6) and open a PR.
|
||||
|
||||
|
||||
### Multiple code snippets in one block
|
||||
|
||||
With PostHog's `MultiLanguage` component, it's possible to group multiple code snippets together into a single block.
|
||||
|
||||
~~~mdx
|
||||
````mdx
|
||||
<MultiLanguage>
|
||||
|
||||
```js
|
||||
console.log("Hello world!")
|
||||
console.log('Hello world!')
|
||||
```
|
||||
|
||||
```html
|
||||
@@ -182,7 +181,7 @@ console.log("Hello world!")
|
||||
```
|
||||
|
||||
</MultiLanguage>
|
||||
~~~
|
||||
````
|
||||
|
||||
> **Note:** Make sure to include empty lines between all your code snippets, as well as above and below the `MultiLanguage` tag
|
||||
|
||||
@@ -191,7 +190,7 @@ This will render the following codeblock:
|
||||
<MultiLanguage>
|
||||
|
||||
```js
|
||||
console.log("Hello world!")
|
||||
console.log('Hello world!')
|
||||
```
|
||||
|
||||
```html
|
||||
@@ -204,7 +203,7 @@ console.log("Hello world!")
|
||||
|
||||
You can specify a filename that a code snippet belongs to using the `file` parameter, which will be displayed in the top bar of the block.
|
||||
|
||||
~~~mdx
|
||||
````mdx
|
||||
```yaml file=values.yaml
|
||||
cloud: 'aws'
|
||||
ingress:
|
||||
@@ -214,7 +213,7 @@ ingress:
|
||||
cert-manager:
|
||||
enabled: true
|
||||
```
|
||||
~~~
|
||||
````
|
||||
|
||||
> **Note:** Make sure **not** to surround your filename in quotes. Each parameter-value pair is delimited by spaces.
|
||||
|
||||
@@ -242,11 +241,10 @@ Use Markdown's standard syntax for linking internally.
|
||||
|
||||
Be sure to use _relative links_ (exclude `https://posthog.com`) with _absolute paths_ (reference the root of the domain with a preceding `/`).
|
||||
|
||||
| | |
|
||||
|----------- |------------------------------------------ |
|
||||
| **Correct syntax** | `/absolute-path/to/url` |
|
||||
| **Incorrect syntax** | `https://posthog.com/absolute-path/to/url` |
|
||||
|
||||
| | |
|
||||
| -------------------- | ------------------------------------------ |
|
||||
| **Correct syntax** | `/absolute-path/to/url` |
|
||||
| **Incorrect syntax** | `https://posthog.com/absolute-path/to/url` |
|
||||
|
||||
### Linking externally
|
||||
|
||||
@@ -254,8 +252,8 @@ The `<Link />` component is used throughout the site, and is accessible within M
|
||||
|
||||
While that doesn't apply here, using it comes with some handy parameters that you can see in action via the link above:
|
||||
|
||||
- Add `external` to a) open the link in a new tab, and b) add the _external link_ icon (for UX best practices if forcing a link to open in a new window)
|
||||
- If, for some reason, you need to hide the icon, use `externalNoIcon` instead
|
||||
- Add `external` to a) open the link in a new tab, and b) add the _external link_ icon (for UX best practices if forcing a link to open in a new window)
|
||||
- If, for some reason, you need to hide the icon, use `externalNoIcon` instead
|
||||
|
||||
Example:
|
||||
|
||||
@@ -289,21 +287,33 @@ Use this component to mention a team member in a post. It will link to their com
|
||||
|
||||
There's also a `photo` parameter which will inline their photo next to their name like this: <TeamMember name="Cory Watilo" photo />
|
||||
|
||||
## Mention a small team
|
||||
|
||||
Use this component to mention a small team in a post. It will link to their team page and appears like this: <SmallTeam slug="brand-vibes" />
|
||||
|
||||
```
|
||||
<SmallTeam slug="brand-vibes" />
|
||||
```
|
||||
|
||||
The default version shows the team's mini crest and name in a bordered "chip" style. There's also a `noMiniCrest` parameter to omit the mini crest and border for inline usage like this: <SmallTeam slug="brand-vibes" noMiniCrest />
|
||||
|
||||
```
|
||||
<SmallTeam slug="brand-vibes" noMiniCrest />
|
||||
```
|
||||
|
||||
Both versions will show the full team crest on hover. Clicking the tooltip will open the team page in a new window.
|
||||
|
||||
## Embedded posts
|
||||
|
||||
You can embed what looks like ~~a Tweet~~ an X post using the `<Tweet>` component. It's used on the [terms](/terms) and [privacy policy](/privacy) pages, but was componentized for use in blog posts to break up bullet points at the top of the post.
|
||||
|
||||
_Note: This does **not** actually embed an X post; it's just styled to look like one._
|
||||
|
||||
<Tweet
|
||||
alertMessage="Gen Z? Don't get distracted. You're here to read our exciting embedded post component."
|
||||
>
|
||||
<Tweet alertMessage="Gen Z? Don't get distracted. You're here to read our exciting embedded post component.">
|
||||
Here's what a post looks like. It's designed to have a familiar look that makes it easy to scan.
|
||||
</Tweet>
|
||||
|
||||
<Tweet
|
||||
alertMessage="Gen Z? Don't get distracted. You're here to read our exciting embedded post component."
|
||||
>
|
||||
<Tweet alertMessage="Gen Z? Don't get distracted. You're here to read our exciting embedded post component.">
|
||||
If you show multiple posts in a row, they'll be connected by a vertical line to make it look like a thread.
|
||||
</Tweet>
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ Max AI is PostHog's AI-powered platform that lets users interact with PostHog's
|
||||
|
||||
Max AI enables users to:
|
||||
|
||||
- Ask questions about their data in natural language
|
||||
- Generate insights and reports through conversation
|
||||
- Navigate PostHog's products using AI assistance
|
||||
- Automate common analytics tasks
|
||||
- Ask questions about their data in natural language
|
||||
- Generate insights and reports through conversation
|
||||
- Navigate PostHog's products using AI assistance
|
||||
- Automate common analytics tasks
|
||||
|
||||
We want Max to work with _every_ PostHog product, so that we can at some stage make a chat (or even complete automation with approval steps as necessary) the default experience for people using PostHog, then resorting to clicking the UX as the backup option for _most_ tasks.
|
||||
|
||||
@@ -23,17 +23,17 @@ We want Max to work with _every_ PostHog product, so that we can at some stage m
|
||||
|
||||
This naturally distributes AI knowledge throughout the organization, while ensuring high-quality AI features that integrate properly with the platform. Implementing something new, missing features in the Max API, or seeing failures? Your supporting engineer is your go-to! Tag them directly on your PRs and questions.
|
||||
|
||||
**If your team is integrating AI features for the first time – the Max AI team will do their best to assign a supporting engineer.**
|
||||
**If your team is integrating AI features for the first time – the Max AI team will do their best to assign a supporting engineer.**
|
||||
|
||||
Just message about your plans in the #team-max-ai channel in Slack.
|
||||
Just message about your plans in the #team-max-ai channel in Slack.
|
||||
|
||||
| Product | Supporting engineer on the Max AI team |
|
||||
| --- | --- |
|
||||
| Product analytics | <TeamMember name="Emanuele Capparelli" /> |
|
||||
| Data warehouse | <TeamMember name="Michael Matloka" /> |
|
||||
| Session replay | <TeamMember name="Alex Lebedev" /> |
|
||||
| CDP | <TeamMember name="Georgiy Tarasov" /> |
|
||||
| _Insert your team_ | [**Shoot #team-max-ai a message!**](https://posthog.slack.com/archives/C06NZEZ7V3Q) |
|
||||
| Product | Supporting engineer on the Max AI team |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| Product analytics | <TeamMember name="Emanuele Capparelli" photo /> |
|
||||
| Data warehouse | <TeamMember name="Michael Matloka" photo /> |
|
||||
| Session replay | <TeamMember name="Alex Lebedev" photo /> |
|
||||
| CDP | <TeamMember name="Georgiy Tarasov" photo /> |
|
||||
| \[Insert your team] | <PrivateLink url="https://posthog.slack.com/archives/C06NZEZ7V3Q">Shoot #team-max-ai a message!</PrivateLink> |
|
||||
|
||||
### Getting started
|
||||
|
||||
@@ -46,14 +46,14 @@ If you need AI capabilities for your product area:
|
||||
|
||||
### Best practices
|
||||
|
||||
- **Start small**: Begin with simple AI features and iterate based on user feedback. A lot of automation can be broken down into smaller, automatable steps!
|
||||
- **Avoid death by random AI widgets - maintain consistency**: Ensure AI features follow PostHog's design patterns and user experience standards. Max AI team can help if you are missing a UX pattern.
|
||||
- **Start small**: Begin with simple AI features and iterate based on user feedback. A lot of automation can be broken down into smaller, automatable steps!
|
||||
- **Avoid death by random AI widgets - maintain consistency**: Ensure AI features follow PostHog's design patterns and user experience standards. Max AI team can help if you are missing a UX pattern.
|
||||
|
||||
## Resources
|
||||
|
||||
- [Max AI team page](/teams/max-ai)
|
||||
- [Max AI objectives](/teams/max-ai/objectives)
|
||||
- [Max AI documentation](/docs/max-ai)
|
||||
- [Max AI team page](/teams/max-ai)
|
||||
- [Max AI objectives](/teams/max-ai#objectives)
|
||||
- [Max AI documentation](/docs/max-ai)
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ Anyone on a monthly plan simply agrees to our [Terms](/terms) and [Privacy Polic
|
||||
|
||||
While we offer [transparent pricing available to all](/pricing), you can use [QuoteHog](https://quote.posthog.net) (internal only) for customers who need a "formal quote," or who have very high volumes, or otherwise have bespoke needs.
|
||||
|
||||
Sign into QuoteHog via your PostHog Google account/SSO. Upon login, you will see a list of existing quotes, sorted by the created date. You can view a previously created quote or create a new quote using the "New Quote" button at the top right.
|
||||
Sign into QuoteHog via your PostHog Google account/SSO. Upon login, you will see a list of existing quotes, sorted by the created date. You can view a previously created quote or create a new quote using the "New Quote" button at the top right.
|
||||
|
||||
The quoting interface is intuitive and, of course, uses the same pricing we display publicly. Feel free to involve a customer in creating a quote if the opportunity presents itself and you think it would build trust.
|
||||
The quoting interface is intuitive and, of course, uses the same pricing we display publicly. Feel free to involve a customer in creating a quote if the opportunity presents itself and you think it would build trust.
|
||||
|
||||
> Be sure to always click the "Save" button after making changes to a quote. QuoteHog does not autosave.
|
||||
|
||||
@@ -27,9 +27,11 @@ Quotes can be shared externally or embedded in an external source. Clicking the
|
||||
QuoteHog also provides Stripe reported usage and spend for existing customers. To do this, you need to first connect QuoteHog to Salesforce from the [Profile page](https://quote.posthog.net/profile). As you build a quote, click "Add customer info" and search for your customer account. This also allows you to link the quote to an existing Salesforce opportunity.
|
||||
|
||||
When building a quote for an annual plan conversion or renewal, consider:
|
||||
|
||||
1. How is usage trending? Looking at the past 6 month's of usage (usage history tab in Quotehog):
|
||||
- If usage is trending up, calculate the growth rate and project expected volume for a year.
|
||||
- If usage is stable, project based on the latest month's volume or the average or the maximum.
|
||||
|
||||
- If usage is trending up, calculate the growth rate and project expected volume for a year.
|
||||
- If usage is stable, project based on the latest month's volume or the average or the maximum.
|
||||
|
||||
> Note: QuoteHog's input expects monthly volume, so after estimating annual volume, don't forget to convert it to monthly volume.
|
||||
|
||||
@@ -39,17 +41,16 @@ You can create quotes with multiple options: e.g. one based on current usage, on
|
||||
|
||||
The legacy pricing calculator is available [here](https://docs.google.com/spreadsheets/d/1ynNM9tbWsWki2Q0vhwCV0iYNtJ1NHz4eXtUvZDw_sjA/edit?usp=sharing) (internal only).
|
||||
|
||||
|
||||
## Order Form
|
||||
|
||||
An Order Form is a lightweight document that captures the customer details, credit amount, discount, term, and signatures from both
|
||||
PostHog and the Customer. They are either governed by our standard terms or a custom MSA (see below).
|
||||
PostHog and the Customer. They are either governed by our standard terms or a custom MSA (see below).
|
||||
|
||||
You will likely need to use [QuoteHog](https://quote.posthog.com/) to get the correct credit amount to be included in the order form.
|
||||
|
||||
### Creating an Order Form
|
||||
|
||||
We use [PandaDoc](https://app.pandadoc.com/a/#/) to handle document generation, routing and signature. Ask Mine or Simon for access if you don't have it.
|
||||
We use [PandaDoc](https://app.pandadoc.com/a/#/) to handle document generation, routing and signature. Ask Mine or Simon for access if you don't have it.
|
||||
|
||||
1. The [order form template](https://app.pandadoc.com/a/#/templates/87jsEEeg8rvYYri9Y8gK5B) to use is titled `[Client.Company] PostHog Cloud Order Form - <MMM YYYY>`
|
||||
2. When looking at the template, click the link to **Use this template** in the top bar.
|
||||
@@ -62,11 +63,13 @@ We use [PandaDoc](https://app.pandadoc.com/a/#/) to handle document generation,
|
||||
5. Remove the Enterprise Plan line item if not needed.
|
||||
6. At the bottom of the pricing table, set the **Discount %** just above the Total
|
||||
7. On the right of the screen there is a sidebar, select the **Variables** tab and populate them as follows:
|
||||
* **Client Address Information** - Needs to be their legal correspondence address (check with your customer contact)
|
||||
* **Client.Company** - The legal company name
|
||||
* **Contract.Discount** - The discount % (appears in the Additional credit purchase section)
|
||||
* **Startup credits** - If the customer [qualifies for the 2 free months](/handbook/growth/sales/contract-rules#startup-plan-discounts) when rolling off the startup plan, add up their total and discount as normal, and then add a note about the free credits in this format: "An additional credit in the amount of `<amount>` to be applied to Customer's account at start of Contract with an expiration 14 months from the start date." For example, if a customer is signing a standard $20k annual contract to get the 20% discount, the total will be $25k, 20% discount of $5k, total cost to the customer would be $20k. In the notes, you would write: "An additional credit in the amount of USD $4,166.67 to be applied to Customer's account at start of Contract with an expiration 14 months from the start date."
|
||||
* **Contract.EffectiveDate**
|
||||
|
||||
- **Client Address Information** - Needs to be their legal correspondence address (check with your customer contact)
|
||||
- **Client.Company** - The legal company name
|
||||
- **Contract.Discount** - The discount % (appears in the Additional credit purchase section)
|
||||
- **Startup credits** - If the customer [qualifies for the 2 free months](/handbook/growth/sales/contract-rules#startup-plan-discounts) when rolling off the startup plan, add up their total and discount as normal, and then add a note about the free credits in this format: "An additional credit in the amount of `<amount>` to be applied to Customer's account at start of Contract with an expiration 14 months from the start date." For example, if a customer is signing a standard $20k annual contract to get the 20% discount, the total will be $25k, 20% discount of $5k, total cost to the customer would be $20k. In the notes, you would write: "An additional credit in the amount of USD $4,166.67 to be applied to Customer's account at start of Contract with an expiration 14 months from the start date."
|
||||
- **Contract.EffectiveDate**
|
||||
|
||||
- Set the start date of the contract in the format DD MMM YYYY (e.g., 01 Feb 2023). For a new customer, this would be the date they choose to start their subscription. For an existing customer, we have two options:
|
||||
- **Immediate Activation:** If the customer wishes to start using the credits immediately, set the start date to the beginning of their current billing period. This backdating ensures that the credits are applied correctly to the current billing cycle.
|
||||
- **Next Billing Cycle:** If the customer prefers to begin their annual plan at the start of their next billing cycle, set the start date accordingly. This option aligns the contract start date with the upcoming billing period.
|
||||
@@ -76,22 +79,24 @@ We use [PandaDoc](https://app.pandadoc.com/a/#/) to handle document generation,
|
||||
- If you set the start date correctly, our Zapier automation flow will create the invoices with correct dates so our revenue calculations are not affected from the transition.
|
||||
- **Note:** Pay-as-you-go products are charged after the end of the period, while flat-rate subscriptions are charged at the beginning of the period. As a result the first two payments on a monthly schedule may occur within the same billing period as part of the transition. Make sure to send a note to the customer to ensure they're fully informed!
|
||||
|
||||
* **Contract.Term** - The term in months of the contract (12 months by default)
|
||||
- **Contract.Term** - The term in months of the contract (12 months by default)
|
||||
|
||||
8. If they are paying monthly change:
|
||||
- Payment Terms to `12 equal monthly payments from Contract start date`.
|
||||
- Payment Method to `Credit Card`.
|
||||
- Payment Terms to `12 equal monthly payments from Contract start date`.
|
||||
- Payment Method to `Credit Card`.
|
||||
9. If an MSA is being used rather than the standard terms you will need to replace the following text:
|
||||
> PostHog Cloud License Terms appearing at: https://www.posthog.com/terms and Privacy Policy appearing at: /privacy (collectively the “Agreement”)
|
||||
|
||||
with
|
||||
> PostHog Cloud License Terms appearing at: https://www.posthog.com/terms and Privacy Policy appearing at: /privacy (collectively the “Agreement”)
|
||||
|
||||
> PostHog Cloud License Terms executed by and between PostHog, Inc. and CUSTOMER LEGAL NAME (the “Agreement”)
|
||||
with
|
||||
|
||||
> PostHog Cloud License Terms executed by and between PostHog, Inc. and CUSTOMER LEGAL NAME (the “Agreement”)
|
||||
|
||||
10. You should link the order form to the opportunity record in Salesforce using the `Contract Link` field in the "Opportunity Closure Details" so that we have a reference to the completed paperwork from our CRM.
|
||||
|
||||
### Routing an Order Form for review and signature
|
||||
|
||||
1. When viewing the order form, check the recipients tab in the sidebar. The Client and PostHog roles should be filled in.
|
||||
1. When viewing the order form, check the recipients tab in the sidebar. The Client and PostHog roles should be filled in.
|
||||
2. A signing order should also be set, with the Client signing first (so they can review it before we sign).
|
||||
3. Ensure Document forwarding and Signature forwarding are set to on so that our Contact can re-assign the document if needed.
|
||||
4. Click Send at the top of the document and add a message explaining the context of the order form.
|
||||
@@ -100,7 +105,6 @@ We use [PandaDoc](https://app.pandadoc.com/a/#/) to handle document generation,
|
||||
7. Zapier will [automatically add](https://zapier.com/editor/217375860) a record in the [Annual Plan Table](https://tables.zapier.com/app/tables/t/01HGX2N9JXNV2EEDYARD24901R) with the PandaDoc Order Form ID.
|
||||
8. Celebrate!
|
||||
|
||||
|
||||
### Manual upload of signed Order Form
|
||||
|
||||
We prefer to keep all signatures in PandaDoc, but sometimes clients may prefer to sign a PDF copy. One way to minimize this is to send contracts for initial review via PandaDoc when possible. It is ok to have multiple drafts in PandaDoc as long as we have the final signed copy in there as well. When a client signs an order form outside of PandaDoc, please follow these steps to complete the process:
|
||||
@@ -117,31 +121,29 @@ We prefer to keep all signatures in PandaDoc, but sometimes clients may prefer t
|
||||
|
||||
Once you the signed form in PandaDoc is marked as complete and the Salesforce opportunity status is set to Closed Won, the RevOps team will get a notification and handle setting up the subscription and invoicing. See the [Billing](/handbook/growth/sales/billing) page for steps on how the billing setup works for more information.
|
||||
|
||||
|
||||
## Master Services Agreement (MSA)
|
||||
|
||||
Occasionally, customers will want to sign an MSA instead of referencing our terms in an order form. We don't have this templated in PandaDoc yet as it's so infrequent.
|
||||
Occasionally, customers will want to sign an MSA instead of referencing our terms in an order form. We don't have this templated in PandaDoc yet as it's so infrequent.
|
||||
|
||||
1. Download a copy of the [PostHog Cloud MSA](https://docs.google.com/document/d/155w70ZAHecVZcDqTq2_415dvaq2Bk-8QlEOozjq1hG8/edit#heading=h.y38xfjgcg4xm) as a Word Document (legal teams prefer this format) and share it with your Customer contact.
|
||||
2. They may want to propose changes (also known as 'redlines'). Work with Fraser to get these agreed.
|
||||
3. Create a new document in PandaDoc, you can choose to either import from Google Drive or upload from your local machine. This should be the clean, non-redlined document as agreed by both parties.
|
||||
2. They may want to propose changes (also known as 'redlines'). Work with Fraser to get these agreed.
|
||||
3. Create a new document in PandaDoc, you can choose to either import from Google Drive or upload from your local machine. This should be the clean, non-redlined document as agreed by both parties.
|
||||
4. Change the name to be `PostHog Cloud MSA - CUSTOMER LEGAL NAME`.
|
||||
5. Add the Client and PostHog (fraser@posthog.com) as roles.
|
||||
6. Add a Signature, Name and Title field for both PostHog and the Customer.
|
||||
7. Check the signing order (Client, then PostHog normally).
|
||||
8. Send for signature.
|
||||
|
||||
Sometimes large customers will ask for changes to our MSA. We have a list of the kinds of changes we will/won't consider in a private repo [here](https://github.com/PostHog/company-internal/blob/master/finance/sales%20contract%20changes) that you can generally agree to without the Ops team reviewing. However, if you are ever in doubt, ask Fraser.
|
||||
Sometimes large customers will ask for changes to our MSA. We have a list of the kinds of changes we will/won't consider in a private repo [here](https://github.com/PostHog/company-internal/blob/master/finance/sales%20contract%20changes) that you can generally agree to without the Ops team reviewing. However, if you are ever in doubt, ask Fraser.
|
||||
|
||||
## Business Associate Agreement (BAA)
|
||||
|
||||
We offer HIPAA Compliance on PostHog Cloud and as such health companies will require us to sign a Business Associate Agreement with them. As this means we take on increased financial risk in case of a breach we ask them as a minimum to subscribe to one of the platform add-ons which is a guaranteed monthly payment. A maximum of one BAA per organization will be signed. Under most circumstances, it should be the company that owns the org/pays us.
|
||||
We offer HIPAA Compliance on PostHog Cloud and as such health companies will require us to sign a Business Associate Agreement with them. As this means we take on increased financial risk in case of a breach we ask them as a minimum to subscribe to one of the platform packages which is a guaranteed monthly payment. A maximum of one BAA per organization will be signed. Under most circumstances, it should be the company that owns the org/pays us.
|
||||
|
||||
1. Ask the customer to subscribe to the platform add-on (as well as any other paid plans they wish to use). You can verify this in Vitally by ensuring that they are in the `Teams Plan` segment.
|
||||
1. Ask the customer to subscribe to the platform add-on (as well as any other paid plans they wish to use). You can verify this in Vitally by ensuring that they are in the `Teams Plan` segment.
|
||||
2. Create a new document from the [PandaDoc Template](https://app.pandadoc.com/a/#/templates/4psCXzU527sNE6WEbFBg3a).
|
||||
3. All you need to do it set the `Client.Company` variable and then send it to them for review and signature.
|
||||
4. It has been pre-signed by Fraser and will automatically add today's date as the date of signature for PostHog.
|
||||
5. You'll get a notification when everybody has signed it - we have automation in place to ensure that the `HIPAA BAA Signed Date` property on the customer's Salesforce Account record is updated.
|
||||
|
||||
> We only provide our default BAA for platform add-on subscribers - customization requires >$20k annual spend. The BAA only remains active for as long as the customer is subscribed to a platform add-on - if they unsubscribe, we send them a message that their BAA will become inactive at the end of the month in which they cancelled. A customer who is on a platform add-on trial (with a credit card in PostHog) is eligible to sign a default BAA, but you should make it clear to them that the default BAA will be voided if/when the platform add-on subscription lapses. If the lead is not sure whether they will need a custom BAA and their usage wouldn't put them at $20K, then it is worth pushing them to get legal feedback by sending them our BAA before moving forward, else you risk spending a lot of time on an evaluation that ends up at $450/month.
|
||||
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="85" height="107" fill="none" viewBox="0 0 85 107"><path fill="#fff" d="M27.5894 91.1365C22.7555 86.7178 21.3444 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4375 78.2199 52.0359 77.7822 59.2232 74.2459C60.0454 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.318 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6845 102.089C39.2087 99.8193 38.5066 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5894 91.1365Z"/><path fill="url(#paint0_linear_1_59)" d="M27.5894 91.1365C22.7555 86.7178 21.3444 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4375 78.2199 52.0359 77.7822 59.2232 74.2459C60.0454 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.318 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6845 102.089C39.2087 99.8193 38.5066 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5894 91.1365Z"/><path fill="#fff" d="M0 69.5866C0 69.5866 14.3139 62.6137 28.6678 62.6137L39.4901 29.1204C39.8953 27.5007 41.0783 26.3999 42.4139 26.3999C43.7495 26.3999 44.9325 27.5007 45.3377 29.1204L56.1601 62.6137C73.1601 62.6137 84.8278 69.5866 84.8278 69.5866C84.8278 69.5866 60.5145 3.35233 60.467 3.21944C59.7692 1.2612 58.5911 0 57.0029 0H27.8274C26.2392 0 25.1087 1.2612 24.3634 3.21944C24.3108 3.34983 0 69.5866 0 69.5866Z"/><defs><linearGradient id="paint0_linear_1_59" x1="22.47" x2="69.145" y1="107" y2="84.947" gradientUnits="userSpaceOnUse"><stop stop-color="#D83333"/><stop offset="1" stop-color="#F041FF"/></linearGradient></defs></svg>
|
||||
<svg width="85" height="107" viewBox="0 0 85 107" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M27.5893 91.1365C22.7555 86.7178 21.3443 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4374 78.2199 52.0358 77.7822 59.2231 74.2459C60.0453 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.3179 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6844 102.089C39.2086 99.8193 38.5065 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5893 91.1365Z"
|
||||
fill="#17191E" />
|
||||
<path
|
||||
d="M0 69.5866C0 69.5866 14.3139 62.6137 28.6678 62.6137L39.4901 29.1204C39.8953 27.5007 41.0783 26.3999 42.4139 26.3999C43.7495 26.3999 44.9325 27.5007 45.3377 29.1204L56.1601 62.6137C73.1601 62.6137 84.8278 69.5866 84.8278 69.5866C84.8278 69.5866 60.5145 3.35233 60.467 3.21944C59.7692 1.2612 58.5911 0 57.0029 0H27.8274C26.2392 0 25.1087 1.2612 24.3634 3.21944C24.3108 3.34983 0 69.5866 0 69.5866Z"
|
||||
fill="#17191E" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.3 KiB |
188
contents/index.mdx
Normal file
188
contents/index.mdx
Normal file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
title: Home
|
||||
template: custom
|
||||
images:
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_llm_analytics_light_a436da72f7.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_llm_analytics_dark_d8f32c249b.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_dashboards_light_998b77b1a0.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_dashboards_dark_43ef120c80.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/dashboard_light_61b3bab3b6.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_cdp_dark_5610c405b2.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_cdp_light_97bc52e8f9.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_replay_timeline_light_9225f869dc.jpg
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_replay_timeline_dark_f5371a996f.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_data_warehouse_light_b0cdbebe8f.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_data_warehouse_dark_8f465ecfaa.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_surveys_light_3dfb9f57e9.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_surveys_dark_a492c37d9c.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_web_analytics_dashboard_light_313729cacc.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_web_analytics_dashboard_dark_20eb61e4b2.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_experiments_result_light_465bac8937.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_experiments_result_dark_399c2187ea.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_feature_flags_light_6a7b1dfc70.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_feature_flags_dark_f091ddfb9b.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_product_analytics_trend_light_703f700a5b.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_product_analytics_trend_dark_086dcec4b2.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_error_tracking_light_93bfa1393d.png
|
||||
- https://res.cloudinary.com/dmukukwp6/image/upload/screenshot_error_tracking_dark_ef481dc7a5.png
|
||||
---
|
||||
|
||||
<div class="text-center @xl:text-left">
|
||||
|
||||
<h1 class="[&_p]:m-0 flex gap-2 flex-wrap justify-center @xl:justify-start">
|
||||
<Logo />
|
||||
</h1>
|
||||
|
||||
<span class="text-base font-medium mb-0">
|
||||
We’re building every tool for product engineers to build successful products.
|
||||
</span>
|
||||
|
||||
<CTAs />
|
||||
|
||||
Questions? [Watch a demo](/demo) or [talk to a human](/talk-to-a-human).
|
||||
|
||||
</div>
|
||||
|
||||
<header class="flex flex-col items-center @xl:flex-row @xl:justify-between @xl:items-baseline [&_h2]:m-0 mt-10 mb-4">
|
||||
|
||||
## Explore apps <span class="text-secondary text-sm font-normal tracking-normal">by company stage</span>
|
||||
|
||||
<aside class="hidden @xl:inline-flex">
|
||||
|
||||
<span class="[&_p]:m-0">
|
||||
[Browse app library](/products) (<AppCount />)
|
||||
</span>
|
||||
|
||||
</aside>
|
||||
</header>
|
||||
|
||||
<CompanyStageTabs />
|
||||
|
||||
<div id="customers">
|
||||
|
||||
## Who's using PostHog?
|
||||
|
||||
Here are some of our paying customers. (Yes they actually use us, no it's not just some random engineer who tried us out 2+ years ago.)
|
||||
|
||||
<Customers />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="space-y-8 pt-2">
|
||||
|
||||
<div id="customer-infrastructure">
|
||||
|
||||
## Customer data infrastructure, built for product engineers
|
||||
|
||||
<div class="@lg:float-right text-sm @lg:max-w-xs bg-accent p-4 rounded-sm @lg:ml-6 @lg:mb-2 relative pb-[120px] @md:pb-4 @md:pr-[220px] @lg:pr-6 @lg:pb-[120px]">
|
||||
|
||||
<p class="my-0 [&_p]:my-0">
|
||||
|
||||
**Built-in, Product OS ships with:**
|
||||
|
||||
</p>
|
||||
|
||||
<span class="[&_ul]:mb-0">
|
||||
|
||||
- A data warehouse <TooltipDW />
|
||||
- 120+ sources/destinations
|
||||
- SQL editor + BI + data viz
|
||||
- User activity feed (CDP-lite)
|
||||
- API, webhooks
|
||||
|
||||
</span>
|
||||
|
||||
<ImageDW />
|
||||
|
||||
</div>
|
||||
|
||||
When you're analyzing how customers use your product, you should be operating from _the full set of data_.
|
||||
|
||||
This includes customer information that happens _outside your product_:
|
||||
|
||||
- payments from Stripe
|
||||
- exceptions in an error tracking tool
|
||||
- tickets in your support platform
|
||||
|
||||
Having all the data in one place means you can make more informed decisions about what to build next.
|
||||
|
||||
PostHog's Product OS isn't just analytics – it's the entire suite of tools built to give you a single source of truth about your customers.
|
||||
|
||||
<ButtonCDI />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="pricing">
|
||||
|
||||
## Usage-based pricing
|
||||
|
||||
<ImageMoney />
|
||||
|
||||
Our whole philosophy is that you shouldn't have to worry about pricing.
|
||||
|
||||
All our paid products are pay-per-use with generous monthly free tiers. In fact, 98% of our customers use PostHog for free.
|
||||
|
||||
We aim to be the cheapest option at scale – PostHog should be a no-brainer. You never have to "jump on a quick call" with sales.
|
||||
|
||||
Here are some examples of how we charge for most popular products:
|
||||
|
||||
<Pricing />
|
||||
|
||||
<ButtonPricing />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="ai">
|
||||
|
||||
## "Shouldn't you be talking about AI?"
|
||||
|
||||
We've got that too. It works across the Product OS platform – and it's _way_ more than just generating insights.
|
||||
|
||||
Max AI helps you automate monotonous tasks of gathering context and summarizing information – and will soon have the ability to make code changes to fix bugs and improve software.
|
||||
|
||||
<ButtonAI />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="why-posthog">
|
||||
|
||||
## Why PostHog?
|
||||
|
||||
We're different from most companies for a bunch of reasons:
|
||||
|
||||
- **Transparency.** You can read our [company handbook](/handbook), our [sales manual](/handbook/growth/sales/overview), and [company strategy](/handbook/why-does-posthog-exist).
|
||||
- **We ship fast.** See our [changelog](/changelog).
|
||||
- **_Actually_-technical support.** Our [support folks](/teams/support) all have engineering backgrounds.
|
||||
|
||||
<ButtonAbout />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="bedtime-reading">
|
||||
|
||||
## Bedtime reading
|
||||
|
||||
<ImageReading1 />
|
||||
|
||||
Still here? We've got some links that may be mildly interesting to you:
|
||||
|
||||
<ImageReading2 />
|
||||
|
||||
- [demo.mov](/demo)
|
||||
- [Technical docs](/docs)
|
||||
- [API](/docs/api)
|
||||
- [Ask a question](/questions)
|
||||
- [Small teams at PostHog](/teams)
|
||||
|
||||
</div>
|
||||
|
||||
<div id="shameless-cta">
|
||||
|
||||
## Shameless CTA
|
||||
|
||||
<CTA />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<HomeHitCounter />
|
||||
76
contents/media-contents.mdx
Normal file
76
contents/media-contents.mdx
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Media & press
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
showSidebar: false
|
||||
---
|
||||
|
||||
# Media & press
|
||||
|
||||
**Want to chat press opportunities? Email [press@posthog.com](mailto:press@posthog.com) and we'll get back to you.**
|
||||
|
||||
If you'd like to keep up to date with PostHog, we recommend you [subscribe to our newsletter](https://newsletter.posthog.com/subscribe). You can also follow us on [X](https://x.com/posthog) or [LinkedIn](https://www.linkedin.com/company/posthog) too.
|
||||
|
||||
## About PostHog
|
||||
|
||||
PostHog aims to equip every developer to build successful products.
|
||||
|
||||
We do this by providing the tools teams need to capture events, analyze data, record user sessions, conduct experiments, deploy new features, track errors, run surveys, provision data warehouses, observe LLM-powered features, and more, all in one platform. And we're constantly shipping new things!
|
||||
|
||||
Founded in January 2020 by James Hawkins and Tim Glaser, PostHog was a member of Y Combinator's Winter 2020 batch, and has subsequently raised $107M in funding from [Stripe](https://stripe.com/), [GV](https://www.gv.com/), [Y Combinator](https://www.ycombinator.com/), and notable angel investors including Jason Warner (CTO, GitHub), Solomon Hykes (Founder, Docker), and others.
|
||||
|
||||
You can read more about [PostHog's story](/handbook/story), [where we are going](/handbook/future), and more about our company culture in our [handbook](/handbook).
|
||||
|
||||
### Funding history
|
||||
|
||||
_Lead investor(s) are in **bold**._
|
||||
|
||||
| Round | Date | Raised | Participants |
|
||||
| ------------------------------------------------------------- | ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Seed | March 2020 | $3M | <ul class="my-0"><li><strong>Y Combinator</strong></li><li><strong>1984 VC</strong></li></ul> |
|
||||
| [Series A](/blog/posthog-announces-9-million-dollar-series-A) | July 2020 | $9M | <ul class="my-0"><li><strong>GV (Alphabet's VC firm)</strong></li><li>Y Combinator's Continuity Fund</li><li>Tapas Capital</li></ul> |
|
||||
| [Series B](/blog/15-million-series-b) | March 2021 | $15M | <ul class="my-0"><li><strong>Y Combinator's Continuity Fund</strong></li><li>GV</li><li>1984 Ventures</li><li>Tapas Capital</li></ul> |
|
||||
| [Series C](/blog/series-d#what-about-the-series-c) | Early 2025 | $10M | <ul class="my-0"><li>Y Combinator's Continuity Fund</li><li>GV</li></ul> |
|
||||
| [Series D](/blog/series-d) | June 2025 | $70M | <ul class="my-0"><li><strong>Stripe</strong></li><li>YC</li><li>GV</li><li>Formus Capital</li></ul> |
|
||||
|
||||
### Founder bios
|
||||
|
||||
You can find biographies and social links for our founders, [James](/community/profiles/27732) and [Tim](/community/profiles/27730), as well as the rest of our team in [our handbook](/people). You can also read about the importance of [our first five hires](/blog/posthog-first-five)!
|
||||
|
||||
## PostHog logos
|
||||
|
||||
We've created brand assets for you. You don't have to negotiate legal agreements for them. You can find them on our [brand assets](/handbook/company/brand-assets) page.
|
||||
|
||||
## Founder headshots
|
||||
|
||||
Below are photos of James and Tim. James is wearing the white hoodie, and Tim is wearing the black. James is also taller, for the record.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Banner images
|
||||
|
||||
Want to show your support for PostHog? You can use these banners anywhere you want.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Desktop wallpapers
|
||||
|
||||
[Here, have some wallpapers.](/blog/posthog-wallpapers)
|
||||
|
||||
## Hedgehog avatars
|
||||
|
||||
Our mascot is a hedgehog called Max. Here he is in some of his favourite outfits!
|
||||
|
||||
| Builder Max | Professor Max | Detective Max |
|
||||
| :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
|  |  |  |
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
title: Media & Press
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
showSidebar: false
|
||||
---
|
||||
|
||||
**Want to chat press opportunities? Email [press@posthog.com](mailto:press@posthog.com) and we'll get back to you.**
|
||||
|
||||
If you'd like to keep up to date with PostHog, we recommend you [subscribe to our newsletter](https://newsletter.posthog.com/subscribe). You can also follow us on [Twitter](https://twitter.com/posthog) or [LinkedIn](https://www.linkedin.com/company/posthog) too.
|
||||
|
||||
## About PostHog
|
||||
|
||||
PostHog aims to equip every developer to build successful products.
|
||||
|
||||
We do this by providing the tools teams need to capture events, analyze data, record user sessions, conduct experiments, deploy new features, track errors, run surveys, provision data warehouses, observe LLM-powered features, and more, all in one platform. And we're constantly shipping new things!
|
||||
|
||||
Founded in January 2020 by James Hawkins and Tim Glaser, PostHog was a member of Y Combinator's Winter 2020 batch, and has subsequently raised $107m in funding from [Stripe](https://stripe.com/), [GV](https://www.gv.com/), [Y Combinator](https://www.ycombinator.com/), and notable angel investors including Jason Warner (CTO, GitHub), Solomon Hykes (Founder, Docker), and others.
|
||||
|
||||
You can read more about [PostHog's story](/handbook/story), [where we are going](/handbook/future), and more about our company culture in our [handbook](/handbook).
|
||||
|
||||
### Funding history
|
||||
|
||||
- **Series D** - June 2025, $70M Series D round, led by Stripe, with participation from YC, GV, and Formus Capital. [More info](/blog/series-d).
|
||||
- **Series C** - Announced June 2025, ~$10M Series C round. [More info](/blog/series-d#what-about-the-series-c).
|
||||
- **Series B** - March 2021, $15M Series B round, led by Y Combinator's Continuity Fund, with participation from GV, 1984 Ventures and Tapas Capital. [More info](/blog/15-million-series-b).
|
||||
- **Series A** - July 2020, $9M Series A round, Alphabet's VC firm GV, with participation from Y Combinator's Continuity Fund and Tapas Capital. [More info](/blog/posthog-announces-9-million-dollar-series-A).
|
||||
- **Seed** - March 2020, $3M seed round, led by Y Combinator and 1984 VC.
|
||||
|
||||
### Founder bios
|
||||
|
||||
You can find biographies and social links for our founders, [James](/community/profiles/27732) and [Tim](/community/profiles/27730), as well as the rest of our team in [our handbook](/people). You can also read about the importance of [our first five hires](/blog/posthog-first-five)!
|
||||
|
||||
## PostHog logos
|
||||
|
||||
We've created brand assets for you. You don't have to negotiate legal agreements for them. You can find them on our [brand assets](/handbook/company/brand-assets) page.
|
||||
|
||||
## Founder headshots
|
||||
|
||||
Below are photos of James and Tim. James is wearing the white hoodie, and Tim is wearing the black. James is also taller, for the record.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Banner images
|
||||
|
||||
Want to show your support for PostHog? You can use these banners anywhere you want.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Hedgehog avatars
|
||||
|
||||
Our mascot is a hedgehog called Max. Here he is in some of his favourite outfits!
|
||||
|
||||
| Builder Max | Professor Max | Detective Max|
|
||||
|:--------------:|:-----------:|:------------:|
|
||||
|  |  |  |
|
||||
113
contents/product-toolkit.mdx
Normal file
113
contents/product-toolkit.mdx
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Home
|
||||
template: custom
|
||||
---
|
||||
|
||||
<div class="flex @lg:flex-row-reverse @lg:justify-end @lg:items-end flex-col">
|
||||
|
||||
<HappyHog />
|
||||
|
||||
<div>
|
||||
|
||||
<h1 class="[&_p]:m-0 flex gap-2 flex-wrap">
|
||||
<span>welcome to</span>
|
||||
<Logo />
|
||||
<span>PostHog</span>
|
||||
</h1>
|
||||
|
||||
we're building the operating system for people who build products.
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="space-y-8 pt-2">
|
||||
|
||||
<div id="product-os">
|
||||
|
||||
<h2 class="mt-0">we call it Product OS</h2>
|
||||
|
||||
you can do powerful things across the platform, like:
|
||||
|
||||
- ask questions about product usage or specific customers
|
||||
- auto-generate insights or run deep research
|
||||
- discover correlations in data that used to loads of time (and lots of SQL)
|
||||
|
||||
</div>
|
||||
|
||||
<div id="products">
|
||||
|
||||
## products
|
||||
|
||||
we've built 19 products and tools so far. many of them fit into these categories:
|
||||
|
||||
<Products />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="roadmap">
|
||||
|
||||
## roadmap
|
||||
|
||||
we haven't built our defining feature. customers help us decide what to build next.
|
||||
|
||||
<Roadmap />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="pricing">
|
||||
|
||||
## pricing
|
||||
|
||||
our usage-based pricing means you don't have to "talk to sales". plus each product has a generous monthly free tier – in fact, 98% of customers use PostHog for free!
|
||||
|
||||
<Pricing />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="logos">
|
||||
|
||||
## logos
|
||||
|
||||
here are some of our paying customers. (yes they actually use us, no it's not just some random engineer that tried us out 2+ years ago.)
|
||||
|
||||
<Customers />
|
||||
|
||||
</div>
|
||||
|
||||
<div id="why-posthog">
|
||||
|
||||
## why PostHog?
|
||||
|
||||
we're different from most companies for a bunch of reasons:
|
||||
|
||||
- **transparency.** read our [company handbook](/handbook), our [sales manual](/sales-manual), or [company strategy](/strategy)
|
||||
- **we ship fast.** see our [changelog](/changelog)
|
||||
- **actually-technical support.** our [support people](/support) all have engineering backgrounds.
|
||||
|
||||
[take the company tour](/why) →
|
||||
|
||||
</div>
|
||||
|
||||
<div id="bedtime-reading">
|
||||
|
||||
## bedtime reading
|
||||
|
||||
here are some links that may be interesting to you:
|
||||
|
||||
- [demo.mov](/demo)
|
||||
- [technical docs](/docs)
|
||||
- [api](/docs/api)
|
||||
- [ask a question](/questions)
|
||||
- [small teams at PostHog](/teams)
|
||||
|
||||
</div>
|
||||
|
||||
<div id="shameless-cta">
|
||||
|
||||
## shameless CTA
|
||||
|
||||
<CTA />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
title: Services
|
||||
sidebar: Docs
|
||||
showTitle: true
|
||||
---
|
||||
|
||||
PostHog is something you can deploy yourself.
|
||||
|
||||
However, many people want someone else to manage it for them.
|
||||
|
||||
If you would like any of the following, please [contact us](/talk-to-a-human).
|
||||
|
||||
## Managed hosting in your cloud, by PostHog's team
|
||||
|
||||
PostHog deployed in your cloud, with our team making sure that it is set up and working properly. This tends to be the best fit for large organizations.
|
||||
|
||||
* No need to send your user data outside your cloud
|
||||
* Full underlying access to the entire PostHog system, for easy customization or integrations with other systems
|
||||
* PostHog's own team will make sure your system is kept updated and secure
|
||||
* Influence our roadmap
|
||||
|
||||
## PostHog hosting
|
||||
|
||||
PostHog hosts your product analytics for you. We can help with the initial setup and integration, as well as making sure you're always up-to-date.
|
||||
|
||||
* This has the lowest possible workload for your team to get started
|
||||
|
||||
## Something else?
|
||||
|
||||
We're friendly, just [get in touch](/talk-to-a-human).
|
||||
@@ -1,311 +0,0 @@
|
||||
---
|
||||
title: PostHog for Startups
|
||||
showTitle: false
|
||||
showSidebar: true
|
||||
width: lg
|
||||
images:
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall-mobile.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/on-belay.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/belay-on.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/cat_li.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-spotlight.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-merch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-launch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-credit.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-heart.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/yc_logo.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/conceptvc_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/better_capital_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/boldstart_square.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/oliver-kicks.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-partner.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-presenter.png
|
||||
---
|
||||
|
||||
import { getImage, GatsbyImage } from 'gatsby-plugin-image'
|
||||
import { FeatureSnapshot } from 'components/FeatureSnapshot'
|
||||
export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-refer.png"
|
||||
|
||||
<div class="w-[calc(100%_+_4rem)] relative -mx-4 px-8 md:-mx-16 pt-32 pb-72 -mt-32 md:-mt-44">
|
||||
<div class="md:hidden absolute top-0 left-0 w-full bottom-0 opacity-40">
|
||||
<GatsbyImage image={getImage(props?.images[0])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="hidden md:block absolute top-0 left-0 w-full bottom-0">
|
||||
<GatsbyImage image={getImage(props?.images[1])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-4 w-24 md:left-16 md:w-48">
|
||||
<GatsbyImage image={getImage(props?.images[2])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 -right-4 w-28 md:right-16 md:w-60">
|
||||
<GatsbyImage image={getImage(props?.images[3])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 left-0 w-full h-24 bg-gradient-to-b from-tan/100 via-tan/85 to-tan/0"></div>
|
||||
|
||||
<div className="max-w-[849px] mx-auto text-center">
|
||||
<h1 className="text-4xl md:text-[64px] leading-none mt-0 mb-5">
|
||||
PostHog for startups
|
||||
</h1>
|
||||
<h2 className="text-[18px] md:text-[20px] leading-[1.4] font-semibold mb-8 !mt-5">$50k in credits (plus extras you'll actually use) <br className="hidden lg:block" />to help you get to product-market fit</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups">Apply now</CallToAction>
|
||||
|
||||
<div className="max-w-xs rounded p-3 text-left bg-accent/100 dark:bg-accent-dark/100 border border-border dark:border-dark mx-auto mt-8 relative z-10">
|
||||
<h3 className="text-lg mb-1">How to apply:</h3>
|
||||
<ol>
|
||||
<li><a href="https://app.posthog.com/startups">Sign up</a> for PostHog Cloud</li>
|
||||
<li>Complete onboarding</li>
|
||||
<li>Submit the <a href="https://app.posthog.com/startups">application form</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-6 sm:mb-16 lg:mb-1">Here's what you get when you join</h3>
|
||||
<p class="text-2xl lg:text-3xl m-0 text-center mb-6 sm:mb-16 lg:mb-8">Teams must be less than 2 years old and have less than $5 million in funding to qualify</p>
|
||||
<div class="flex justify-center">
|
||||
<ul class="m-0 p-0 list-none inline-grid sm:grid-cols-2 lg:grid-cols-2 gap-[10px] justify-evenly relative text-center sm:text-left">
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">$50,000 in PostHog credit</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
That's a lot of events, replays, API calls, survey responses, and more. It lasts a year!
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Exclusive founder merch</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
You can never have too many laptop stickers or free t-shirts, right?
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better docs with Mintlify</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
The best products deserve the best documentation. Get 50% off Mintlify for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better SDKs with Speakeasy</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
Building an API or SDK? Our pals at Speakeasy have you covered with 50% off for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Building is never just one-and-done. You always need to find ways to improve.
|
||||
<span class="text-red"> PostHog is central to how we do that at Y Combinator</span>. It helps us try ideas, measure results and make better products.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[4])} alt="Cat Li" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Cat Li</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Product & Engineering Lead, <span class="inline-block">Y Combinator</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-3 sm:mb-8 lg:mb-1">Recommended by the world's leading startup accelerators</h3>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-primary/75 dark:text-primary-dark/75 text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
</div>
|
||||
<ul class="list-none p-0 grid md:grid-cols-3 gap-4 mb-5 md:mb-10 justify-center">
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/pry_posthog_506c464b7a.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by <a href="/customers/ycombinator">Y Combinator</a>, acquired by Brex</p>
|
||||
<p class="text-sm">"PostHog isn’t just about making decisions, it's about having ideas. <span class="bg-highlight p-0.5">There are things you don’t even think of until you see the data."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/pry">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/opensauced_posthog_a180477623.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Boldstart, the partner for devs</p>
|
||||
<p class="text-sm">"Boldstart recommended PostHog to us. There’s so many things that are possible for us — but <span class="bg-highlight p-0.5">PostHog is helping us find a path."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/opensauced">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/eleven_labs_b5853d00b7.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Concept, the UK's largest seed fund</p>
|
||||
<p class="text-sm">"We used to have dozens of tools and dashboards. PostHog is amazing because <span class="bg-highlight p-0.5">it reins in the chaos so we have everything in one place."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/elevenlabs">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<Section>
|
||||
<h2 className="text-3xl lg:text-5xl text-center mb-0">How does PostHog for Startups compare?</h2>
|
||||
<h3 className="text-xl m-0 font-semibold opacity-75 text-center !pb-8">Well, it's the only startup program with free laptop stickers...</h3>
|
||||
<div className="overflow-x-auto -mx-5 flex justify-start lg:justify-center px-4 lg:px-0">
|
||||
<table className="w-400 mt-4" style="max-width: 1100px; font-size: 15px;">
|
||||
<thead>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td className="w-2/12"></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-pendo">Pendo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-amplitude">Amplitude</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-mixpanel">Mixpanel</a></td>
|
||||
<td className="w-2/12 text-center bg-accent dark:bg-accent-dark"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Eligibility criteria</strong></td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center"><$5m in funding and <20 staff members</td>
|
||||
<td className="text-center"><$8m in funding and less than 5 years old</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><$5m in funding and less than 2 years old</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Limitations</strong></td>
|
||||
<td className="text-center">500 monthly users</td>
|
||||
<td className="text-center">1,000 monthly sessions</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">One year duration</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Benefits</strong></td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">200,000 MTUs</td>
|
||||
<td className="text-center">$50,000 credit</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">$50,000 credit</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Open source product</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Free gifts (omg, stickers)</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Partnership opportunities</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center mt-8">
|
||||
<p><a href="/blog/tags/comparisons">Explore more product comparisons</a></p>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-md mx-auto space-y-1">
|
||||
<details>
|
||||
<summary>How do I apply?</summary>
|
||||
<p>Just sign up to a paid plan in PostHog (you're only charged for usage) and then fill in this <a href="https://app.posthog.com/startups">form</a>. We will apply the credit automatically if you're eligible. If you're accepted into the program, we will notify you by email. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Who's eligible? </summary>
|
||||
<p>Your company needs to be less than 2 years old and have raised less than $5m funding. You need to have signed up any time from Jan 1st 2023 onwards. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>I signed up before this deal launched, can I still get it?</summary>
|
||||
<p>Yes, but only if you signed up after Jan 1st 2023. If your startup meets the eligibility criteria but you signed up to PostHog before Jan 1st, we won't apply the credits but are still happy to enroll you in the rest of the program. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can I get this deal if I'm part of YC?</summary>
|
||||
<p>We have a separate deal for YC folks - check out Bookface. No, they don't stack!</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What if I go over the $50k limit? </summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What happens at the end of the 12 months?</summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>. You'll continue to be considered part of the program in terms of invites to office hour events, and other perks. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How do I get the Mintlify/Speakeasy discount?</summary>
|
||||
<p>Once you're accepted into the PostHog for Startups program, we'll email you with a voucher code to get you 50% off Mintlify and Speakeasy for six months.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What level of customer support do I get?</summary>
|
||||
<p>PostHog is run by a small team and, as such, we're only able to offer support to paying customers. Organizations which are part of our startup plan are therefore not eligible for high priority customer support, and only qualify for normal priority and community support. This is still the case even if you apply your credits towards a platforms add-on.</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Our portfolio companies rely on analytics to optimise their products. <span class="text-red"> Understanding user behaviours through platforms like PostHog is mission-critical.</span> The insights it provides are invaluable for founders.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[14])} alt="Oliver Kicks" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Oliver Kicks</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Partner, <span class="inline-block">Concept Ventures</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="text-center">
|
||||
|
||||
<h2 className="text-3xl lg:text-5xl pb-8">Ready to get started?</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups">Apply now</CallToAction>
|
||||
|
||||
</div>
|
||||
@@ -1,311 +0,0 @@
|
||||
---
|
||||
title: PostHog for Startups
|
||||
showTitle: false
|
||||
showSidebar: true
|
||||
width: lg
|
||||
images:
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall-mobile.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/on-belay.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/belay-on.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/cat_li.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-spotlight.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-merch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-launch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-credit.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-heart.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/yc_logo.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/conceptvc_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/better_capital_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/boldstart_square.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/oliver-kicks.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-partner.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-presenter.png
|
||||
---
|
||||
|
||||
import { getImage, GatsbyImage } from 'gatsby-plugin-image'
|
||||
import { FeatureSnapshot } from 'components/FeatureSnapshot'
|
||||
export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-refer.png"
|
||||
|
||||
<div class="w-[calc(100%_+_4rem)] relative -mx-4 px-8 md:-mx-16 pt-32 pb-72 -mt-32 md:-mt-44">
|
||||
<div class="md:hidden absolute top-0 left-0 w-full bottom-0 opacity-40">
|
||||
<GatsbyImage image={getImage(props?.images[0])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="hidden md:block absolute top-0 left-0 w-full bottom-0">
|
||||
<GatsbyImage image={getImage(props?.images[1])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-4 w-24 md:left-16 md:w-48">
|
||||
<GatsbyImage image={getImage(props?.images[2])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 -right-4 w-28 md:right-16 md:w-60">
|
||||
<GatsbyImage image={getImage(props?.images[3])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 left-0 w-full h-24 bg-gradient-to-b from-tan/100 via-tan/85 to-tan/0"></div>
|
||||
|
||||
<div className="max-w-[849px] mx-auto text-center">
|
||||
<h1 className="text-4xl md:text-[64px] leading-none mt-0 mb-5">
|
||||
PostHog x ODF
|
||||
</h1>
|
||||
<h2 className="text-[18px] md:text-[20px] leading-[1.4] font-semibold mb-8 !mt-5">$50k in credits (plus extras you'll actually use) <br className="hidden lg:block" />to help you get to product-market fit</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/ODF">Apply now</CallToAction>
|
||||
|
||||
<div className="max-w-xs rounded p-3 text-left bg-accent/100 dark:bg-accent-dark/100 border border-border dark:border-dark mx-auto mt-8 relative z-10">
|
||||
<h3 className="text-lg mb-1">How to apply:</h3>
|
||||
<ol>
|
||||
<li><a href="https://app.posthog.com/startups/ODF">Sign up</a> for PostHog Cloud</li>
|
||||
<li>Complete onboarding</li>
|
||||
<li>Submit the <a href="https://app.posthog.com/startups/ODF">application form</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-6 sm:mb-16 lg:mb-1">We've teamed up with ODF to offer the following</h3>
|
||||
<p class="text-2xl lg:text-3xl m-0 text-center mb-6 sm:mb-16 lg:mb-8">Teams must be less than 2 years old and have less than $5 million in funding to qualify</p>
|
||||
<div class="flex justify-center">
|
||||
<ul class="m-0 p-0 list-none inline-grid sm:grid-cols-2 lg:grid-cols-2 gap-[10px] justify-evenly relative text-center sm:text-left">
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">$50,000 in PostHog credit</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
That's a lot of events, replays, API calls, survey responses, and more. It lasts a year!
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Exclusive founder merch</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
You can never have too many laptop stickers or free t-shirts, right?
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better docs with Mintlify</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
The best products deserve the best documentation. Get 50% off Mintlify for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better SDKs with Speakeasy</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
Building an API or SDK? Our pals at Speakeasy have you covered with 50% off for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Building is never just one-and-done. You always need to find ways to improve.
|
||||
<span class="text-red"> PostHog is central to how we do that at Y Combinator</span>. It helps us try ideas, measure results and make better products.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[4])} alt="Cat Li" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Cat Li</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Product & Engineering Lead, <span class="inline-block">Y Combinator</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-3 sm:mb-8 lg:mb-1">Recommended by the world's leading startup accelerators</h3>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-primary/75 dark:text-primary-dark/75 text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
</div>
|
||||
<ul class="list-none p-0 grid md:grid-cols-3 gap-4 mb-5 md:mb-10 justify-center">
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/pry_posthog_506c464b7a.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by <a href="/customers/ycombinator">Y Combinator</a>, acquired by Brex</p>
|
||||
<p class="text-sm">"PostHog isn’t just about making decisions, it's about having ideas. <span class="bg-highlight p-0.5">There are things you don’t even think of until you see the data."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/pry">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/opensauced_posthog_a180477623.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Boldstart, the partner for devs</p>
|
||||
<p class="text-sm">"Boldstart recommended PostHog to us. There’s so many things that are possible for us — but <span class="bg-highlight p-0.5">PostHog is helping us find a path."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/opensauced">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/eleven_labs_b5853d00b7.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Concept, the UK's largest fund</p>
|
||||
<p class="text-sm">"We used to have dozens of tools and dashboards. PostHog is amazing because <span class="bg-highlight p-0.5">it reins in the chaos so we have everything in one place."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/elevenlabs">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<Section>
|
||||
<h2 className="text-3xl lg:text-5xl text-center mb-0">How does PostHog for Startups compare?</h2>
|
||||
<h3 className="text-xl m-0 font-semibold opacity-75 text-center !pb-8">Well, it's the only startup program with free laptop stickers...</h3>
|
||||
<div className="overflow-x-auto -mx-5 flex justify-start lg:justify-center px-4 lg:px-0">
|
||||
<table className="w-400 mt-4" style="max-width: 1100px; font-size: 15px;">
|
||||
<thead>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td className="w-3/12"></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-pendo">Pendo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-amplitude">Amplitude</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-mixpanel">Mixpanel</a></td>
|
||||
<td className="w-2/12 text-center bg-accent dark:bg-accent-dark"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Eligibility criteria</strong></td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center"><$5m in funding and <20 staff members</td>
|
||||
<td className="text-center"><$8m in funding and less than 5 years old</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><$5m in funding and less than 2 years old</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Limitations</strong></td>
|
||||
<td className="text-center">500 monthly users</td>
|
||||
<td className="text-center">1,000 monthly sessions</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">One year duration</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Benefits</strong></td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">200,000 MTUs</td>
|
||||
<td className="text-center">$50,000 credit</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">$50,000 credit</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Open source product</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Free gifts (omg, stickers)</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Partnership opportunities</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center mt-8">
|
||||
<p><a href="/blog/tags/comparisons">Explore more product comparisons</a></p>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-md mx-auto space-y-1">
|
||||
<details>
|
||||
<summary>How do I apply?</summary>
|
||||
<p>Just sign up to a paid plan in PostHog (you're only charged for usage) and then fill in this <a href="https://app.posthog.com/startups/ODF">form</a>. We will apply the credit automatically if you're eligible. If you're accepted into the program, we will notify you by email. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Who's eligible? </summary>
|
||||
<p>Your company needs to be less than 2 years old and have raised less than $5m funding. You need to have signed up any time from Jan 1st 2023 onwards. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>I signed up before this deal launched, can I still get it?</summary>
|
||||
<p>Yes, but only if you signed up after Jan 1st 2023. If your startup meets the eligibility criteria but you signed up to PostHog before Jan 1st, we won't apply the credits but are still happy to enroll you in the rest of the program. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can I get this deal if I'm part of YC?</summary>
|
||||
<p>We have a separate deal for YC folks - check out Bookface. No, they don't stack!</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What if I go over the $50k limit? </summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What happens at the end of the 12 months?</summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>. You'll continue to be considered part of the program in terms of invites to office hour events, and other perks. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How do I get the Mintlify/Speakeasy discount?</summary>
|
||||
<p>Once you're accepted into the PostHog for Startups program, we'll email you with a voucher code to get you 50% off Mintlify and Speakeasy for six months.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What level of customer support do I get?</summary>
|
||||
<p>PostHog is run by a small team and, as such, we're only able to offer support to paying customers. Organizations which are part of our startup plan are therefore not eligible for high priority customer support, and only qualify for normal priority and community support. This is still the case even if you apply your credits towards a platforms add-on.</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Our portfolio companies rely on analytics to optimise their products. <span class="text-red"> Understanding user behaviours through platforms like PostHog is mission-critical.</span> The insights it provides are invaluable for founders.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[14])} alt="Oliver Kicks" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Oliver Kicks</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Partner, <span class="inline-block">Concept Ventures</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="text-center">
|
||||
|
||||
<h2 className="text-3xl lg:text-5xl pb-8">Ready to get started?</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/ODF">Apply now</CallToAction>
|
||||
|
||||
</div>
|
||||
@@ -1,311 +0,0 @@
|
||||
---
|
||||
title: PostHog for Startups
|
||||
showTitle: false
|
||||
showSidebar: true
|
||||
width: lg
|
||||
images:
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall-mobile.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/on-belay.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/belay-on.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/cat_li.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-spotlight.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-merch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-launch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-credit.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-heart.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/yc_logo.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/conceptvc_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/better_capital_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/boldstart_square.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/oliver-kicks.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-partner.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-presenter.png
|
||||
---
|
||||
|
||||
import { getImage, GatsbyImage } from 'gatsby-plugin-image'
|
||||
import { FeatureSnapshot } from 'components/FeatureSnapshot'
|
||||
export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-refer.png"
|
||||
|
||||
<div class="w-[calc(100%_+_4rem)] relative -mx-4 px-8 md:-mx-16 pt-32 pb-72 -mt-32 md:-mt-44">
|
||||
<div class="md:hidden absolute top-0 left-0 w-full bottom-0 opacity-40">
|
||||
<GatsbyImage image={getImage(props?.images[0])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="hidden md:block absolute top-0 left-0 w-full bottom-0">
|
||||
<GatsbyImage image={getImage(props?.images[1])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-4 w-24 md:left-16 md:w-48">
|
||||
<GatsbyImage image={getImage(props?.images[2])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 -right-4 w-28 md:right-16 md:w-60">
|
||||
<GatsbyImage image={getImage(props?.images[3])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 left-0 w-full h-24 bg-gradient-to-b from-tan/100 via-tan/85 to-tan/0"></div>
|
||||
|
||||
<div className="max-w-[849px] mx-auto text-center">
|
||||
<h1 className="text-4xl md:text-[64px] leading-none mt-0 mb-5">
|
||||
PostHog x Stripe Atlas
|
||||
</h1>
|
||||
<h2 className="text-[18px] md:text-[20px] leading-[1.4] font-semibold mb-8 !mt-5">$50k in credits (plus extras you'll actually use) <br className="hidden lg:block" />to help you get to product-market fit</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/Stripe-Atlas">Apply now</CallToAction>
|
||||
|
||||
<div className="max-w-xs rounded p-3 text-left bg-accent/100 dark:bg-accent-dark/100 border border-border dark:border-dark mx-auto mt-8 relative z-10">
|
||||
<h3 className="text-lg mb-1">How to apply:</h3>
|
||||
<ol>
|
||||
<li><a href="https://app.posthog.com/startups/Stripe-Atlas">Sign up</a> for PostHog Cloud</li>
|
||||
<li>Complete onboarding</li>
|
||||
<li>Submit the <a href="https://app.posthog.com/startups/Stripe-Atlas">application form</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-6 sm:mb-16 lg:mb-1">We've teamed up with Stripe Atlas to offer the following</h3>
|
||||
<p class="text-2xl lg:text-3xl m-0 text-center mb-6 sm:mb-16 lg:mb-8">Teams must be less than 2 years old and have less than $5 million in funding to qualify</p>
|
||||
<div class="flex justify-center">
|
||||
<ul class="m-0 p-0 list-none inline-grid sm:grid-cols-2 lg:grid-cols-2 gap-[10px] justify-evenly relative text-center sm:text-left">
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">$50,000 in PostHog credit</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
That's a lot of events, replays, API calls, survey responses, and more. It lasts a year!
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Exclusive founder merch</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
You can never have too many laptop stickers or free t-shirts, right?
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better docs with Mintlify</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
The best products deserve the best documentation. Get 50% off Mintlify for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better SDKs with Speakeasy</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
Building an API or SDK? Our pals at Speakeasy have you covered with 50% off for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Building is never just one-and-done. You always need to find ways to improve.
|
||||
<span class="text-red"> PostHog is central to how we do that at Y Combinator</span>. It helps us try ideas, measure results and make better products.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[4])} alt="Cat Li" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Cat Li</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Product & Engineering Lead, <span class="inline-block">Y Combinator</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-3 sm:mb-8 lg:mb-1">Recommended by the world's leading startup accelerators</h3>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-primary/75 dark:text-primary-dark/75 text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
</div>
|
||||
<ul class="list-none p-0 grid md:grid-cols-3 gap-4 mb-5 md:mb-10 justify-center">
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/pry_posthog_506c464b7a.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by <a href="/customers/ycombinator">Y Combinator</a>, acquired by Brex</p>
|
||||
<p class="text-sm">"PostHog isn’t just about making decisions, it's about having ideas. <span class="bg-highlight p-0.5">There are things you don’t even think of until you see the data."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/pry">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/opensauced_posthog_a180477623.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Boldstart, the partner for devs</p>
|
||||
<p class="text-sm">"Boldstart recommended PostHog to us. There’s so many things that are possible for us — but <span class="bg-highlight p-0.5">PostHog is helping us find a path."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/opensauced">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/eleven_labs_b5853d00b7.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Concept, the UK's largest fund</p>
|
||||
<p class="text-sm">"We used to have dozens of tools and dashboards. PostHog is amazing because <span class="bg-highlight p-0.5">it reins in the chaos so we have everything in one place."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/elevenlabs">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<Section>
|
||||
<h2 className="text-3xl lg:text-5xl text-center mb-0">How does PostHog for Startups compare?</h2>
|
||||
<h3 className="text-xl m-0 font-semibold opacity-75 text-center !pb-8">Well, it's the only startup program with free laptop stickers...</h3>
|
||||
<div className="overflow-x-auto -mx-5 flex justify-start lg:justify-center px-4 lg:px-0">
|
||||
<table className="w-400 mt-4" style="max-width: 1100px; font-size: 15px;">
|
||||
<thead>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td className="w-3/12"></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-pendo">Pendo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-amplitude">Amplitude</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-mixpanel">Mixpanel</a></td>
|
||||
<td className="w-2/12 text-center bg-accent dark:bg-accent-dark"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Eligibility criteria</strong></td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center"><$5m in funding and <20 staff members</td>
|
||||
<td className="text-center"><$8m in funding and less than 5 years old</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><$5m in funding and less than 2 years old</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Limitations</strong></td>
|
||||
<td className="text-center">500 monthly users</td>
|
||||
<td className="text-center">1,000 monthly sessions</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">One year duration</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Benefits</strong></td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">200,000 MTUs</td>
|
||||
<td className="text-center">$50,000 credit</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">$50,000 credit</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Open source product</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Free gifts (omg, stickers)</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Partnership opportunities</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center mt-8">
|
||||
<p><a href="/blog/tags/comparisons">Explore more product comparisons</a></p>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-md mx-auto space-y-1">
|
||||
<details>
|
||||
<summary>How do I apply?</summary>
|
||||
<p>Just sign up to a paid plan in PostHog (you're only charged for usage) and then fill in this <a href="https://app.posthog.com/startups/Stripe-Atlas">form</a>. We will apply the credit automatically if you're eligible. If you're accepted into the program, we will notify you by email. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Who's eligible? </summary>
|
||||
<p>Your company needs to be less than 2 years old and have raised less than $5m funding. You need to have signed up any time from Jan 1st 2023 onwards. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>I signed up before this deal launched, can I still get it?</summary>
|
||||
<p>Yes, but only if you signed up after Jan 1st 2023. If your startup meets the eligibility criteria but you signed up to PostHog before Jan 1st, we won't apply the credits but are still happy to enroll you in the rest of the program. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can I get this deal if I'm part of YC?</summary>
|
||||
<p>We have a separate deal for YC folks - check out Bookface. No, they don't stack!</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What if I go over the $50k limit? </summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What happens at the end of the 12 months?</summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>. You'll continue to be considered part of the program in terms of invites to office hour events, and other perks. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How do I get the Mintlify/Speakeasy discount?</summary>
|
||||
<p>Once you're accepted into the PostHog for Startups program, we'll email you with a voucher code to get you 50% off Mintlify and Speakeasy for six months.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What level of customer support do I get?</summary>
|
||||
<p>PostHog is run by a small team and, as such, we're only able to offer support to paying customers. Organizations which are part of our startup plan are therefore not eligible for high priority customer support, and only qualify for normal priority and community support. This is still the case even if you apply your credits towards a platforms add-on.</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Our portfolio companies rely on analytics to optimise their products. <span class="text-red"> Understanding user behaviours through platforms like PostHog is mission-critical.</span> The insights it provides are invaluable for founders.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[14])} alt="Oliver Kicks" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Oliver Kicks</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Partner, <span class="inline-block">Concept Ventures</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="text-center">
|
||||
|
||||
<h2 className="text-3xl lg:text-5xl pb-8">Ready to get started?</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/Stripe-Atlas">Apply now</CallToAction>
|
||||
|
||||
</div>
|
||||
@@ -1,311 +0,0 @@
|
||||
---
|
||||
title: PostHog for Startups
|
||||
showTitle: false
|
||||
showSidebar: true
|
||||
width: lg
|
||||
images:
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall-mobile.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/rockwall.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/on-belay.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/belay-on.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/cat_li.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-spotlight.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-merch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-launch.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-credit.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-heart.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/yc_logo.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/conceptvc_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/better_capital_logo.jpg
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/boldstart_square.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/oliver-kicks.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-partner.png
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-presenter.png
|
||||
---
|
||||
|
||||
import { getImage, GatsbyImage } from 'gatsby-plugin-image'
|
||||
import { FeatureSnapshot } from 'components/FeatureSnapshot'
|
||||
export const refer = "https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-refer.png"
|
||||
|
||||
<div class="w-[calc(100%_+_4rem)] relative -mx-4 px-8 md:-mx-16 pt-32 pb-72 -mt-32 md:-mt-44">
|
||||
<div class="md:hidden absolute top-0 left-0 w-full bottom-0 opacity-40">
|
||||
<GatsbyImage image={getImage(props?.images[0])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="hidden md:block absolute top-0 left-0 w-full bottom-0">
|
||||
<GatsbyImage image={getImage(props?.images[1])} alt="PostHog for startups" objectFit="cover" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 left-4 w-24 md:left-16 md:w-48">
|
||||
<GatsbyImage image={getImage(props?.images[2])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
<div class="absolute bottom-0 -right-4 w-28 md:right-16 md:w-60">
|
||||
<GatsbyImage image={getImage(props?.images[3])} alt="PostHog for startups" objectFit="contain" className="" />
|
||||
</div>
|
||||
|
||||
<div class="absolute top-0 left-0 w-full h-24 bg-gradient-to-b from-tan/100 via-tan/85 to-tan/0"></div>
|
||||
|
||||
<div className="max-w-[849px] mx-auto text-center">
|
||||
<h1 className="text-4xl md:text-[64px] leading-none mt-0 mb-5">
|
||||
PostHog x Stripe
|
||||
</h1>
|
||||
<h2 className="text-[18px] md:text-[20px] leading-[1.4] font-semibold mb-8 !mt-5">$50k in credits (plus extras you'll actually use) <br className="hidden lg:block" />to help you get to product-market fit</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/Stripe">Apply now</CallToAction>
|
||||
|
||||
<div className="max-w-xs rounded p-3 text-left bg-accent/100 dark:bg-accent-dark/100 border border-border dark:border-dark mx-auto mt-8 relative z-10">
|
||||
<h3 className="text-lg mb-1">How to apply:</h3>
|
||||
<ol>
|
||||
<li><a href="https://app.posthog.com/startups/Stripe">Sign up</a> for PostHog Cloud</li>
|
||||
<li>Complete onboarding</li>
|
||||
<li>Submit the <a href="https://app.posthog.com/startups/Stripe">application form</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-6 sm:mb-16 lg:mb-1">We've teamed up with Stripe to offer the following</h3>
|
||||
<p class="text-2xl lg:text-3xl m-0 text-center mb-6 sm:mb-16 lg:mb-8">Teams must be less than 2 years old and have less than $5 million in funding to qualify</p>
|
||||
<div class="flex justify-center">
|
||||
<ul class="m-0 p-0 list-none inline-grid sm:grid-cols-2 lg:grid-cols-2 gap-[10px] justify-evenly relative text-center sm:text-left">
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">$50,000 in PostHog credit</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
That's a lot of events, replays, API calls, survey responses, and more. It lasts a year!
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Exclusive founder merch</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
You can never have too many laptop stickers or free t-shirts, right?
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better docs with Mintlify</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
The best products deserve the best documentation. Get 50% off Mintlify for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
<li class="bg-[#E5E7E0] dark:bg-[#2C2C2C] relative md:max-w-md py-4 md:py-8 pl-4 pr-2 md:px-12 lg:px-8 rounded-2xl shadow-sm transition-colors duration-300">
|
||||
<h5 class="text-xl font-extrabold m-0 pb-1 pr-4 text-black dark:text-white">Better SDKs with Speakeasy</h5>
|
||||
<p class="m-0 text-[15px] text-gray-800 dark:text-gray-300">
|
||||
Building an API or SDK? Our pals at Speakeasy have you covered with 50% off for 6 months.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Building is never just one-and-done. You always need to find ways to improve.
|
||||
<span class="text-red"> PostHog is central to how we do that at Y Combinator</span>. It helps us try ideas, measure results and make better products.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[4])} alt="Cat Li" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Cat Li</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Product & Engineering Lead, <span class="inline-block">Y Combinator</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-2xl mx-auto">
|
||||
<h3 class="text-2xl lg:text-4xl m-0 text-center mb-3 sm:mb-8 lg:mb-1">Recommended by the world's leading startup accelerators</h3>
|
||||
<p className="m-0 dark:text-primary-dark font-semibold mt-2 md:mt-0 text-primary/75 dark:text-primary-dark/75 text-center text-xl pb-8">(And <a href="/blog/categories/startups">their startups</a> like us, too.)</p>
|
||||
</div>
|
||||
<ul class="list-none p-0 grid md:grid-cols-3 gap-4 mb-5 md:mb-10 justify-center">
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/pry_posthog_506c464b7a.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by <a href="/customers/ycombinator">Y Combinator</a>, acquired by Brex</p>
|
||||
<p class="text-sm">"PostHog isn’t just about making decisions, it's about having ideas. <span class="bg-highlight p-0.5">There are things you don’t even think of until you see the data."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/pry">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/opensauced_posthog_a180477623.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Boldstart, the partner for devs</p>
|
||||
<p class="text-sm">"Boldstart recommended PostHog to us. There’s so many things that are possible for us — but <span class="bg-highlight p-0.5">PostHog is helping us find a path."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/opensauced">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="w-full bg-accent dark:bg-accent-dark p-6 rounded">
|
||||
<div class="flex items-center mb-4">
|
||||
<img class="max-h-150 max-w-[1500px] w-full object-contain object-left" src="https://res.cloudinary.com/dmukukwp6/image/upload/eleven_labs_b5853d00b7.png" />
|
||||
</div>
|
||||
<p class="!text-xl font-bold m-0 !leading-tight !mb-2">Backed by Concept, the UK's largest fund</p>
|
||||
<p class="text-sm">"We used to have dozens of tools and dashboards. PostHog is amazing because <span class="bg-highlight p-0.5">it reins in the chaos so we have everything in one place."</span></p>
|
||||
<a class="bg-orange dark:bg-button-secondary-shadow-dark dark:border-button-secondary-dark border-[1.5px] relative top-[1px] rounded-[6px] w-auto text-primary inline-block border-button text-center group disabled:opacity-50 disabled:cursor-not-allowed" href="/customers/elevenlabs">
|
||||
<span class="relative text-center w-auto bg-white text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark border-button dark:border-orange dark:bg-dark rounded-[6px] text-[13px] font-bold px-3.5 py-1.5 translate-y-[-2px] hover:translate-y-[-3px] active:translate-y-[-1px] border-[1.5px] mx-[-1.5px] group-disabled:hover:!translate-y-[-2px] block active:transition-all active:duration-100 select-none">Read the story</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<Section>
|
||||
<h2 className="text-3xl lg:text-5xl text-center mb-0">How does PostHog for Startups compare?</h2>
|
||||
<h3 className="text-xl m-0 font-semibold opacity-75 text-center !pb-8">Well, it's the only startup program with free laptop stickers...</h3>
|
||||
<div className="overflow-x-auto -mx-5 flex justify-start lg:justify-center px-4 lg:px-0">
|
||||
<table className="w-400 mt-4" style="max-width: 1100px; font-size: 15px;">
|
||||
<thead>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td className="w-3/12"></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-pendo">Pendo</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-logrocket">LogRocket</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-amplitude">Amplitude</a></td>
|
||||
<td className="w-2/12 text-center"><a href="/blog/posthog-vs-mixpanel">Mixpanel</a></td>
|
||||
<td className="w-2/12 text-center bg-accent dark:bg-accent-dark"><strong>PostHog</strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Eligibility criteria</strong></td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center">Free plan only</td>
|
||||
<td className="text-center"><$5m in funding and <20 staff members</td>
|
||||
<td className="text-center"><$8m in funding and less than 5 years old</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><$5m in funding and less than 2 years old</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Limitations</strong></td>
|
||||
<td className="text-center">500 monthly users</td>
|
||||
<td className="text-center">1,000 monthly sessions</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="text-center">One year duration</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">One year duration</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Benefits</strong></td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">None</td>
|
||||
<td className="text-center">200,000 MTUs</td>
|
||||
<td className="text-center">$50,000 credit</td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center">$50,000 credit</td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Open source product</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Free gifts (omg, stickers)</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
<tr class="border-b border-light dark:border-dark">
|
||||
<td><strong>Partnership opportunities</strong></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="text-center"><span className="text-red text-lg">✖</span></td>
|
||||
<td className="bg-accent dark:bg-accent-dark text-center"><span className="text-green text-lg">✔</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center mt-8">
|
||||
<p><a href="/blog/tags/comparisons">Explore more product comparisons</a></p>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
<div class="max-w-screen-md mx-auto space-y-1">
|
||||
<details>
|
||||
<summary>How do I apply?</summary>
|
||||
<p>Just sign up to a paid plan in PostHog (you're only charged for usage) and then fill in this <a href="https://app.posthog.com/startups/Stripe">form</a>. We will apply the credit automatically if you're eligible. If you're accepted into the program, we will notify you by email. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Who's eligible? </summary>
|
||||
<p>Your company needs to be less than 2 years old and have raised less than $5m funding. You need to have signed up any time from Jan 1st 2023 onwards. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>I signed up before this deal launched, can I still get it?</summary>
|
||||
<p>Yes, but only if you signed up after Jan 1st 2023. If your startup meets the eligibility criteria but you signed up to PostHog before Jan 1st, we won't apply the credits but are still happy to enroll you in the rest of the program. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Can I get this deal if I'm part of YC?</summary>
|
||||
<p>We have a separate deal for YC folks - check out Bookface. No, they don't stack!</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What if I go over the $50k limit? </summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What happens at the end of the 12 months?</summary>
|
||||
<p>At that point you can move onto <a href="/pricing">another PostHog plan</a>. You'll continue to be considered part of the program in terms of invites to office hour events, and other perks. </p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How do I get the Mintlify/Speakeasy discount?</summary>
|
||||
<p>Once you're accepted into the PostHog for Startups program, we'll email you with a voucher code to get you 50% off Mintlify and Speakeasy for six months.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>What level of customer support do I get?</summary>
|
||||
<p>PostHog is run by a small team and, as such, we're only able to offer support to paying customers. Organizations which are part of our startup plan are therefore not eligible for high priority customer support, and only qualify for normal priority and community support. This is still the case even if you apply your credits towards a platforms add-on.</p>
|
||||
</details>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-24 px-5">
|
||||
|
||||
<div class="max-w-screen-lg mx-auto font-bold">
|
||||
|
||||
<blockquote class="text-2xl text-primary dark:text-primary-dark m-0 quote md:text-[32px] md:leading-tight">
|
||||
<span class="leading-tight">
|
||||
"Our portfolio companies rely on analytics to optimise their products. <span class="text-red"> Understanding user behaviours through platforms like PostHog is mission-critical.</span> The insights it provides are invaluable for founders.”
|
||||
</span>
|
||||
<footer class="flex items-center space-x-8 mt-9">
|
||||
<GatsbyImage image={getImage(props?.images[14])} alt="Oliver Kicks" objectFit="contain" style={{ maxWidth: 120, paddingRight: '20px' }} />
|
||||
<span class="flex flex-col"><cite class="not-italic text-lg md:text-xl">Oliver Kicks</cite><cite class="not-italic font-medium text-lg opacity-50 md:text-lg">Partner, <span class="inline-block">Concept Ventures</span></cite></span>
|
||||
</footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="text-center">
|
||||
|
||||
<h2 className="text-3xl lg:text-5xl pb-8">Ready to get started?</h2>
|
||||
<CallToAction href="https://app.posthog.com/startups/Stripe">Apply now</CallToAction>
|
||||
|
||||
</div>
|
||||
@@ -1,27 +1,29 @@
|
||||
## Q3 2025 Objectives
|
||||
|
||||
- Zach
|
||||
- Access control
|
||||
- Get every major model supported
|
||||
- Make sure interdependent models are supported
|
||||
- Migrate old dashboard access controls
|
||||
- Remove licensing
|
||||
- Get the wallet shipped and hand off to growth
|
||||
- Zach
|
||||
|
||||
- Yasen
|
||||
- Activity / audit log
|
||||
- Advanced activity log product
|
||||
- Make sure every major action is properly tracked
|
||||
- Review free/paid usage
|
||||
- Compliance framework requirements
|
||||
- Review Metalytics
|
||||
- Release to all customers?
|
||||
- What does it look like in the future?
|
||||
- Access control
|
||||
- Get every major model supported
|
||||
- Make sure interdependent models are supported
|
||||
- Migrate old dashboard access controls
|
||||
- Remove licensing
|
||||
- Get the wallet shipped and hand off to growth
|
||||
|
||||
- TBD
|
||||
- Platform add-ons
|
||||
- Better UI to subscribe and switch plans
|
||||
- Unsubscribe removing feature entitlements
|
||||
- Get environments beta fully rolled back
|
||||
- Case-insensitive emails
|
||||
- No project, env, org handling
|
||||
- Yasen
|
||||
|
||||
- Activity / audit log
|
||||
- Advanced activity log product
|
||||
- Make sure every major action is properly tracked
|
||||
- Review free/paid usage
|
||||
- Compliance framework requirements
|
||||
- Review Metalytics
|
||||
- Release to all customers?
|
||||
- What does it look like in the future?
|
||||
|
||||
- TBD
|
||||
- Platform packages
|
||||
- Better UI to subscribe and switch plans
|
||||
- Unsubscribe removing feature entitlements
|
||||
- Get environments beta fully rolled back
|
||||
- Case-insensitive emails
|
||||
- No project, env, org handling
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
---
|
||||
title: PostHog Tracks
|
||||
showTitle: false
|
||||
showSidebar: true
|
||||
width: md
|
||||
images:
|
||||
- >-
|
||||
https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/startup-hogs.png
|
||||
---
|
||||
|
||||
import { StaticImage } from 'gatsby-plugin-image'
|
||||
import { getImage, GatsbyImage } from 'gatsby-plugin-image'
|
||||
import CommunityCTA from 'components/CommunityCTA'
|
||||
|
||||
<Hero
|
||||
title="PostHog Tracks"
|
||||
subtitle="Curated lesson tracks from our engineers and users, to help you build better products"
|
||||
/>
|
||||
|
||||
PostHog Tracks is a curated course of tutorials and other lessons which cover common uses for particular roles, as well as general advice for all users - and it's constantly expanding!
|
||||
|
||||
<p class="mt-4 pb-12 flex space-x-2 items-center justify-center">
|
||||
<CallToAction href="/tutorials">Browse all tutorials</CallToAction>
|
||||
<CallToAction href="/questions" type="outline">Ask a question</CallToAction>
|
||||
</p>
|
||||
|
||||
<h3 className="mb-0">PostHog 101</h3>
|
||||
|
||||
Want a quick summary of the essential info? Look no further than PostHog 101!
|
||||
|
||||
<TutorialsSlider slugs={[
|
||||
"/tutorials/non-technical-guide-to-data",
|
||||
"/tutorials/event-tracking-guide",
|
||||
"/tutorials/regex-basics",
|
||||
"/tutorials/identifying-users-guide",
|
||||
"/tutorials/next-steps-after-installing"
|
||||
]} />
|
||||
|
||||
<br />
|
||||
|
||||
<h3 className="mb-0">PostHog for <span className="text-red">product engineers</span></h3>
|
||||
|
||||
Are you part-engineer, part-product person? This is the lesson track for you!
|
||||
|
||||
<TutorialsSlider slugs={[
|
||||
"/tutorials/multiple-environments",
|
||||
"/tutorials/canary-release",
|
||||
"/tutorials/build-your-own-posthog-app",
|
||||
"/tutorials/new-user-experiments",
|
||||
"/tutorials/feature-retention",
|
||||
"/tutorials/explore-insights-session-recordings"
|
||||
]} />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h3 className="mb-0">PostHog for <span className="text-red">front-end developers</span></h3>
|
||||
|
||||
Want to build site apps and design products users love? We can help.
|
||||
|
||||
<TutorialsSlider slugs={[
|
||||
"/tutorials/test-frontend-feature-flags",
|
||||
"/tutorials/react-popups",
|
||||
"/tutorials/vue-cookie-banner",
|
||||
"/tutorials/build-site-app",
|
||||
"/tutorials/cookieless-tracking"
|
||||
]} />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h3 className="mb-0">PostHog for <span className="text-red">product managers</span></h3>
|
||||
|
||||
Find the right users to talk to, organize interviews and gather intelligence.
|
||||
|
||||
<TutorialsSlider slugs={[
|
||||
"/tutorials/churn-rate",
|
||||
"/tutorials/feature-retention",
|
||||
"/tutorials/feedback-interviews-site-apps",
|
||||
"/tutorials/stripe-payment-data",
|
||||
"/tutorials/explore-insights-session-recordings"
|
||||
]} />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<CommunityCTA />
|
||||
|
||||
<section class="my-12 px-5">
|
||||
<div class="max-w-screen-md mx-auto">
|
||||
<h3 class="text-2xl sm:text-4xl lg:text-5xl xl:text-6xl m-0 text-center mb-0">The PostHog Way</h3>
|
||||
<p class="text-center p-4">We're open source, fully remote and we believe in transparency. Part of what's helped PostHog ship so fast is that we share as much information as we can, including about the way we work.</p>
|
||||
<ul class="p-0">
|
||||
<li class="list-none px-4 py-2"><a href="/blog/interview-snapshot-guide">How to turn user interviews into actionable snapshots</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/transparent-enterprise-pricing">Why we ditched 'talk to sales' for transparent pricing</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/posthog-first-five">What we learned about hiring from our first five employees</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/how-to-run-a-transparent-company">How to run a transparent startup</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/making-something-people-want">How we made something people want</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/startup-ops-toolkit">The ops toolkit for early-stage startups</a></li>
|
||||
<li class="list-none px-4 py-2"><a href="/blog/startup-finance-without-finance">How to run finance at your startup without hiring a finance person</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
@@ -23,7 +23,7 @@ Once your survey is created, submit a few sample responses.
|
||||
|
||||
You have two options for creating your Zap and setting its trigger:
|
||||
|
||||
### Option 1: Via the PostHog app in Zapier <span class="bg-gray-accent-light dark:bg-gray-accent-dark text-gray font-semibold align-middle text-sm p-1 rounded">recommended</span>
|
||||
### Option 1: Via the PostHog app in Zapier <span class="bg-accent text-gray font-semibold align-middle text-sm p-1 rounded">recommended</span>
|
||||
|
||||
1. In PostHog, go to the [actions tab](https://us.posthog.com/project/data-management/actions).
|
||||
2. Click **New action** and then **From event or pageview**.
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import React from 'react'
|
||||
import { initKea, wrapElement } from './kea'
|
||||
import './src/styles/global.css'
|
||||
import HandbookLayout from './src/templates/Handbook'
|
||||
import Job from './src/templates/Job'
|
||||
import Posts from './src/components/Edition/Posts'
|
||||
import { Provider as ToastProvider } from './src/context/toast'
|
||||
import { Provider as ToastProvider } from './src/context/Toast'
|
||||
import { RouteUpdateArgs } from 'gatsby'
|
||||
import { UserProvider } from './src/hooks/useUser'
|
||||
import { ChatProvider } from './src/hooks/useChat'
|
||||
|
||||
import Wrapper from './src/components/Wrapper'
|
||||
import { Provider } from './src/context/App'
|
||||
initKea(false)
|
||||
|
||||
export const wrapRootElement = ({ element }) => (
|
||||
<UserProvider>
|
||||
<ToastProvider>
|
||||
<ChatProvider>{wrapElement({ element })}</ChatProvider>
|
||||
</ToastProvider>
|
||||
</UserProvider>
|
||||
<ToastProvider>
|
||||
<UserProvider>{wrapElement({ element })}</UserProvider>
|
||||
</ToastProvider>
|
||||
)
|
||||
|
||||
export const onRouteUpdate = ({ location, prevLocation }: RouteUpdateArgs) => {
|
||||
// This is checked and set on initial load in the body script set in gatsby-ssr.js
|
||||
// Checking for prevLocation prevents this from happening twice
|
||||
@@ -39,30 +35,11 @@ export const onRouteUpdate = ({ location, prevLocation }: RouteUpdateArgs) => {
|
||||
window?.posthog?.capture('$pageview')
|
||||
}
|
||||
}
|
||||
export const wrapPageElement = ({ element, props }) => {
|
||||
const slug = props.location.pathname.substring(1)
|
||||
return !/^posts\/new|^posts\/(.*)\/edit/.test(slug) &&
|
||||
(props.pageContext.post || /^posts|^changelog\/(.*?)\//.test(slug)) ? (
|
||||
<Posts {...props}>{element}</Posts>
|
||||
) : props.custom404 || !props.data || props.pageContext.ignoreWrapper ? (
|
||||
element
|
||||
) : /^handbook|^docs\/(?!api)|^manual/.test(slug) &&
|
||||
![
|
||||
'docs/api/post-only-endpoints',
|
||||
'docs/api/user',
|
||||
'docs/integrations',
|
||||
'docs/product-analytics',
|
||||
'docs/session-replay',
|
||||
'docs/feature-flags',
|
||||
'docs/experiments',
|
||||
'docs/data',
|
||||
].includes(slug) ? (
|
||||
<HandbookLayout {...props} />
|
||||
) : /^session-replay|^product-analytics|^feature-flags|^experiments|^product-os/.test(slug) ? (
|
||||
<Product {...props} />
|
||||
) : /^careers\//.test(slug) ? (
|
||||
<Job {...props} />
|
||||
) : (
|
||||
element
|
||||
|
||||
export const wrapPageElement = ({ element, props: { location } }) => {
|
||||
return (
|
||||
<Provider element={element} location={location}>
|
||||
<Wrapper />
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
||||
194
gatsby-config.js
194
gatsby-config.js
@@ -50,6 +50,9 @@ const getQuestionPages = async (base) => {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
flags: {
|
||||
DEV_SSR: false,
|
||||
},
|
||||
siteMetadata: {
|
||||
title: 'PostHog',
|
||||
titleTemplate: '%s',
|
||||
@@ -101,7 +104,6 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
'gatsby-plugin-react-helmet',
|
||||
`gatsby-plugin-sass`,
|
||||
`gatsby-plugin-smoothscroll`,
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
@@ -277,100 +279,100 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-plugin-feed`,
|
||||
options: {
|
||||
setup: (options) => ({
|
||||
...options,
|
||||
custom_namespaces: {
|
||||
blog: 'https://posthog.com/blog',
|
||||
},
|
||||
}),
|
||||
query: `
|
||||
{
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
description
|
||||
siteUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
feeds: [
|
||||
{
|
||||
serialize: ({ query: { site, allMdx } }) => {
|
||||
let {
|
||||
siteMetadata: { siteUrl },
|
||||
} = site
|
||||
// {
|
||||
// resolve: `gatsby-plugin-feed`,
|
||||
// options: {
|
||||
// setup: (options) => ({
|
||||
// ...options,
|
||||
// custom_namespaces: {
|
||||
// blog: 'https://posthog.com/blog',
|
||||
// },
|
||||
// }),
|
||||
// query: `
|
||||
// {
|
||||
// site {
|
||||
// siteMetadata {
|
||||
// title
|
||||
// description
|
||||
// siteUrl
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// feeds: [
|
||||
// {
|
||||
// serialize: ({ query: { site, allMdx } }) => {
|
||||
// let {
|
||||
// siteMetadata: { siteUrl },
|
||||
// } = site
|
||||
|
||||
let allMdxs = allMdx.edges.map((edge) => {
|
||||
let { node } = edge
|
||||
let { frontmatter, excerpt, slug, id, html } = node
|
||||
let { date, title, authors, featuredImage } = frontmatter
|
||||
return {
|
||||
description: excerpt,
|
||||
date,
|
||||
title,
|
||||
url: `${siteUrl}/${slug}`,
|
||||
guid: id,
|
||||
author: authors && authors[0].name,
|
||||
custom_elements: [
|
||||
{
|
||||
'content:encoded': {
|
||||
_cdata: html,
|
||||
},
|
||||
},
|
||||
],
|
||||
enclosure: {
|
||||
url: featuredImage ? `${siteUrl}${featuredImage.publicURL}` : null,
|
||||
},
|
||||
}
|
||||
})
|
||||
// let allMdxs = allMdx.edges.map((edge) => {
|
||||
// let { node } = edge
|
||||
// let { frontmatter, excerpt, slug, id, html } = node
|
||||
// let { date, title, authors, featuredImage } = frontmatter
|
||||
// return {
|
||||
// description: excerpt,
|
||||
// date,
|
||||
// title,
|
||||
// url: `${siteUrl}/${slug}`,
|
||||
// guid: id,
|
||||
// author: authors && authors[0].name,
|
||||
// custom_elements: [
|
||||
// {
|
||||
// 'content:encoded': {
|
||||
// _cdata: html,
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// enclosure: {
|
||||
// url: featuredImage ? `${siteUrl}${featuredImage.publicURL}` : null,
|
||||
// },
|
||||
// }
|
||||
// })
|
||||
|
||||
return allMdxs
|
||||
},
|
||||
query: `
|
||||
{
|
||||
allMdx(
|
||||
sort: { order: DESC, fields: [frontmatter___date] }
|
||||
filter: { frontmatter: { rootPage: { eq: "/blog" } } }
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
slug
|
||||
html
|
||||
excerpt(pruneLength: 150)
|
||||
frontmatter {
|
||||
date(formatString: "MMMM DD, YYYY")
|
||||
title
|
||||
featuredImage {
|
||||
publicURL
|
||||
}
|
||||
authors: authorData {
|
||||
handle
|
||||
name
|
||||
role
|
||||
link_type
|
||||
link_url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
output: '/rss.xml',
|
||||
title: "PostHog's RSS Feed",
|
||||
// optional configuration to insert feed reference in pages:
|
||||
// if `string` is used, it will be used to create RegExp and then test if pathname of
|
||||
// current page satisfied this regular expression;
|
||||
// if not provided or `undefined`, all pages will have feed reference inserted
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// return allMdxs
|
||||
// },
|
||||
// query: `
|
||||
// {
|
||||
// allMdx(
|
||||
// sort: { order: DESC, fields: [frontmatter___date] }
|
||||
// filter: { frontmatter: { rootPage: { eq: "/blog" } } }
|
||||
// ) {
|
||||
// edges {
|
||||
// node {
|
||||
// id
|
||||
// slug
|
||||
// html
|
||||
// excerpt(pruneLength: 150)
|
||||
// frontmatter {
|
||||
// date(formatString: "MMMM DD, YYYY")
|
||||
// title
|
||||
// featuredImage {
|
||||
// publicURL
|
||||
// }
|
||||
// authors: authorData {
|
||||
// handle
|
||||
// name
|
||||
// role
|
||||
// link_type
|
||||
// link_url
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `,
|
||||
// output: '/rss.xml',
|
||||
// title: "PostHog's RSS Feed",
|
||||
// // optional configuration to insert feed reference in pages:
|
||||
// // if `string` is used, it will be used to create RegExp and then test if pathname of
|
||||
// // current page satisfied this regular expression;
|
||||
// // if not provided or `undefined`, all pages will have feed reference inserted
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
resolve: require.resolve(`./plugins/gatsby-transformer-cloudinary`),
|
||||
options: {
|
||||
@@ -389,9 +391,9 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-plugin-no-sourcemaps',
|
||||
},
|
||||
// {
|
||||
// resolve: 'gatsby-plugin-no-sourcemaps',
|
||||
// },
|
||||
...(!process.env.GATSBY_ALGOLIA_APP_ID || !process.env.ALGOLIA_API_KEY || !process.env.GATSBY_ALGOLIA_INDEX_NAME
|
||||
? []
|
||||
: [algoliaConfig]),
|
||||
|
||||
@@ -14,7 +14,38 @@ export { onPreBootstrap } from './gatsby/onPreBootstrap'
|
||||
// Implement the Gatsby API “onCreatePage”. This is
|
||||
// called after every page is created.
|
||||
export const onCreatePage: GatsbyNode['onCreatePage'] = async ({ page, actions }) => {
|
||||
const { createPage } = actions
|
||||
const { createPage, deletePage } = actions
|
||||
|
||||
// Add build time to credits page using environment variable
|
||||
if (page.path === '/credits/') {
|
||||
// Use Vercel's VERCEL_ENV variable or current time as fallback
|
||||
const buildDate = process.env.VERCEL_GIT_COMMIT_SHA
|
||||
? new Date() // This will be the actual build time when deployed
|
||||
: new Date()
|
||||
|
||||
const options: Intl.DateTimeFormatOptions = {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
hour12: true,
|
||||
timeZone: 'America/Los_Angeles'
|
||||
}
|
||||
const buildTime = buildDate.toLocaleString('en-US', options)
|
||||
|
||||
deletePage(page)
|
||||
createPage({
|
||||
...page,
|
||||
context: {
|
||||
...page.context,
|
||||
buildTime,
|
||||
// Also pass the commit SHA if available for debugging
|
||||
commitSha: process.env.VERCEL_GIT_COMMIT_SHA?.substring(0, 7) || 'local',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (page.path.match(/^\/community\/profiles/)) {
|
||||
page.matchPath = '/community/profiles/*'
|
||||
createPage(page)
|
||||
@@ -45,7 +76,6 @@ export const onCreateWebpackConfig: GatsbyNode['onCreateWebpackConfig'] = ({ sta
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
exports.createPages = async ({ actions }) => {
|
||||
const { createPage } = actions
|
||||
|
||||
|
||||
@@ -8,48 +8,23 @@
|
||||
const React = require('react')
|
||||
|
||||
import { initKea, wrapElement } from './kea'
|
||||
import HandbookLayout from './src/templates/Handbook'
|
||||
import Job from './src/templates/Job'
|
||||
import { UserProvider } from './src/hooks/useUser'
|
||||
import Posts from './src/components/Edition/Posts'
|
||||
import { Provider as ToastProvider } from './src/context/toast'
|
||||
import { ChatProvider } from './src/hooks/useChat'
|
||||
import Chat from './src/components/Chat'
|
||||
export const wrapPageElement = ({ element, props }) => {
|
||||
const slug = props.location.pathname.substring(1)
|
||||
initKea(true, props.location)
|
||||
import Wrapper from './src/components/Wrapper'
|
||||
import { Provider } from './src/context/App'
|
||||
import { Provider as ToastProvider } from './src/context/Toast'
|
||||
|
||||
export const wrapRootElement = ({ element }) => (
|
||||
<ToastProvider>
|
||||
<UserProvider>{wrapElement({ element })}</UserProvider>
|
||||
</ToastProvider>
|
||||
)
|
||||
|
||||
export const wrapPageElement = ({ element, props: { location } }) => {
|
||||
initKea(true, location)
|
||||
return (
|
||||
<UserProvider>
|
||||
<ChatProvider>
|
||||
{wrapElement({
|
||||
element:
|
||||
!/^posts\/new|^posts\/(.*)\/edit/.test(slug) &&
|
||||
(props.pageContext.post || /^posts|^changelog\/(.*?)\//.test(slug)) ? (
|
||||
<Posts {...props}>{element}</Posts>
|
||||
) : props.custom404 || !props.data || props.pageContext.ignoreWrapper ? (
|
||||
element
|
||||
) : /^handbook|^docs\/(?!api)|^manual/.test(slug) &&
|
||||
![
|
||||
'docs/api/post-only-endpoints',
|
||||
'docs/api/user',
|
||||
'docs/integrations',
|
||||
'docs/product-analytics',
|
||||
'docs/session-replay',
|
||||
'docs/feature-flags',
|
||||
'docs/experiments',
|
||||
'docs/data',
|
||||
].includes(slug) ? (
|
||||
<HandbookLayout {...props} />
|
||||
) : /^session-replay|^product-analytics|^feature-flags|^experiments|^product-os/.test(slug) ? (
|
||||
<Product {...props} />
|
||||
) : /^careers\//.test(slug) ? (
|
||||
<Job {...props} />
|
||||
) : (
|
||||
element
|
||||
),
|
||||
})}
|
||||
</ChatProvider>
|
||||
</UserProvider>
|
||||
<Provider element={element} location={location}>
|
||||
<Wrapper />
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -72,21 +47,30 @@ export const onRenderBody = function ({ setPreBodyComponents }) {
|
||||
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
darkQuery.addListener(function (e) {
|
||||
if (!localStorage.getItem('theme')) {
|
||||
window.__setPreferredTheme(e.matches ? 'dark' : 'light')
|
||||
window.__setPreferredTheme('system')
|
||||
}
|
||||
})
|
||||
try {
|
||||
preferredTheme =
|
||||
(localStorage.getItem('theme') || (darkQuery.matches ? 'dark' : 'light')) ||
|
||||
'light'
|
||||
localStorage.getItem('theme') || 'light'
|
||||
} catch (err) {}
|
||||
window.__setPreferredTheme = function (newTheme) {
|
||||
window.__setPreferredTheme = function (theme) {
|
||||
const newTheme = theme === 'system' ? (darkQuery.matches ? 'dark' : 'light') : theme
|
||||
setTheme(newTheme)
|
||||
try {
|
||||
localStorage.setItem('theme', newTheme)
|
||||
} catch (err) {}
|
||||
return newTheme
|
||||
}
|
||||
setTheme(preferredTheme)
|
||||
setTheme(preferredTheme === 'system' ? (darkQuery.matches ? 'dark' : 'light') : preferredTheme)
|
||||
|
||||
// Set initial skin value
|
||||
try {
|
||||
const savedSkin = JSON.parse(localStorage.getItem('siteSettings') || '{}').skinMode || 'modern'
|
||||
document.body.setAttribute('data-skin', savedSkin)
|
||||
const savedWallpaper = JSON.parse(localStorage.getItem('siteSettings') || '{}').wallpaper || 'keyboard-garden'
|
||||
document.body.setAttribute('data-wallpaper', savedWallpaper)
|
||||
} catch (err) {}
|
||||
})()
|
||||
`,
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ const Slugger = require('github-slugger')
|
||||
const markdownLinkExtractor = require('markdown-link-extractor')
|
||||
|
||||
export const createPages: GatsbyNode['createPages'] = async ({ actions: { createPage }, graphql }) => {
|
||||
const BlogPostTemplate = path.resolve(`src/templates/BlogPost.js`)
|
||||
const BlogPostTemplate = path.resolve(`src/templates/BlogPost.tsx`)
|
||||
const PlainTemplate = path.resolve(`src/templates/Plain.js`)
|
||||
const BlogCategoryTemplate = path.resolve(`src/templates/BlogCategory.tsx`)
|
||||
const BlogTagTemplate = path.resolve(`src/templates/BlogTag.tsx`)
|
||||
@@ -22,7 +22,7 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
|
||||
const ChangelogTemplate = path.resolve(`src/templates/Changelog.tsx`)
|
||||
const PostListingTemplate = path.resolve(`src/templates/PostListing.tsx`)
|
||||
const PaginationTemplate = path.resolve(`src/templates/Pagination.tsx`)
|
||||
|
||||
const HubTagTemplate = path.resolve(`src/templates/Hub/Tag.tsx`)
|
||||
// Tutorials
|
||||
const TutorialsTemplate = path.resolve(`src/templates/tutorials/index.tsx`)
|
||||
const TutorialTemplate = path.resolve(`src/templates/tutorials/Tutorial.tsx`)
|
||||
@@ -40,13 +40,18 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
|
||||
{
|
||||
allMdx(
|
||||
filter: {
|
||||
fileAbsolutePath: { regex: "/^((?!contents/teams/).)*$/" }
|
||||
frontmatter: { title: { ne: "" } }
|
||||
fileAbsolutePath: {
|
||||
regex: "/^((?!contents/teams/|contents/about.mdx|contents/media-contents.mdx).)*$/"
|
||||
}
|
||||
frontmatter: { title: { nin: [""] }, template: { nin: ["custom"] } }
|
||||
}
|
||||
) {
|
||||
nodes {
|
||||
id
|
||||
slug
|
||||
frontmatter {
|
||||
template
|
||||
}
|
||||
}
|
||||
}
|
||||
handbook: allMdx(
|
||||
@@ -281,7 +286,11 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
postCategories: allPostCategory(filter: { attributes: { folder: { ne: null } } }) {
|
||||
postCategories: allPostCategory(
|
||||
filter: {
|
||||
attributes: { folder: { nin: [null, "customers", "changelog"] }, label: { ne: "Customers" } }
|
||||
}
|
||||
) {
|
||||
nodes {
|
||||
attributes {
|
||||
label
|
||||
@@ -501,101 +510,102 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
|
||||
})
|
||||
})
|
||||
|
||||
if (process.env.VERCEL_ENV !== 'preview') {
|
||||
const categories = {}
|
||||
result.data.categories.categories.forEach(({ category, totalCount }) => {
|
||||
const slug = slugify(category, { lower: true })
|
||||
const base = `/blog/categories/${slug}`
|
||||
categories[category] = {
|
||||
slug,
|
||||
url: base,
|
||||
}
|
||||
const categories = {}
|
||||
result.data.categories.categories.forEach(({ category, totalCount }) => {
|
||||
const slug = slugify(category, { lower: true })
|
||||
const base = `/blog/categories/${slug}`
|
||||
categories[category] = {
|
||||
slug,
|
||||
url: base,
|
||||
}
|
||||
|
||||
createPaginatedPages({ totalCount, base, template: BlogCategoryTemplate, extraContext: { category, slug } })
|
||||
})
|
||||
createPaginatedPages({ totalCount, base, template: BlogCategoryTemplate, extraContext: { category, slug } })
|
||||
})
|
||||
|
||||
result.data.categories.tags.forEach(({ tag, totalCount }) => {
|
||||
const slug = slugify(tag, { lower: true })
|
||||
const base = `/blog/tags/${slug}`
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount,
|
||||
base,
|
||||
template: BlogTagTemplate,
|
||||
extraContext: { tag, slug },
|
||||
})
|
||||
})
|
||||
result.data.categories.tags.forEach(({ tag, totalCount }) => {
|
||||
const slug = slugify(tag, { lower: true })
|
||||
const base = `/blog/tags/${slug}`
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.blogPosts.totalCount,
|
||||
base: '/blog/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/blog/',
|
||||
title: 'Blog',
|
||||
},
|
||||
totalCount,
|
||||
base,
|
||||
template: BlogTagTemplate,
|
||||
extraContext: { tag, slug },
|
||||
})
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.blogPosts.totalCount,
|
||||
base: '/blog/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/blog/',
|
||||
title: 'Blog',
|
||||
},
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.library.totalCount,
|
||||
base: '/library/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/library/',
|
||||
title: 'Library',
|
||||
},
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.founders.totalCount,
|
||||
base: '/founders/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/founders/',
|
||||
title: 'Founders',
|
||||
},
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.productEngineers.totalCount,
|
||||
base: '/product-engineers/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/product-engineers/',
|
||||
title: 'Product engineers',
|
||||
},
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.features.totalCount,
|
||||
base: '/features/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/features/',
|
||||
title: 'Features',
|
||||
},
|
||||
})
|
||||
|
||||
result.data.tutorials.categories.forEach(({ category, totalCount }) => {
|
||||
const slug = slugify(category, { lower: true })
|
||||
const base = `/tutorials/categories/${slug}`
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.library.totalCount,
|
||||
base: '/library/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/library/',
|
||||
title: 'Library',
|
||||
},
|
||||
totalCount,
|
||||
base,
|
||||
template: TutorialsCategoryTemplate,
|
||||
extraContext: { activeFilter: category, slug },
|
||||
})
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.founders.totalCount,
|
||||
base: '/founders/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/founders/',
|
||||
title: 'Founders',
|
||||
},
|
||||
})
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.tutorials.totalCount,
|
||||
base: '/tutorials/all',
|
||||
template: TutorialsTemplate,
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.productEngineers.totalCount,
|
||||
base: '/product-engineers/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/product-engineers/',
|
||||
title: 'Product engineers',
|
||||
},
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.features.totalCount,
|
||||
base: '/features/all',
|
||||
template: PaginationTemplate,
|
||||
extraContext: {
|
||||
regex: '/^/features/',
|
||||
title: 'Features',
|
||||
},
|
||||
})
|
||||
|
||||
result.data.tutorials.categories.forEach(({ category, totalCount }) => {
|
||||
const slug = slugify(category, { lower: true })
|
||||
const base = `/tutorials/categories/${slug}`
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount,
|
||||
base,
|
||||
template: TutorialsCategoryTemplate,
|
||||
extraContext: { activeFilter: category, slug },
|
||||
})
|
||||
})
|
||||
|
||||
createPaginatedPages({
|
||||
totalCount: result.data.tutorials.totalCount,
|
||||
base: '/tutorials/all',
|
||||
template: TutorialsTemplate,
|
||||
})
|
||||
|
||||
result.data.postCategories.nodes.forEach(
|
||||
({ attributes: { folder: categoryFolder, label: categoryLabel, post_tags } }) => {
|
||||
result.data.postCategories.nodes.forEach(
|
||||
({ attributes: { folder: categoryFolder, label: categoryLabel, post_tags } }) => {
|
||||
const isHub = categoryFolder === 'founders' || categoryFolder === 'product-engineers'
|
||||
if (!isHub) {
|
||||
createPage({
|
||||
path: `/${categoryFolder}`,
|
||||
component: PostListingTemplate,
|
||||
@@ -603,24 +613,26 @@ export const createPages: GatsbyNode['createPages'] = async ({ actions: { create
|
||||
post: true,
|
||||
title: categoryLabel,
|
||||
article: false,
|
||||
root: categoryFolder,
|
||||
},
|
||||
})
|
||||
|
||||
post_tags?.data?.forEach(({ attributes: { label: tagLabel } }) => {
|
||||
createPage({
|
||||
path: `/${categoryFolder}/${slugify(tagLabel, { lower: true, strict: true })}`,
|
||||
component: PostListingTemplate,
|
||||
context: {
|
||||
selectedTag: tagLabel,
|
||||
post: true,
|
||||
title: tagLabel,
|
||||
article: false,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
post_tags?.data?.forEach(({ attributes: { label: tagLabel } }) => {
|
||||
createPage({
|
||||
path: `/${categoryFolder}/${slugify(tagLabel, { lower: true, strict: true })}`,
|
||||
component: isHub ? HubTagTemplate : PostListingTemplate,
|
||||
context: {
|
||||
selectedTag: tagLabel,
|
||||
post: true,
|
||||
title: tagLabel,
|
||||
article: false,
|
||||
root: categoryFolder,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
createPosts(result.data.handbook.nodes, 'handbook', HandbookTemplate, { name: 'Handbook', url: '/handbook' })
|
||||
createPosts(result.data.docs.nodes, 'docs', HandbookTemplate, { name: 'Docs', url: '/docs' })
|
||||
|
||||
@@ -15,6 +15,18 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
slug: String
|
||||
contributors: [Contributors]
|
||||
appConfig: [AppConfig]
|
||||
commits: [Commit]
|
||||
}
|
||||
type Commit {
|
||||
author: GitHubUser
|
||||
date: Date
|
||||
message: String
|
||||
url: String
|
||||
}
|
||||
type GitHubUser {
|
||||
avatar_url: String
|
||||
html_url: String
|
||||
login: String
|
||||
}
|
||||
type AshbyJobPostingTableOfContents {
|
||||
value: String,
|
||||
@@ -290,6 +302,11 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
is_plan_default: Boolean
|
||||
unit: String
|
||||
}
|
||||
type SqueakTeam implements Node {
|
||||
tagline: String
|
||||
description: String
|
||||
createdAt: Date
|
||||
}
|
||||
`)
|
||||
createTypes([
|
||||
schema.buildObjectType({
|
||||
@@ -322,6 +339,7 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
type ShopifyMetafield implements Node {
|
||||
key: String!
|
||||
value: String!
|
||||
namespace: String!
|
||||
}
|
||||
type ShopifyProductVariant implements Node {
|
||||
availableForSale: Boolean!
|
||||
@@ -361,6 +379,12 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
height: Int
|
||||
originalSrc: String
|
||||
}
|
||||
type ShopifyProductCategory {
|
||||
id: String!
|
||||
name: String!
|
||||
level: Int!
|
||||
parentId: String
|
||||
}
|
||||
type ShopifyProduct implements Node {
|
||||
descriptionHtml: String
|
||||
description: String!
|
||||
@@ -379,6 +403,8 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
totalInventory: Int!
|
||||
featuredImage: ShopifyImage @proxy(from: "featuredMedia.preview.image")
|
||||
imageProducts: [ShopifyProduct]
|
||||
createdAt: Date
|
||||
category: ShopifyProductCategory
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import chromium from 'chrome-aws-lambda'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import blogTemplate from '../src/templates/OG/blog.js'
|
||||
import docsHandbookTemplate from '../src/templates/OG/docs-handbook.js'
|
||||
import customerTemplate from '../src/templates/OG/customer.js'
|
||||
import careersTemplate from '../src/templates/OG/careers.js'
|
||||
import jobTemplate from '../src/templates/OG/job.js'
|
||||
import { flattenMenu } from './utils'
|
||||
import fetch from 'node-fetch'
|
||||
import { GatsbyNode } from 'gatsby'
|
||||
import pLimit from 'p-limit'
|
||||
@@ -24,6 +18,80 @@ import { SdkReferenceData } from '../src/templates/sdk/SdkReference.js'
|
||||
|
||||
const limit = pLimit(10)
|
||||
|
||||
const createOGImages = async () => {
|
||||
console.log('Creating OG images')
|
||||
|
||||
const dir = path.resolve(__dirname, '../public/og-images')
|
||||
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
|
||||
|
||||
const browserFetcher = chromium.puppeteer.createBrowserFetcher()
|
||||
const revisionInfo = await browserFetcher.download('982053')
|
||||
|
||||
const browser = await chromium.puppeteer.launch({
|
||||
args: await chromium.args,
|
||||
executablePath: revisionInfo.executablePath || process.env.PUPPETEER_EXECUTABLE_PATH,
|
||||
headless: true,
|
||||
defaultViewport: {
|
||||
width: 1200,
|
||||
height: 630,
|
||||
},
|
||||
})
|
||||
const page = await browser.newPage()
|
||||
await page.setViewport({
|
||||
width: 1200,
|
||||
height: 630,
|
||||
})
|
||||
|
||||
const publicDir = path.resolve(__dirname, '../public')
|
||||
await page.setRequestInterception(true)
|
||||
|
||||
page.on('request', (request) => {
|
||||
const url = request.url()
|
||||
if (url.startsWith('file:///') && !url.includes(publicDir)) {
|
||||
const pathname = url.replace('file:///', '')
|
||||
const newUrl = `file://${publicDir}/${pathname}`
|
||||
request.continue({ url: newUrl })
|
||||
} else {
|
||||
request.continue()
|
||||
}
|
||||
})
|
||||
|
||||
async function createOG({ slug }) {
|
||||
const htmlFilePath = path.resolve(__dirname, `../public/${slug}/index.html`)
|
||||
console.log(`Creating OG image for: ${htmlFilePath}`)
|
||||
|
||||
await page.goto(`file://${htmlFilePath}`, {
|
||||
waitUntil: ['domcontentloaded', 'networkidle0'],
|
||||
})
|
||||
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await page.addStyleTag({
|
||||
content: `
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 630px;
|
||||
}
|
||||
.ToastRoot {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
await page.screenshot({
|
||||
type: 'jpeg',
|
||||
path: `${dir}/${slug.replace(/\//g, '')}.jpeg`,
|
||||
quality: 100,
|
||||
})
|
||||
}
|
||||
|
||||
await createOG({ slug: 'careers-og' })
|
||||
|
||||
console.log('Finished creating OG images')
|
||||
|
||||
await browser.close()
|
||||
}
|
||||
|
||||
const createOrUpdateStrapiPosts = async (posts, roadmaps) => {
|
||||
const apiHost = process.env.GATSBY_SQUEAK_API_HOST
|
||||
|
||||
@@ -351,6 +419,8 @@ export const onPostBuild: GatsbyNode['onPostBuild'] = async ({ graphql }) => {
|
||||
|
||||
console.log('Running onPostBuild tasks')
|
||||
|
||||
await createOGImages()
|
||||
|
||||
const { data } = await graphql(`
|
||||
query {
|
||||
allRoadmap(filter: { complete: { ne: false } }) {
|
||||
@@ -520,171 +590,4 @@ export const onPostBuild: GatsbyNode['onPostBuild'] = async ({ graphql }) => {
|
||||
`)
|
||||
|
||||
await createOrUpdateStrapiPosts(data.allMDXPosts.nodes, data.allRoadmap.nodes)
|
||||
|
||||
const dir = path.resolve(__dirname, '../public/og-images')
|
||||
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })
|
||||
const fontDir = path.resolve(__dirname, '../fonts')
|
||||
if (!fs.existsSync(fontDir)) fs.mkdirSync(fontDir)
|
||||
const res = await fetch('https://d27nj4tzr3d5tm.cloudfront.net/Website-Assets/Fonts/Matter/MatterSQVF.woff', {
|
||||
headers: {
|
||||
Origin: 'https://posthog.com',
|
||||
},
|
||||
})
|
||||
await new Promise((resolve, reject) => {
|
||||
const fileStream = fs.createWriteStream(path.resolve(__dirname, '../fonts/matter.woff'))
|
||||
res.body.pipe(fileStream)
|
||||
res.body.on('error', (err) => {
|
||||
reject(err)
|
||||
})
|
||||
fileStream.on('finish', function () {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
const font = fs.readFileSync(path.resolve(__dirname, '../fonts/matter.woff'), {
|
||||
encoding: 'base64',
|
||||
})
|
||||
|
||||
const browserFetcher = chromium.puppeteer.createBrowserFetcher()
|
||||
const revisionInfo = await browserFetcher.download('982053')
|
||||
|
||||
const browser = await chromium.puppeteer.launch({
|
||||
args: await chromium.args,
|
||||
executablePath: revisionInfo.executablePath || process.env.PUPPETEER_EXECUTABLE_PATH,
|
||||
headless: true,
|
||||
})
|
||||
const page = await browser.newPage()
|
||||
await page.setViewport({
|
||||
width: 1200,
|
||||
height: 630,
|
||||
})
|
||||
|
||||
async function createOG({ html, slug }) {
|
||||
await page.setContent(html, {
|
||||
waitUntil: ['domcontentloaded', 'networkidle0'],
|
||||
})
|
||||
|
||||
await page.evaluateHandle('document.fonts.ready')
|
||||
|
||||
await page.screenshot({
|
||||
type: 'jpeg',
|
||||
path: `${dir}/${slug.replace(/\//g, '')}.jpeg`,
|
||||
quality: 100,
|
||||
})
|
||||
}
|
||||
|
||||
// Blog post OG
|
||||
for (const post of data.blog.nodes) {
|
||||
const { title, authorData, featuredImage } = post.frontmatter
|
||||
const image = featuredImage?.publicURL
|
||||
const author =
|
||||
authorData &&
|
||||
authorData.map((author) => {
|
||||
const image =
|
||||
author.profile?.avatar?.url ||
|
||||
`https://res.cloudinary.com/dmukukwp6/image/upload/contributor_posthog_e8c595ea3d.png`
|
||||
return {
|
||||
...author,
|
||||
image,
|
||||
}
|
||||
})[0]
|
||||
await createOG({
|
||||
html: blogTemplate({ title, authorData: author, image, font }),
|
||||
slug: post.fields.slug,
|
||||
})
|
||||
}
|
||||
|
||||
const docsHandbookMenus = flattenMenu([...handbookSidebar, ...docsMenu.children])
|
||||
|
||||
// Docs and Handbook OG
|
||||
for (const post of [...data.docsHandbook.nodes, ...data.tutorials.nodes]) {
|
||||
const { title } = post.frontmatter
|
||||
const { timeToRead, excerpt, fields, parent } = post
|
||||
const lastUpdated = parent && parent.fields && parent.fields.lastUpdated
|
||||
if (!title || !timeToRead || !excerpt || !lastUpdated || !fields?.contributors) continue
|
||||
const contributors = fields?.contributors.map((contributor) => {
|
||||
const { avatar, username } = contributor
|
||||
return {
|
||||
username,
|
||||
avatar,
|
||||
}
|
||||
})
|
||||
let breadcrumbs = null
|
||||
docsHandbookMenus.some((item) => {
|
||||
if (item.url === fields.slug) {
|
||||
breadcrumbs = item.breadcrumb
|
||||
return true
|
||||
}
|
||||
})
|
||||
await createOG({
|
||||
html: docsHandbookTemplate({
|
||||
font,
|
||||
title,
|
||||
timeToRead,
|
||||
excerpt,
|
||||
lastUpdated,
|
||||
contributors,
|
||||
breadcrumbs: [
|
||||
{
|
||||
name: fields.slug.startsWith('/docs')
|
||||
? 'Docs'
|
||||
: fields.slug.startsWith('/tutorials')
|
||||
? 'Tutorials'
|
||||
: 'Handbook',
|
||||
},
|
||||
...(breadcrumbs || []),
|
||||
],
|
||||
}),
|
||||
slug: fields.slug,
|
||||
})
|
||||
}
|
||||
|
||||
// Customers OG
|
||||
for (const post of data.customers.nodes) {
|
||||
const { frontmatter } = post
|
||||
const featuredImage = frontmatter.featuredImage?.publicURL
|
||||
const logo = frontmatter.logo?.publicURL
|
||||
await createOG({
|
||||
html: customerTemplate({
|
||||
title: frontmatter.title,
|
||||
featuredImage,
|
||||
logo,
|
||||
font,
|
||||
}),
|
||||
slug: post.fields.slug,
|
||||
})
|
||||
}
|
||||
|
||||
// Careers OG
|
||||
await createOG({
|
||||
html: careersTemplate({ jobs: (data.careers && data.careers.nodes) || [], font }),
|
||||
slug: 'careers',
|
||||
})
|
||||
|
||||
for (const job of data.careers.nodes) {
|
||||
const {
|
||||
title,
|
||||
parent,
|
||||
fields: { slug },
|
||||
} = job
|
||||
const timezone = parent?.customFields?.find(({ title }) => title === 'Timezone(s)')?.value
|
||||
await createOG({
|
||||
html: jobTemplate({ role: title, font, timezone }),
|
||||
slug,
|
||||
})
|
||||
}
|
||||
|
||||
// Tutorials OG
|
||||
// for (const post of data.tutorials.nodes) {
|
||||
// const { featuredImage } = post.frontmatter
|
||||
// const image = fs.readFileSync(featuredImage.absolutePath, {
|
||||
// encoding: 'base64',
|
||||
// })
|
||||
// await createOG({
|
||||
// html: tutorialTemplate({ image }),
|
||||
// slug: post.fields.slug,
|
||||
// })
|
||||
// }
|
||||
|
||||
await browser.close()
|
||||
}
|
||||
|
||||
@@ -429,6 +429,7 @@ export const sourceNodes: GatsbyNode['sourceNodes'] = async ({ actions, createCo
|
||||
nodes {
|
||||
value
|
||||
key
|
||||
namespace
|
||||
}
|
||||
}
|
||||
options {
|
||||
@@ -449,6 +450,13 @@ export const sourceNodes: GatsbyNode['sourceNodes'] = async ({ actions, createCo
|
||||
title
|
||||
tags
|
||||
totalInventory
|
||||
createdAt
|
||||
category {
|
||||
id
|
||||
name
|
||||
level
|
||||
parentId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
package.json
46
package.json
@@ -5,7 +5,7 @@
|
||||
"author": "PostHog",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "20.x"
|
||||
"node": "22.x"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -18,7 +18,7 @@
|
||||
"scripts": {
|
||||
"build-move": "gatsby build && bash ./src/scripts/move-index.sh",
|
||||
"build": "gatsby build",
|
||||
"start": "TAILWIND_MODE=watch gatsby develop -H 0.0.0.0 -p 8001",
|
||||
"start": "TAILWIND_MODE=watch NODE_OPTIONS='--max_old_space_size=8192' gatsby develop -H 0.0.0.0 -p 8001",
|
||||
"serve": "gatsby serve",
|
||||
"format": "prettier --write \"**/*.{html,js,ts,tsx,json,yml,css,scss}\"",
|
||||
"clean": "gatsby clean",
|
||||
@@ -28,7 +28,8 @@
|
||||
"test-redirects": "jest scripts",
|
||||
"check-links-post-build": "node scripts/check-links-post-build.js",
|
||||
"storybook": "start-storybook -s ./static -p 6006",
|
||||
"build-storybook": "build-storybook"
|
||||
"build-storybook": "build-storybook",
|
||||
"postinstall": "patch-package"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dotlottie/react-player": "^1.6.6",
|
||||
@@ -37,11 +38,17 @@
|
||||
"@headlessui/tailwindcss": "^0.1.1",
|
||||
"@heroicons/react": "^1.0.6",
|
||||
"@hubspot/api-client": "^7.1.2",
|
||||
"@inkeep/uikit": "^0.3.19",
|
||||
"@inkeep/uikit-js": "^0.3.19",
|
||||
"@inkeep/cxkit-react": "^0.5.93",
|
||||
"@inkeep/uikit": "^0.3.20",
|
||||
"@inkeep/uikit-js": "^0.3.20",
|
||||
"@mdxeditor/editor": "^3.32.3",
|
||||
"@popperjs/core": "^2.11.2",
|
||||
"@posthog/hedgehog-mode": "^0.0.41",
|
||||
"@posthog/icons": "0.29.0",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@radix-ui/react-menubar": "^1.1.6",
|
||||
"@radix-ui/react-tabs": "^1.1.4",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@types/lodash.groupby": "^4.6.7",
|
||||
"@types/react-slick": "^0.23.10",
|
||||
@@ -73,7 +80,6 @@
|
||||
"gatsby-plugin-postcss": "^5.20.0",
|
||||
"gatsby-plugin-react-helmet": "^5.20.0",
|
||||
"gatsby-plugin-react-svg": "^3.1.0",
|
||||
"gatsby-plugin-sass": "^5.20.0",
|
||||
"gatsby-plugin-sitemap": "^5.20.0",
|
||||
"gatsby-plugin-smoothscroll": "^1.2.0",
|
||||
"gatsby-remark-autolink-headers": "^5.20.0",
|
||||
@@ -86,15 +92,19 @@
|
||||
"html-to-image": "^1.11.11",
|
||||
"instantsearch.js": "^4.49.1",
|
||||
"jsdom": "^20.0.0",
|
||||
"kea": "^3.0.2",
|
||||
"kea-loaders": "^3.0.0",
|
||||
"kea-localstorage": "^3.0.0",
|
||||
"kea-router": "^3.0.1",
|
||||
"kea-typegen": "^3.1.3",
|
||||
"jspdf": "^3.0.1",
|
||||
"kea": "^3.1.6",
|
||||
"kea-loaders": "^3.1.1",
|
||||
"kea-localstorage": "^3.1.0",
|
||||
"kea-router": "^3.1.6",
|
||||
"kea-typegen": "^3.1.6",
|
||||
"keen-slider": "^6.8.6",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.groupby": "^4.6.0",
|
||||
"lodash.uniqby": "^4.7.0",
|
||||
"lottie-react": "^2.4.1",
|
||||
"lucide-react": "^0.525.0",
|
||||
"mark.js": "^8.11.1",
|
||||
"markdown-link-extractor": "^4.0.1",
|
||||
"markdown-to-jsx": "^7.4.0",
|
||||
"md5": "^2.3.0",
|
||||
@@ -104,6 +114,7 @@
|
||||
"node-fetch": "^2.6.1",
|
||||
"p-limit": "3.1.0",
|
||||
"parse-link-header": "^2.0.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"posthog-js": "1.262.0",
|
||||
"posthog-node": "^4.2.0",
|
||||
@@ -112,8 +123,9 @@
|
||||
"puppeteer-core": "^13.0.1",
|
||||
"qs": "^6.11.1",
|
||||
"query-string": "^6.13.1",
|
||||
"radix-ui": "^1.1.3",
|
||||
"rc-slider": "^9.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react": "^18.2.0",
|
||||
"react-animate-height": "^2.0.23",
|
||||
"react-burger-menu": "^3.0.6",
|
||||
"react-calendly": "^2.2.2",
|
||||
@@ -121,7 +133,7 @@
|
||||
"react-compare-slider": "^2.1.0",
|
||||
"react-confetti": "^6.1.0",
|
||||
"react-country-flag": "^3.0.2",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-github-btn": "^1.2.1",
|
||||
"react-helmet": "^5.2.1",
|
||||
@@ -134,7 +146,7 @@
|
||||
"react-medium-image-zoom": "^4.4.3",
|
||||
"react-number-format": "^5.4.0",
|
||||
"react-popper": "^2.2.5",
|
||||
"react-redux": "^7.2.1",
|
||||
"react-redux": "^8.1.2",
|
||||
"react-scroll": "^1.8.3",
|
||||
"react-scrollspy": "^3.4.3",
|
||||
"react-simple-maps": "^3.0.0",
|
||||
@@ -182,7 +194,7 @@
|
||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||
"@tailwindcss/forms": "^0.5.2",
|
||||
"@tailwindcss/line-clamp": "^0.4.0",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/chart.js": "^2.9.31",
|
||||
"@types/gatsby-plugin-breakpoints": "^1.3.2",
|
||||
"@types/mdx-js__react": "^1.5.5",
|
||||
@@ -203,6 +215,7 @@
|
||||
"jest": "^27.0.6",
|
||||
"lint-staged": "^10.2.12",
|
||||
"postcss": "^8.4.14",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"prettier": "^2.1.0",
|
||||
"puppeteer": "^13.0.1",
|
||||
"react-dev-utils": "^11.0.4",
|
||||
@@ -218,6 +231,9 @@
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"resolutions": {
|
||||
"undici": "5.26.3"
|
||||
},
|
||||
"workspaces": [
|
||||
"plugins/*"
|
||||
],
|
||||
|
||||
26
patches/kea+3.1.6.patch
Normal file
26
patches/kea+3.1.6.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
diff --git a/node_modules/kea/lib/index.cjs.js b/node_modules/kea/lib/index.cjs.js
|
||||
index 68e14d9..9d6f0cf 100644
|
||||
--- a/node_modules/kea/lib/index.cjs.js
|
||||
+++ b/node_modules/kea/lib/index.cjs.js
|
||||
@@ -848,6 +848,8 @@ var getStoreState$1 = function getStoreState() {
|
||||
function useSelector(selector) {
|
||||
return shim.exports.useSyncExternalStore(getContext().store.subscribe, function () {
|
||||
return selector(getStoreState$1());
|
||||
+ }, function () {
|
||||
+ return selector(getStoreState$1());
|
||||
});
|
||||
}
|
||||
function useValues(logic) {
|
||||
diff --git a/node_modules/kea/lib/index.esm.js b/node_modules/kea/lib/index.esm.js
|
||||
index 7376cc6..a8f02fe 100644
|
||||
--- a/node_modules/kea/lib/index.esm.js
|
||||
+++ b/node_modules/kea/lib/index.esm.js
|
||||
@@ -822,6 +822,8 @@ var getStoreState$1 = function getStoreState() {
|
||||
function useSelector(selector) {
|
||||
return shim.exports.useSyncExternalStore(getContext().store.subscribe, function () {
|
||||
return selector(getStoreState$1());
|
||||
+ }, function () {
|
||||
+ return selector(getStoreState$1());
|
||||
});
|
||||
}
|
||||
function useValues(logic) {
|
||||
@@ -186,6 +186,7 @@ export const sourceNodes: GatsbyNode['sourceNodes'] = async (
|
||||
image: true,
|
||||
},
|
||||
},
|
||||
tagline: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -392,6 +393,7 @@ export const createSchemaCustomization: GatsbyNode['createSchemaCustomization']
|
||||
title: String!
|
||||
description: String!
|
||||
image: StrapiImage
|
||||
tagline: String!
|
||||
slug: String!
|
||||
dateCompleted: Date @dateformat
|
||||
projectedCompletion: Date @dateformat
|
||||
|
||||
@@ -26,7 +26,11 @@ exports.onPreInit = async function (_, options) {
|
||||
const { data, meta } = strapiPages
|
||||
if (data) {
|
||||
data.forEach(({ id, attributes }) => {
|
||||
files[attributes.path] = { contributors: attributes.contributors, lastUpdated: attributes.lastUpdated }
|
||||
files[attributes.path] = {
|
||||
contributors: attributes.contributors,
|
||||
lastUpdated: attributes.lastUpdated,
|
||||
commits: attributes.commits,
|
||||
}
|
||||
})
|
||||
}
|
||||
if (meta?.pagination?.pageCount > page) {
|
||||
@@ -45,7 +49,7 @@ exports.onCreateNode = async function ({ node, getNode, actions, getCache, cache
|
||||
if (parent.internal.type === 'File') {
|
||||
const file = files[`contents/${parent.relativePath}`]
|
||||
if (file) {
|
||||
const { contributors, lastUpdated } = file
|
||||
const { contributors, lastUpdated, commits } = file
|
||||
if (contributors) {
|
||||
try {
|
||||
const contributorsNode = await Promise.all(
|
||||
@@ -68,6 +72,14 @@ exports.onCreateNode = async function ({ node, getNode, actions, getCache, cache
|
||||
}
|
||||
}
|
||||
|
||||
if (commits) {
|
||||
createNodeField({
|
||||
node,
|
||||
name: `commits`,
|
||||
value: commits,
|
||||
})
|
||||
}
|
||||
|
||||
createNodeField({
|
||||
node: parent,
|
||||
name: 'gitLogLatestDate',
|
||||
|
||||
169
safelist.txt
169
safelist.txt
@@ -1,3 +1,23 @@
|
||||
from-[color-mix(in_srgb,rgb(var(--bg))_0%,transparent)]
|
||||
via-[color-mix(in_srgb,rgb(var(--bg))_75%,transparent)]
|
||||
to-[rgb(var(--bg))]
|
||||
[&_ul]:mb-0
|
||||
@xl:max-w-2xs
|
||||
[&_.bg-front]:fill-yellow
|
||||
[&_.bg-front]:fill-blue
|
||||
[&_.bg-front]:fill-salmon
|
||||
[&_.bg-front]:fill-red
|
||||
[&_.bg-front]:fill-green
|
||||
[&_.bg-front]:fill-green-2
|
||||
[&_.bg-front]:fill-purple
|
||||
[&_.bg-front]:fill-seagreen
|
||||
[&_.bg-front]:fill-sky-blue
|
||||
[&_.bg-front]:fill-lilac
|
||||
[&_.bg-front]:fill-lime-green
|
||||
[&_.bg-front]:fill-orange
|
||||
[&_.bg-front]:fill-teal
|
||||
[&_.bg-rear]:fill-[#B56C00]
|
||||
[&_.bg-rear]:fill-[#37945D]
|
||||
!pb-8
|
||||
!-mb-12
|
||||
-mb-12
|
||||
@@ -47,6 +67,7 @@ bg-[#9C19BD]
|
||||
bg-[#D42F18]
|
||||
bg-[#F2AD46]
|
||||
bg-[#FCC779]
|
||||
bg-ai-blue
|
||||
bg-aqua
|
||||
bg-aqua/10
|
||||
bg-black
|
||||
@@ -59,9 +80,9 @@ bg-creamsicle-dark
|
||||
bg-gold
|
||||
bg-gold-dark
|
||||
bg-gradient-to-tr
|
||||
bg-gray
|
||||
bg-green
|
||||
bg-green/10
|
||||
bg-green-2
|
||||
bg-light-blue
|
||||
bg-light-purple
|
||||
bg-lilac
|
||||
@@ -77,15 +98,12 @@ bg-pale-blue
|
||||
bg-pale-blue-dark
|
||||
bg-pink
|
||||
bg-pink-dark
|
||||
bg-primary
|
||||
bg-primary-dark
|
||||
bg-primary-dark/10
|
||||
bg-primary/10
|
||||
bg-purple
|
||||
bg-purple-2
|
||||
bg-purple-2-dark
|
||||
bg-purple/10
|
||||
bg-red
|
||||
bg-red/10
|
||||
bg-salmon
|
||||
bg-salmon/10
|
||||
bg-seagreen
|
||||
@@ -133,7 +151,6 @@ dark:hover:border-seagreen
|
||||
dark:hover:border-sky-blue
|
||||
dark:hover:border-teal
|
||||
dark:hover:border-yellow
|
||||
|
||||
fill-aqua
|
||||
fill-aqua/10
|
||||
fill-black
|
||||
@@ -198,10 +215,12 @@ fill-white
|
||||
fill-yellow
|
||||
fill-yellow-2
|
||||
fill-yellow-2-dark
|
||||
|
||||
flex
|
||||
flex
|
||||
flex-row-reverse
|
||||
focus:bg-blue/10
|
||||
focus:border-blue
|
||||
focus-visible:bg-blue/10
|
||||
from-tan/100
|
||||
gap-y-4
|
||||
gap-y-4
|
||||
@@ -219,6 +238,24 @@ grid-rows-1
|
||||
grid-rows-2
|
||||
grid-rows-3
|
||||
grid-rows-4
|
||||
group-data-[state=active]:bg-blue
|
||||
group-data-[state=active]:bg-yellow
|
||||
group-data-[state=active]:bg-teal
|
||||
group-data-[state=active]:bg-purple
|
||||
group-data-[state=active]:bg-red
|
||||
group-data-[state=active]:bg-seagreen
|
||||
group-data-[state=active]:bg-lime-green
|
||||
group-data-[state=active]:bg-green
|
||||
group-data-[state=active]:bg-salmon
|
||||
group-hover:bg-blue/25
|
||||
group-hover:bg-yellow/25
|
||||
group-hover:bg-teal/25
|
||||
group-hover:bg-purple/25
|
||||
group-hover:bg-red/25
|
||||
group-hover:bg-seagreen/25
|
||||
group-hover:bg-lime-green/25
|
||||
group-hover:bg-green/25
|
||||
group-hover:bg-salmon/25
|
||||
group-hover:animate-delay-[100ms]
|
||||
group-hover:animate-delay-[200ms]
|
||||
group-hover:animate-delay-[300ms]
|
||||
@@ -286,6 +323,7 @@ md:-mx-16
|
||||
md:right-16
|
||||
md:w-48
|
||||
md:w-60
|
||||
min-w-[10rem]
|
||||
mt-16
|
||||
opacity-1
|
||||
opacity-100
|
||||
@@ -337,6 +375,7 @@ stroke-gold-dark
|
||||
stroke-gradient-to-tr
|
||||
stroke-gray
|
||||
stroke-green
|
||||
stroke-green-dark
|
||||
stroke-green/10
|
||||
stroke-fuchsia
|
||||
stroke-fuchsia-dark
|
||||
@@ -385,7 +424,7 @@ stroke-white
|
||||
stroke-white-dark
|
||||
stroke-yellow-2
|
||||
stroke-yellow-2-dark
|
||||
|
||||
text-[#063619]
|
||||
text-[#36C46F]
|
||||
text-[#43B6E7]
|
||||
text-[#681291]
|
||||
@@ -406,6 +445,7 @@ text-gold
|
||||
text-gold-dark
|
||||
text-gray
|
||||
text-green
|
||||
text-green-2
|
||||
text-light-blue
|
||||
text-light-purple
|
||||
text-lilac
|
||||
@@ -426,6 +466,8 @@ text-purple-2-dark
|
||||
text-red
|
||||
text-salmon
|
||||
text-seagreen
|
||||
text-secondary
|
||||
text-muted
|
||||
text-sky-blue
|
||||
text-tan
|
||||
text-teal
|
||||
@@ -434,6 +476,19 @@ text-teal-2-dark
|
||||
text-white
|
||||
text-yellow
|
||||
to-tan/0
|
||||
to-yellow
|
||||
to-green
|
||||
to-red
|
||||
to-salmon
|
||||
to-blue
|
||||
to-green
|
||||
to-purple
|
||||
to-orange
|
||||
to-lime-green
|
||||
to-sky-blue
|
||||
to-lilac
|
||||
to-teal
|
||||
to-teal-2
|
||||
via-tan/85
|
||||
w-2/12
|
||||
w-24
|
||||
@@ -450,3 +505,101 @@ fill-white
|
||||
text-brown
|
||||
|
||||
|
||||
skin-classic:!border-b-1.5
|
||||
|
||||
hover:bg-secondary
|
||||
data-[state=open]:bg-secondary
|
||||
data-[highlighted]:data-[state=open]:bg-secondary
|
||||
data-[highlighted]:bg-text-secondary
|
||||
|
||||
@xs:hidden
|
||||
@sm:hidden
|
||||
@md:hidden
|
||||
@lg:hidden
|
||||
@xl:hidden
|
||||
@2xl:hidden
|
||||
@3xl:hidden
|
||||
@4xl:hidden
|
||||
@5xl:hidden
|
||||
@6xl:hidden
|
||||
@7xl:hidden
|
||||
@xs:block
|
||||
@sm:block
|
||||
@md:block
|
||||
@lg:block
|
||||
@xl:block
|
||||
@2xl:block
|
||||
@3xl:block
|
||||
@4xl:block
|
||||
@5xl:block
|
||||
@6xl:block
|
||||
@7xl:block
|
||||
|
||||
@xs/reader-content-container:hidden
|
||||
@sm/reader-content-container:hidden
|
||||
@md/reader-content-container:hidden
|
||||
@lg/reader-content-container:hidden
|
||||
@xl/reader-content-container:hidden
|
||||
@2xl/reader-content-container:hidden
|
||||
@3xl/reader-content-container:hidden
|
||||
@4xl/reader-content-container:hidden
|
||||
@5xl/reader-content-container:hidden
|
||||
@6xl/reader-content-container:hidden
|
||||
@7xl/reader-content-container:hidden
|
||||
@xs/reader-content-container:block
|
||||
@sm/reader-content-container:block
|
||||
@md/reader-content-container:block
|
||||
@lg/reader-content-container:block
|
||||
@xl/reader-content-container:block
|
||||
@2xl/reader-content-container:block
|
||||
@3xl/reader-content-container:block
|
||||
@4xl/reader-content-container:block
|
||||
@5xl/reader-content-container:block
|
||||
@6xl/reader-content-container:block
|
||||
@7xl/reader-content-container:block
|
||||
|
||||
@xs/reader-content:hidden
|
||||
@sm/reader-content:hidden
|
||||
@md/reader-content:hidden
|
||||
@lg/reader-content:hidden
|
||||
@xl/reader-content:hidden
|
||||
@2xl/reader-content:hidden
|
||||
@3xl/reader-content:hidden
|
||||
@4xl/reader-content:hidden
|
||||
@5xl/reader-content:hidden
|
||||
@6xl/reader-content:hidden
|
||||
@7xl/reader-content:hidden
|
||||
@xs/reader-content:block
|
||||
@sm/reader-content:block
|
||||
@md/reader-content:block
|
||||
@lg/reader-content:block
|
||||
@xl/reader-content:block
|
||||
@2xl/reader-content:block
|
||||
@3xl/reader-content:block
|
||||
@4xl/reader-content:block
|
||||
@5xl/reader-content:block
|
||||
@6xl/reader-content:block
|
||||
@7xl/reader-content:block
|
||||
|
||||
@xs/app-reader:hidden
|
||||
@sm/app-reader:hidden
|
||||
@md/app-reader:hidden
|
||||
@lg/app-reader:hidden
|
||||
@xl/app-reader:hidden
|
||||
@2xl/app-reader:hidden
|
||||
@3xl/app-reader:hidden
|
||||
@4xl/app-reader:hidden
|
||||
@5xl/app-reader:hidden
|
||||
@6xl/app-reader:hidden
|
||||
@7xl/app-reader:hidden
|
||||
@xs/app-reader:block
|
||||
@sm/app-reader:block
|
||||
@md/app-reader:block
|
||||
@lg/app-reader:block
|
||||
@xl/app-reader:block
|
||||
@2xl/app-reader:block
|
||||
@3xl/app-reader:block
|
||||
@4xl/app-reader:block
|
||||
@5xl/app-reader:block
|
||||
@6xl/app-reader:block
|
||||
@7xl/app-reader:block
|
||||
|
||||
14
src/api/homepage-hits.js
Normal file
14
src/api/homepage-hits.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import fetch from 'node-fetch'
|
||||
|
||||
const handler = async (_req, res) => {
|
||||
const data = await fetch(`https://us.posthog.com/shared/aH0asDUbyFXPGSo6JOPryoycVhX7EA.json`).then((res) =>
|
||||
res.json()
|
||||
)
|
||||
|
||||
const count = data?.insight?.result?.[0]?.aggregated_value
|
||||
|
||||
return res.status(200).json(count)
|
||||
}
|
||||
|
||||
export default handler
|
||||
@@ -34,7 +34,7 @@ const Investor = ({ logo, logoDark, width, height, photo, large, name, role }: I
|
||||
) : photo ? (
|
||||
<div className="py-4 px-4 flex flex-col justify-center">
|
||||
{/* if a photo instead of a logo (angel)... */}
|
||||
<figure className="mb-2 mx-auto p-[2px] rounded-full bg-white border border-solid border-gray">
|
||||
<figure className="mb-2 mx-auto p-[2px] rounded-full bg-white border border-solid border-primary">
|
||||
{large ? (
|
||||
<img src={photo} width={80} height={80} alt={name} className="rounded-full " />
|
||||
) : (
|
||||
@@ -98,7 +98,7 @@ export const AboutInvestors = () => {
|
||||
<Investor name="Rujul Zaparde" role="Flightcar Founder" photo="/images/investors/rujul-zaparde.jpg" />
|
||||
|
||||
<div className="py-4 px-4 flex flex-col justify-center">
|
||||
<figure className="mb-2 mx-auto p-[2px] rounded-full bg-gray-accent-light border border-solid border-gray w-[50px] h-[50px] flex justify-center items-center">
|
||||
<figure className="mb-2 mx-auto p-[2px] rounded-full bg-accent-light border border-solid border-primary w-[50px] h-[50px] flex justify-center items-center">
|
||||
<span className="inline-block w-8 h-8">
|
||||
<Investors />
|
||||
</span>
|
||||
|
||||
@@ -24,7 +24,7 @@ export const AboutStory = () => {
|
||||
Continue reading
|
||||
</CallToAction>
|
||||
</div>
|
||||
<div className="inline-flex sm:flex-col mdlg:flex-row border-t border-primary/25 gap-8 sm:gap-2 mdlg:gap-8 items-center sm:items-start mdlg:items-center pt-3 pb-5 mt-6 sm:mr-12 mdlg:mr-24">
|
||||
<div className="inline-flex sm:flex-col mdlg:flex-row border-t border-input gap-8 sm:gap-2 mdlg:gap-8 items-center sm:items-start mdlg:items-center pt-3 pb-5 mt-6 sm:mr-12 mdlg:mr-24">
|
||||
<p className="pb-0 mb-0 text-sm opacity-75">Want to be our next star?</p>
|
||||
<span className="h-[28px] w-[125px]">
|
||||
<GitHubButton
|
||||
|
||||
@@ -13,7 +13,7 @@ const sizes = {
|
||||
export const circle = (size = 'lg', className = '') => cntl`
|
||||
rounded-full
|
||||
relative
|
||||
border-gray-accent-light
|
||||
border-primary
|
||||
border-solid
|
||||
inline-block
|
||||
bg-white
|
||||
@@ -38,7 +38,7 @@ export const Avatar = ({ size = 'lg', className = '', image, country, name, colo
|
||||
imgClassName="w-full h-full border border-solid border-white box-border rounded-full"
|
||||
/>
|
||||
)}
|
||||
<div className="absolute -right-2 -bottom-1 bg-white w-8 h-8 rounded-full border-2 text-lg border-gray-accent-light border-solid flex items-center justify-center">
|
||||
<div className="absolute -right-2 -bottom-1 bg-white w-8 h-8 rounded-full border-2 text-lg border-primary border-solid flex items-center justify-center">
|
||||
<ReactCountryFlag svg countryCode={country} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
17
src/components/About/v2/DifferentHighlights.tsx
Normal file
17
src/components/About/v2/DifferentHighlights.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import Link from 'components/Link'
|
||||
import { DotLottiePlayer } from '@dotlottie/react-player'
|
||||
import { IconBold, IconMusicEighthNote } from 'components/OSIcons'
|
||||
import NoHatingAllowed from 'components/NoHatingAllowed'
|
||||
import { HomepageCards } from 'components/NoHatingAllowed/data'
|
||||
|
||||
export const DifferentHighlights = () => {
|
||||
return (
|
||||
<div className="bg-red/10 rounded text-base p-4">
|
||||
<strong>Warning:</strong> If you like the way most companies treat you, you might not like us.{' '}
|
||||
<Link to="/vibe-check" state={{ newWindow: true }}>
|
||||
See 15 reasons why PostHog might be <em>wrong</em> for you.
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
45
src/components/About/v2/Letterhead.tsx
Normal file
45
src/components/About/v2/Letterhead.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from 'react'
|
||||
import Link from 'components/Link'
|
||||
import { IconXNotTwitter } from 'components/OSIcons'
|
||||
import Logo from 'components/Logo'
|
||||
import CloudinaryImage from 'components/CloudinaryImage'
|
||||
import { useApp } from '../../../context/App'
|
||||
import { DebugContainerQuery } from "components/DebugContainerQuery"
|
||||
|
||||
export const Letterhead = () => {
|
||||
const { siteSettings } = useApp()
|
||||
|
||||
return (
|
||||
<div className="not-prose border-b border-primary py-4 flex flex-col gap-2 @sm:flex-row items-center justify-between">
|
||||
<div>
|
||||
<Logo className="inline-block" fill={siteSettings.theme === 'dark' ? 'white' : undefined} />
|
||||
</div>
|
||||
<div className="@sm:hidden uppercase text-xs tracking-wider text-center text-muted pt-2">From the desk of</div>
|
||||
<aside className="flex gap-2 items-center">
|
||||
<div>
|
||||
<Link
|
||||
to="/community/profiles/27732"
|
||||
state={{ newWindow: true }}
|
||||
className="inline-block aspect-square size-16 rounded-full overflow-hidden bg-yellow"
|
||||
>
|
||||
<CloudinaryImage
|
||||
alt="James Hawkins"
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/v1738943658/James_H_5cb4c53d9a.png"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col gap-0 leading-none">
|
||||
<div className="hidden @sm:flex uppercase text-xs tracking-wider text-center text-muted pb-0.5">From the desk of</div>
|
||||
<strong>James Hawkins</strong>
|
||||
<span className="text-secondary text-sm">Co-founder</span>
|
||||
<div>
|
||||
<IconXNotTwitter className="inline-block size-4 mr-1" />
|
||||
<Link to="https://x.com/james406" external className="text-sm">
|
||||
james406
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
133
src/components/About/v2/LottieAnimations.tsx
Normal file
133
src/components/About/v2/LottieAnimations.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import React, { useEffect, useState, useRef } from 'react'
|
||||
import { DotLottiePlayer, PlayerEvents } from '@dotlottie/react-player'
|
||||
import { IconMusicEighthNote } from 'components/OSIcons'
|
||||
import { useIntersectionObserver } from 'hooks/useIntersectionObserver'
|
||||
|
||||
interface LottieAnimationProps {
|
||||
variant: 'kendrick' | 'different' | 'toy' | 'office'
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const LottieAnimation = ({ variant, className = '' }: LottieAnimationProps) => {
|
||||
const { elementRef, isInView } = useIntersectionObserver()
|
||||
const [fallbackInView, setFallbackInView] = useState(false)
|
||||
const [lottieReady, setLottieReady] = useState(false)
|
||||
const lottieRef = useRef<any>(null)
|
||||
|
||||
// Fallback scroll-based approach in case intersection observer doesn't work
|
||||
useEffect(() => {
|
||||
const checkScrollPosition = () => {
|
||||
if (elementRef.current) {
|
||||
const rect = elementRef.current.getBoundingClientRect()
|
||||
const windowHeight = window.innerHeight
|
||||
const isVisible = rect.top < windowHeight * 0.8 && rect.bottom > 0
|
||||
|
||||
if (isVisible && !fallbackInView) {
|
||||
setFallbackInView(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check immediately
|
||||
checkScrollPosition()
|
||||
|
||||
// Check on scroll
|
||||
window.addEventListener('scroll', checkScrollPosition)
|
||||
window.addEventListener('resize', checkScrollPosition)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', checkScrollPosition)
|
||||
window.removeEventListener('resize', checkScrollPosition)
|
||||
}
|
||||
}, [elementRef.current, fallbackInView])
|
||||
|
||||
// Use intersection observer result, fallback to scroll detection
|
||||
const shouldAutoplay = isInView || fallbackInView
|
||||
|
||||
// Manually control Lottie playback when visibility changes
|
||||
useEffect(() => {
|
||||
if (lottieRef.current && lottieReady) {
|
||||
if (shouldAutoplay) {
|
||||
try {
|
||||
// Reset to beginning and start playing
|
||||
lottieRef.current.seek(0)
|
||||
lottieRef.current.play()
|
||||
} catch (error) {
|
||||
// Silently handle any playback errors
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
lottieRef.current.pause()
|
||||
} catch (error) {
|
||||
// Silently handle any pause errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [shouldAutoplay, lottieReady])
|
||||
|
||||
// Configuration for each variant
|
||||
const variants = {
|
||||
kendrick: {
|
||||
src: '/lotties/kendrick.lottie',
|
||||
caption: (
|
||||
<>
|
||||
There are other dev tool companies, <br />
|
||||
but <em>they not like us</em> <IconMusicEighthNote className="inline-block size-4" />
|
||||
</>
|
||||
),
|
||||
className: '@lg:float-right w-72 mx-auto @lg:mt-8',
|
||||
containerClasses: 'relative',
|
||||
backgroundClasses: 'absolute inset-4 bg-gradient-to-b from-[#AAD4F2] to-[#F2D8AA] rounded-full size-56 mx-auto',
|
||||
lottieClasses: 'size-64 mx-auto relative top-[8px] right-[-6px]',
|
||||
captionClasses: 'text-primary text-center text-[15px] -mt-2 text-balance',
|
||||
},
|
||||
different: {
|
||||
src: '/lotties/rainbow.lottie',
|
||||
className: 'mx-auto w-84 pt-4',
|
||||
containerClasses: 'relative',
|
||||
backgroundClasses: 'absolute bg-[#D9E8F2] inset-4 rounded-full size-60 mx-auto',
|
||||
lottieClasses: 'size-72 mx-auto relative mx-auto',
|
||||
// captionClasses: 'text-primary text-center text-[15px] -mt-2 text-balance',
|
||||
},
|
||||
toy: {
|
||||
src: '/lotties/toy.lottie',
|
||||
caption: 'Our pricing is sustainable because most customers use multiple products',
|
||||
className: 'mx-auto w-80',
|
||||
containerClasses: 'relative',
|
||||
backgroundClasses: 'absolute inset-4 bg-accent rounded-full size-60 mx-auto',
|
||||
lottieClasses: 'size-72 mx-auto relative -top-2',
|
||||
captionClasses: 'text-primary text-center text-[15px] -mt-2 text-balance',
|
||||
},
|
||||
office: {
|
||||
src: '/lotties/office.lottie',
|
||||
// caption: "We're intentional about building the kind of company we actually enjoy working at.",
|
||||
className: '@xl:float-right mx-auto w-80 @xl:mr-4',
|
||||
containerClasses: 'relative',
|
||||
backgroundClasses: 'absolute inset-4 bg-accent rounded-full size-60 mx-auto',
|
||||
lottieClasses: 'size-72 mx-auto relative',
|
||||
// captionClasses: 'text-primary text-center text-[15px] -mt-2 text-balance',
|
||||
},
|
||||
}
|
||||
|
||||
const config = variants[variant]
|
||||
|
||||
return (
|
||||
<div ref={elementRef} className={`${config.className} ${className}`}>
|
||||
<div className={config.containerClasses}>
|
||||
<div className={config.backgroundClasses} />
|
||||
<DotLottiePlayer
|
||||
ref={lottieRef}
|
||||
src={config.src}
|
||||
autoplay={false}
|
||||
onEvent={(event) => {
|
||||
if (event === PlayerEvents.Ready) {
|
||||
setLottieReady(true)
|
||||
}
|
||||
}}
|
||||
className={config.lottieClasses}
|
||||
/>
|
||||
</div>
|
||||
{config.caption && <figcaption className={config.captionClasses}>{config.caption}</figcaption>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
31
src/components/About/v2/TLDR.tsx
Normal file
31
src/components/About/v2/TLDR.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react'
|
||||
import Link from 'components/Link'
|
||||
|
||||
export const TLDR = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<div className="max-w-sm mx-auto border-2 border-primary px-4 py-3 mt-4 mb-1 mr-1 rotate-1">
|
||||
<div className="flex gap-2 items-center mb-2">
|
||||
<div className="w-10">
|
||||
<div className="size-10 rounded-full bg-accent flex justify-center items-center text-xl font-bold text-muted">
|
||||
TN
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 text-sm flex flex-col">
|
||||
<strong>TLDR Founders Newsletter</strong>
|
||||
<span className="text-secondary text-xs">June 18, 2025</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="!mb-1">
|
||||
<Link
|
||||
to="https://www.cautiousoptimism.news/p/posthog-vs-the-industry"
|
||||
externalNoIcon
|
||||
className="!text-primary underline !font-bold"
|
||||
>
|
||||
PostHog vs. The Industry
|
||||
</Link>
|
||||
</p>
|
||||
<div className="prose-sm">{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
62
src/components/About/v2/YC.tsx
Normal file
62
src/components/About/v2/YC.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import CloudinaryImage from 'components/CloudinaryImage'
|
||||
import { YCBadge } from '../AboutStory/yc-badge'
|
||||
import React from 'react'
|
||||
import { James, Tim } from 'components/Signatures'
|
||||
|
||||
export const YC = () => {
|
||||
return (
|
||||
<aside className="max-w-sm relative @xl:float-right @xl:ml-4 mt-4 @2xl/reader-content-container:-mr-4 @3xl/reader-content-container:-mr-16 @4xl/reader-content-container:-mr-28 mb-6 @xl:mb-0 inline-block transition-all">
|
||||
{/* <div className="hidden @xl:flex justify-end text-primary dark:text-primary-dark">
|
||||
<YCBadge className="w-[95px] h-[63px]" />
|
||||
</div> */}
|
||||
<div className="rotate-1">
|
||||
<div className="relative shadow-2xl rounded overflow-hidden">
|
||||
<CloudinaryImage
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/hn_screenshot_e2819766a4.png"
|
||||
width={574}
|
||||
height={352}
|
||||
alt="PostHog launches on HackerNews"
|
||||
/>
|
||||
<div className="bg-gradient-to-b from-transparent via-transparent to-tan dark:to-dark absolute inset-0" />
|
||||
<div className="absolute -bottom-4 right-32 -rotate-1">
|
||||
<CloudinaryImage
|
||||
breakpoints={[750, 1080, 1366, 1920]}
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/src/components/About/AboutStory/images/james.png"
|
||||
width={386}
|
||||
height={366}
|
||||
quality={100}
|
||||
alt="James Hawkins, Co-CEO, Co-founder"
|
||||
placeholder="none"
|
||||
objectFit="contain"
|
||||
className="w-36"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-primary absolute bottom-4 right-60 leading-tight -rotate-1">
|
||||
<James className="h-12 mb-1" />
|
||||
<strong>James Hawkins</strong>
|
||||
<span className="block text-sm">Co-CEO</span>
|
||||
</div>
|
||||
<div className="absolute -bottom-2 right-16 -rotate-1">
|
||||
<CloudinaryImage
|
||||
breakpoints={[750, 1080, 1366, 1920]}
|
||||
src="https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/src/components/About/AboutStory/images/tim.png"
|
||||
width={285}
|
||||
height={320}
|
||||
quality={100}
|
||||
alt="Tim Glaser, Co-CEO, Co-founder"
|
||||
placeholder="none"
|
||||
objectFit="contain"
|
||||
className="w-28"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute bottom-2 right-2 text-primary leading-tight -rotate-1">
|
||||
<Tim className="h-10 mb-1" />
|
||||
<strong>Tim Glaser</strong>
|
||||
<span className="block text-sm">Co-CEO</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="!text-xs text-right pt-2 !mt-1 !mb-0">PostHog was hatched in Y Combinator's W20 batch.</p>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
@@ -123,7 +123,7 @@ const PostQuote: React.FC<PostQuoteProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<div className="flex-1 [&_p]:text-lg [&_p]:mb-3 [&_p:last-child]:mb-0 md:columns-2 gap-8">
|
||||
<div className="flex-1 [&_p]:first:mt-0 [&_p]:text-base [&_p]:mb-3 [&_p:last-child]:mb-0 md:columns-2 gap-8">
|
||||
{quote.split('\n\n').map((paragraph, index) => (
|
||||
<p key={index} dangerouslySetInnerHTML={{ __html: paragraph }} />
|
||||
))}
|
||||
103
src/components/ActiveWindowsPanel/index.tsx
Normal file
103
src/components/ActiveWindowsPanel/index.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useApp } from '../../context/App'
|
||||
import SidePanel from 'components/SidePanel'
|
||||
import ScrollArea from 'components/RadixUI/ScrollArea'
|
||||
import OSButton from 'components/OSButton'
|
||||
import { navigate } from 'gatsby'
|
||||
|
||||
export default function ActiveWindowsPanel() {
|
||||
const {
|
||||
windows,
|
||||
isActiveWindowsPanelOpen,
|
||||
setIsActiveWindowsPanelOpen,
|
||||
focusedWindow,
|
||||
bringToFront,
|
||||
closeWindow,
|
||||
animateClosingAllWindows,
|
||||
} = useApp()
|
||||
|
||||
const closeActiveWindowsPanel = () => {
|
||||
setIsActiveWindowsPanelOpen(false)
|
||||
}
|
||||
|
||||
// Add keyboard listener for Escape key
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape' && isActiveWindowsPanelOpen) {
|
||||
e.preventDefault()
|
||||
closeActiveWindowsPanel()
|
||||
}
|
||||
}
|
||||
|
||||
if (isActiveWindowsPanelOpen) {
|
||||
document.addEventListener('keydown', handleKeyDown)
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown)
|
||||
}
|
||||
}, [isActiveWindowsPanelOpen])
|
||||
|
||||
const handleWindowClick = (appWindow: any) => {
|
||||
if (appWindow.path.startsWith('/')) {
|
||||
navigate(`${appWindow.path}`)
|
||||
} else {
|
||||
bringToFront(appWindow)
|
||||
}
|
||||
closeActiveWindowsPanel()
|
||||
}
|
||||
|
||||
const totalWindows = windows.length
|
||||
|
||||
return (
|
||||
<SidePanel
|
||||
isOpen={isActiveWindowsPanelOpen}
|
||||
onClose={closeActiveWindowsPanel}
|
||||
title="Active windows"
|
||||
headerAside={
|
||||
windows.length > 0 && (
|
||||
<OSButton
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
animateClosingAllWindows()
|
||||
closeActiveWindowsPanel()
|
||||
}}
|
||||
>
|
||||
Close all
|
||||
</OSButton>
|
||||
)
|
||||
}
|
||||
width="w-80"
|
||||
>
|
||||
<ScrollArea className="p-2">
|
||||
<div className="flex flex-col gap-1">
|
||||
{windows.map((window) => (
|
||||
<OSButton
|
||||
key={window.key}
|
||||
size="md"
|
||||
width="full"
|
||||
align="left"
|
||||
active={focusedWindow === window}
|
||||
onClick={() => handleWindowClick(window)}
|
||||
className="group"
|
||||
>
|
||||
<span className={`truncate flex-1 ${window.minimized ? 'italic opacity-60' : ''}`}>
|
||||
{window.meta?.title || 'Untitled'}
|
||||
</span>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
closeWindow(window)
|
||||
}}
|
||||
className="ml-2 text-secondary hover:text-primary opacity-0 group-hover:opacity-100 transition-opacity text-lg leading-none px-1"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</OSButton>
|
||||
))}
|
||||
{totalWindows === 0 && <div className="text-center text-secondary p-4">No active windows</div>}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</SidePanel>
|
||||
)
|
||||
}
|
||||
@@ -7,7 +7,7 @@ export default function AppStatus() {
|
||||
|
||||
return loading ? null : (
|
||||
<Link
|
||||
className="flex gap-1 items-center justify-end text-inherit hover:text-red dark:hover:text-yellow"
|
||||
className="flex gap-1 items-center justify-end text-inherit hover:underline"
|
||||
to="https://status.posthog.com"
|
||||
externalNoIcon
|
||||
>
|
||||
|
||||
944
src/components/AppWindow/index.tsx
Normal file
944
src/components/AppWindow/index.tsx
Normal file
@@ -0,0 +1,944 @@
|
||||
import React, { useEffect, useState, useMemo, useRef, useCallback } from 'react'
|
||||
import { AnimatePresence, motion, useDragControls } from 'framer-motion'
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconDocument,
|
||||
IconMinus,
|
||||
IconX,
|
||||
IconCollapse45Chevrons,
|
||||
IconExpand45Chevrons,
|
||||
IconSquare,
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
} from '@posthog/icons'
|
||||
import { Menu, MenuItem, useApp } from '../../context/App'
|
||||
import { Provider as WindowProvider, AppWindow as AppWindowType, useWindow } from '../../context/Window'
|
||||
import { ContextMenu, Dialog } from 'radix-ui'
|
||||
import Tooltip from 'components/RadixUI/Tooltip'
|
||||
import OSButton from 'components/OSButton'
|
||||
import { Button } from 'components/Squeak/components/SubscribeButton'
|
||||
import MenuBar, { MenuItemType } from 'components/RadixUI/MenuBar'
|
||||
import { Popover } from '../RadixUI/Popover'
|
||||
import { FileMenu } from '../RadixUI/FileMenu'
|
||||
import { IMenu } from 'components/PostLayout/types'
|
||||
import { Link, navigate } from 'gatsby'
|
||||
import Inbox from 'components/Inbox'
|
||||
import Handbook from '../../templates/Handbook'
|
||||
import BlogPost from '../../templates/BlogPost'
|
||||
import Legal from 'components/Legal'
|
||||
import { getProseClasses } from '../../constants'
|
||||
import KeyboardShortcut from 'components/KeyboardShortcut'
|
||||
import { useToast } from '../../context/Toast'
|
||||
import usePostHog from '../../hooks/usePostHog'
|
||||
|
||||
const recursiveSearch = (array: MenuItem[] | undefined, value: string): boolean => {
|
||||
if (!array) return false
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const element = array[i]
|
||||
|
||||
if (element.url?.split('?')[0] === value) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (element.children) {
|
||||
const found = recursiveSearch(element.children, value)
|
||||
if (found) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const snapThreshold = -50
|
||||
|
||||
const Router = (props) => {
|
||||
const { minimizeWindow } = useApp()
|
||||
const { appWindow } = useWindow()
|
||||
const { children, path, minimizing, onExit } = props
|
||||
|
||||
useEffect(() => {
|
||||
if (minimizing) {
|
||||
minimizeWindow(appWindow)
|
||||
// Trigger the animation in the TaskBarMenu
|
||||
const taskbarMenu = document.querySelector('#taskbar')
|
||||
if (taskbarMenu) {
|
||||
const event = new CustomEvent('windowMinimized')
|
||||
taskbarMenu.dispatchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
onExit()
|
||||
}
|
||||
}, [minimizing])
|
||||
|
||||
if (/^\/questions/.test(path)) {
|
||||
return <Inbox {...props} />
|
||||
}
|
||||
if (/^\/handbook|^\/docs\/(?!api)|^\/manual/.test(path) && props.data?.post) {
|
||||
return <Handbook {...props} />
|
||||
}
|
||||
if ((props.pageContext?.post || /^posts/.test(path)) && props.data) {
|
||||
return <BlogPost {...props} />
|
||||
}
|
||||
if (['/terms', '/privacy', '/dpa', '/baa'].includes(path)) {
|
||||
return <Legal defaultTab={path}>{children}</Legal>
|
||||
}
|
||||
return (!props.minimizing || appWindow?.appSettings?.size?.autoHeight) && children
|
||||
}
|
||||
|
||||
const WindowContainer = ({ children, closing }: { children: React.ReactNode; closing: boolean }) => {
|
||||
const { closeWindow } = useApp()
|
||||
const { appWindow } = useWindow()
|
||||
return (
|
||||
<AnimatePresence
|
||||
onExitComplete={() => {
|
||||
if (closing) {
|
||||
closeWindow(appWindow)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AnimatePresence>
|
||||
)
|
||||
}
|
||||
|
||||
export default function AppWindow({ item, chrome = true }: { item: AppWindowType; chrome?: boolean }) {
|
||||
const { addToast, toasts } = useToast()
|
||||
const {
|
||||
minimizeWindow,
|
||||
bringToFront,
|
||||
focusedWindow,
|
||||
taskbarHeight,
|
||||
windows,
|
||||
updateWindowRef,
|
||||
updateWindow,
|
||||
getDesktopCenterPosition,
|
||||
handleSnapToSide,
|
||||
constraintsRef,
|
||||
expandWindow,
|
||||
siteSettings,
|
||||
updateSiteSettings,
|
||||
openNewChat,
|
||||
compact,
|
||||
menu: appMenu,
|
||||
taskbarRef,
|
||||
} = useApp()
|
||||
const isSSR = typeof window === 'undefined'
|
||||
const controls = useDragControls()
|
||||
const sizeConstraints = item.sizeConstraints
|
||||
const size = item.size
|
||||
const previousSize = item.previousSize
|
||||
const position = item.position
|
||||
const previousPosition = item.previousPosition
|
||||
const [snapIndicator, setSnapIndicator] = useState<'left' | 'right' | null>(null)
|
||||
const [windowOptionsTooltipVisible, setWindowOptionsTooltipVisible] = useState(false)
|
||||
const [menu, setMenu] = useState<IMenu[]>([])
|
||||
const [history, setHistory] = useState<string[]>([])
|
||||
const [activeHistoryIndex, setActiveHistoryIndex] = useState(0)
|
||||
const windowRef = useRef<HTMLDivElement>(null)
|
||||
const [rendered, setRendered] = useState(false)
|
||||
const [dragging, setDragging] = useState(false)
|
||||
const contentRef = useRef<HTMLDivElement>(null)
|
||||
const [pageOptions, setPageOptions] = useState<MenuItemType[]>()
|
||||
const [closing, setClosing] = useState(false)
|
||||
const [closed, setClosed] = useState(false)
|
||||
const [minimizing, setMinimizing] = useState(false)
|
||||
const [animating, setAnimating] = useState(true)
|
||||
const animationStartTimeRef = useRef<number | null>(null)
|
||||
const posthog = usePostHog()
|
||||
|
||||
const inView = useMemo(() => {
|
||||
const windowsAbove = windows.filter(
|
||||
(window) => window !== item && window.zIndex > item.zIndex && !window.minimized
|
||||
)
|
||||
|
||||
let coveredArea = 0
|
||||
const currentArea = size.width * size.height
|
||||
|
||||
for (const windowAbove of windowsAbove) {
|
||||
const left = Math.max(position.x, windowAbove.position.x)
|
||||
const right = Math.min(position.x + size.width, windowAbove.position.x + windowAbove.size.width)
|
||||
const top = Math.max(position.y, windowAbove.position.y)
|
||||
const bottom = Math.min(position.y + size.height, windowAbove.position.y + windowAbove.size.height)
|
||||
|
||||
if (left < right && top < bottom) {
|
||||
coveredArea += (right - left) * (bottom - top)
|
||||
}
|
||||
}
|
||||
|
||||
return coveredArea / currentArea < 0.8
|
||||
}, [windows, item, position, size])
|
||||
|
||||
const parent =
|
||||
(appMenu as Menu).find(({ children, url }) => {
|
||||
const currentURL = item?.path
|
||||
return currentURL === url?.split('?')[0] || recursiveSearch(children, currentURL)
|
||||
}) ||
|
||||
appMenu.find(({ url }) => url === `/${item?.path?.split('/')[1]}`) ||
|
||||
appMenu[0]
|
||||
|
||||
const internalMenu = parent?.children || []
|
||||
|
||||
const getActiveInternalMenu = useCallback(() => {
|
||||
return internalMenu?.find((menuItem: MenuItem) => {
|
||||
const currentURL = item?.path
|
||||
return currentURL === menuItem.url?.split('?')[0] || recursiveSearch(menuItem.children, currentURL)
|
||||
})
|
||||
}, [internalMenu, item])
|
||||
|
||||
const [activeInternalMenu, setActiveInternalMenu] = useState<MenuItem | undefined>(getActiveInternalMenu())
|
||||
|
||||
useEffect(() => {
|
||||
setMenu?.(internalMenu)
|
||||
}, [activeInternalMenu])
|
||||
|
||||
useEffect(() => {
|
||||
if (windowRef.current) {
|
||||
updateWindowRef(item, windowRef)
|
||||
}
|
||||
}, [windowRef.current])
|
||||
|
||||
const beyondViewport = (windowSize: { width: number; height: number }) => {
|
||||
const rightEdge = position.x + windowSize.width
|
||||
const bottomEdge = position.y + windowSize.height
|
||||
|
||||
return (
|
||||
rightEdge > window.innerWidth ||
|
||||
bottomEdge > window.innerHeight - taskbarHeight ||
|
||||
position.x < 0 ||
|
||||
position.y < 0
|
||||
)
|
||||
}
|
||||
|
||||
const handleDoubleClick = () => {
|
||||
const newSize = beyondViewport(sizeConstraints.max)
|
||||
? { width: window.innerWidth, height: window.innerHeight - taskbarHeight }
|
||||
: sizeConstraints.max
|
||||
updateWindow(item, {
|
||||
size: newSize,
|
||||
position: getDesktopCenterPosition(newSize),
|
||||
})
|
||||
}
|
||||
|
||||
const collapseWindow = () => {
|
||||
const isBeyondViewport = beyondViewport(previousSize)
|
||||
const newSize = isBeyondViewport
|
||||
? { width: window.innerWidth - 40, height: window.innerHeight - 40 - taskbarHeight }
|
||||
: previousSize
|
||||
updateWindow(item, {
|
||||
size: newSize,
|
||||
position: isBeyondViewport ? getDesktopCenterPosition(newSize) : previousPosition,
|
||||
})
|
||||
}
|
||||
|
||||
const getActiveWindowsButtonPosition = () => {
|
||||
const activeWindowsButton = isSSR ? null : taskbarRef.current?.querySelector('[data-active-windows]')
|
||||
if (!activeWindowsButton) return { x: 0, y: 0 }
|
||||
const rect = activeWindowsButton.getBoundingClientRect()
|
||||
return {
|
||||
x: rect.left + rect.width / 2,
|
||||
y: rect.top + rect.height / 2,
|
||||
}
|
||||
}
|
||||
|
||||
const handleMinimize = () => {
|
||||
setMinimizing(true)
|
||||
}
|
||||
|
||||
const handleDrag = (_event: any, info: any) => {
|
||||
if (!dragging) setDragging(true)
|
||||
if (item.fixedSize) return
|
||||
if (!constraintsRef.current) return
|
||||
|
||||
const bounds = constraintsRef.current.getBoundingClientRect()
|
||||
const newX = position.x + info.offset.x
|
||||
|
||||
if (newX < snapThreshold) {
|
||||
setSnapIndicator('left')
|
||||
} else if (newX > bounds.width - size.width - snapThreshold) {
|
||||
setSnapIndicator('right')
|
||||
} else {
|
||||
setSnapIndicator(null)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragEnd = (_event: any, info: any) => {
|
||||
if (dragging) setDragging(false)
|
||||
if (!item.fixedSize && snapIndicator !== null) {
|
||||
handleSnapToSide(snapIndicator)
|
||||
setSnapIndicator(null)
|
||||
return
|
||||
} else {
|
||||
if (!constraintsRef.current) return
|
||||
|
||||
const bounds = constraintsRef.current.getBoundingClientRect()
|
||||
const newX = position.x + info?.offset?.x
|
||||
const newY = position.y + info?.offset?.y
|
||||
|
||||
if (newX >= 0 && newY >= 0 && newX + size.width <= bounds.width && newY + size.height <= bounds.height) {
|
||||
updateWindow(item, {
|
||||
position: { x: newX, y: newY },
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragTransitionEnd = () => {
|
||||
if (!dragging) setDragging(false)
|
||||
if (!constraintsRef.current || !item.ref?.current) return
|
||||
|
||||
const containerBounds = constraintsRef.current.getBoundingClientRect()
|
||||
const windowBounds = item.ref.current.getBoundingClientRect()
|
||||
|
||||
const newX = windowBounds.left - containerBounds.left
|
||||
const newY = windowBounds.top - containerBounds.top
|
||||
|
||||
updateWindow(item, {
|
||||
position: { x: newX, y: newY },
|
||||
})
|
||||
}
|
||||
|
||||
const windowPosition = useMemo(() => {
|
||||
if (isSSR) return { x: 0, y: 0 }
|
||||
const activeWindowsPosition = getActiveWindowsButtonPosition()
|
||||
if (activeWindowsPosition.x === 0 && activeWindowsPosition.y === 0) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
x: activeWindowsPosition.x - size.width / 2,
|
||||
y: activeWindowsPosition.y - size.height / 2,
|
||||
}
|
||||
}, [size.width, size.height, taskbarRef.current])
|
||||
|
||||
const canGoBack = history.length > 0 && activeHistoryIndex > 0
|
||||
const canGoForward = activeHistoryIndex < history.length - 1
|
||||
|
||||
useEffect(() => {
|
||||
if (!item?.fromHistory) {
|
||||
setHistory((prev) => [...prev, item.path])
|
||||
setActiveHistoryIndex(history.length)
|
||||
}
|
||||
setActiveInternalMenu(getActiveInternalMenu())
|
||||
}, [item?.path])
|
||||
|
||||
const goBack = () => {
|
||||
if (canGoBack) {
|
||||
setActiveHistoryIndex(activeHistoryIndex - 1)
|
||||
navigate(history[activeHistoryIndex - 1], {
|
||||
state: {
|
||||
fromHistory: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const goForward = () => {
|
||||
if (canGoForward) {
|
||||
setActiveHistoryIndex(activeHistoryIndex + 1)
|
||||
navigate(history[activeHistoryIndex + 1], {
|
||||
state: {
|
||||
fromHistory: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleMouseDown = () => {
|
||||
if (focusedWindow === item) return
|
||||
if (item.path.startsWith('/')) {
|
||||
navigate(item.path, { state: { newWindow: true } })
|
||||
} else {
|
||||
bringToFront(item)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
if (beyondViewport(size)) {
|
||||
const newSize = {
|
||||
width: Math.min(size.width, window.innerWidth),
|
||||
height: Math.min(size.height, window.innerHeight - taskbarHeight),
|
||||
}
|
||||
|
||||
const newPosition = {
|
||||
x: Math.min(Math.max(0, position.x), window.innerWidth - newSize.width),
|
||||
y: Math.min(Math.max(0, position.y), window.innerHeight - taskbarHeight - newSize.height),
|
||||
}
|
||||
|
||||
updateWindow(item, {
|
||||
size: newSize,
|
||||
position: newPosition,
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!isSSR) {
|
||||
window.addEventListener('resize', handleResize)
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}
|
||||
}, [item])
|
||||
|
||||
useEffect(() => {
|
||||
setRendered(true)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const handleWindowClose = (event: CustomEvent) => {
|
||||
if (event.detail.windowKey === item.key) {
|
||||
handleClose()
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('windowClose', handleWindowClose as EventListener)
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('windowClose', handleWindowClose as EventListener)
|
||||
}
|
||||
}, [item.key])
|
||||
|
||||
const chatWindows = windows.filter((w) => w.key?.startsWith('ask-max'))
|
||||
const defaultPageOptions = useMemo(
|
||||
() => [
|
||||
{
|
||||
type: 'submenu',
|
||||
label: 'Ask Max about this page',
|
||||
items: [
|
||||
{
|
||||
type: 'item',
|
||||
label: 'New Max chat',
|
||||
onClick() {
|
||||
openNewChat({
|
||||
path: `ask-max-${item.path}`,
|
||||
context: [{ type: 'page', value: { path: item.path, label: item.meta?.title } }],
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
...(chatWindows.length > 0
|
||||
? [
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
...chatWindows.map((appWindow, index) => ({
|
||||
type: 'item',
|
||||
label: appWindow.meta?.title || `Chat ${index + 1}`,
|
||||
onClick: () => {
|
||||
const newAppWindow = updateWindow(appWindow, {
|
||||
element: {
|
||||
...appWindow.element,
|
||||
props: {
|
||||
...appWindow.props,
|
||||
context: [
|
||||
{
|
||||
type: 'page',
|
||||
value: { path: item.path, label: item.meta?.title },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
bringToFront(newAppWindow)
|
||||
},
|
||||
})),
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
label: 'Bookmark',
|
||||
},
|
||||
],
|
||||
[item, chatWindows]
|
||||
)
|
||||
|
||||
const handleClose = () => {
|
||||
setAnimating(true)
|
||||
setClosing(true)
|
||||
setTimeout(() => {
|
||||
setClosed(true)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
const onAnimationStart = () => {
|
||||
animationStartTimeRef.current = performance.now()
|
||||
}
|
||||
const onAnimationComplete = () => {
|
||||
setAnimating(false)
|
||||
const endTime = performance.now()
|
||||
const startTime = animationStartTimeRef.current || 0
|
||||
const duration = endTime - startTime
|
||||
if (
|
||||
duration > 700 &&
|
||||
!siteSettings.performanceBoost &&
|
||||
!toasts.some((toast) => toast.title === 'Animations running slow')
|
||||
) {
|
||||
posthog?.capture('animation_performance_toast_shown')
|
||||
addToast({
|
||||
title: 'Animations may be affecting performance',
|
||||
description: 'You can turn off animations to improve performance if needed.',
|
||||
actionLabel: 'Disable animations',
|
||||
onAction: () => {
|
||||
posthog?.capture('animation_performance_toast_action')
|
||||
updateSiteSettings({ ...siteSettings, performanceBoost: true })
|
||||
addToast({
|
||||
title: 'Animations have been disabled',
|
||||
description: (
|
||||
<p className="max-w-sm">
|
||||
Animations have been turned off to improve performance. You can change this setting in{' '}
|
||||
<Link
|
||||
to="/display-options"
|
||||
className="font-semibold underline"
|
||||
state={{ newWindow: true }}
|
||||
>
|
||||
display options
|
||||
</Link>
|
||||
</p>
|
||||
),
|
||||
duration: 2000,
|
||||
onUndo: () => {
|
||||
updateSiteSettings({ ...siteSettings, performanceBoost: false })
|
||||
},
|
||||
})
|
||||
},
|
||||
duration: 8000,
|
||||
})
|
||||
}
|
||||
animationStartTimeRef.current = null
|
||||
}
|
||||
|
||||
return (
|
||||
<WindowProvider
|
||||
appWindow={item}
|
||||
menu={menu}
|
||||
setMenu={setMenu}
|
||||
goBack={goBack}
|
||||
goForward={goForward}
|
||||
canGoBack={canGoBack}
|
||||
canGoForward={canGoForward}
|
||||
dragControls={controls}
|
||||
setPageOptions={setPageOptions}
|
||||
activeInternalMenu={activeInternalMenu}
|
||||
setActiveInternalMenu={setActiveInternalMenu}
|
||||
internalMenu={internalMenu}
|
||||
parent={parent}
|
||||
>
|
||||
<WindowContainer closing={closing}>
|
||||
{!item.minimized && !closed && (
|
||||
<>
|
||||
{snapIndicator && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 0.3 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-4 border-2 border-blue bg-blue/40 pointer-events-none rounded-md"
|
||||
style={{
|
||||
left: snapIndicator === 'left' ? 0 : '50%',
|
||||
width: '50%',
|
||||
top: taskbarHeight,
|
||||
height: `calc(100% - ${taskbarHeight}px)`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<motion.div
|
||||
ref={windowRef}
|
||||
data-app="AppWindow"
|
||||
data-scheme="tertiary"
|
||||
suppressHydrationWarning
|
||||
className={`@container absolute !select-auto flex flex-col ${
|
||||
item.appSettings?.size?.fixed ? 'bg-transparent' : 'bg-transparent'
|
||||
} ${
|
||||
siteSettings.experience === 'boring' && !item.appSettings?.size?.fixed
|
||||
? 'border-b border-primary'
|
||||
: `${
|
||||
focusedWindow === item
|
||||
? 'shadow-2xl border-primary'
|
||||
: 'shadow-lg border-input'
|
||||
} ${dragging ? '[&_*]:select-none' : ''} ${
|
||||
item.minimal
|
||||
? '!shadow-none'
|
||||
: `flex flex-col ${
|
||||
siteSettings.experience === 'boring' ? '' : 'border rounded'
|
||||
}`
|
||||
}`
|
||||
} ${chrome ? 'overflow-hidden' : ''}`}
|
||||
style={{
|
||||
zIndex: item.zIndex,
|
||||
}}
|
||||
initial={{
|
||||
scale: 0.08,
|
||||
x: rendered
|
||||
? siteSettings.experience === 'boring' || !windowPosition
|
||||
? 0
|
||||
: windowPosition.x
|
||||
: item.fromOrigin?.x || windowPosition?.x || Math.round(position.x),
|
||||
y: rendered
|
||||
? siteSettings.experience === 'boring' || !windowPosition
|
||||
? 0
|
||||
: windowPosition.y
|
||||
: item.fromOrigin?.y || windowPosition?.y || Math.round(position.y),
|
||||
width: siteSettings.experience === 'boring' ? '100%' : size.width,
|
||||
height:
|
||||
siteSettings.experience === 'boring'
|
||||
? '100%'
|
||||
: item.appSettings?.size?.autoHeight
|
||||
? 'auto'
|
||||
: size.height,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
x: siteSettings.experience === 'boring' ? 0 : Math.round(position.x),
|
||||
y: siteSettings.experience === 'boring' ? 0 : Math.round(position.y),
|
||||
width: siteSettings.experience === 'boring' ? '100%' : size.width,
|
||||
height:
|
||||
siteSettings.experience === 'boring'
|
||||
? '100%'
|
||||
: item.appSettings?.size?.autoHeight
|
||||
? 'auto'
|
||||
: size.height,
|
||||
transition: {
|
||||
duration:
|
||||
siteSettings.experience === 'boring' || siteSettings.performanceBoost ? 0 : 0.2,
|
||||
scale: {
|
||||
duration:
|
||||
siteSettings.experience === 'boring' ||
|
||||
siteSettings.performanceBoost ||
|
||||
!windowPosition
|
||||
? 0
|
||||
: 0.2,
|
||||
delay:
|
||||
siteSettings.experience === 'boring' ||
|
||||
siteSettings.performanceBoost ||
|
||||
!windowPosition
|
||||
? 0
|
||||
: 0.2,
|
||||
ease: [0.2, 0.2, 0.8, 1],
|
||||
},
|
||||
width: {
|
||||
duration: 0,
|
||||
},
|
||||
height: {
|
||||
duration: 0,
|
||||
},
|
||||
},
|
||||
}}
|
||||
exit={{
|
||||
scale: 0.005,
|
||||
...(closing || !windowPosition ? {} : { x: windowPosition.x, y: windowPosition.y }),
|
||||
transition: {
|
||||
scale: {
|
||||
duration:
|
||||
siteSettings.experience === 'boring' || siteSettings.performanceBoost
|
||||
? 0
|
||||
: 0.23,
|
||||
ease: [0.2, 0.2, 0.8, 1],
|
||||
},
|
||||
x: {
|
||||
duration: 0.23,
|
||||
ease: [0.2, 0.2, 0.8, 1],
|
||||
},
|
||||
y: {
|
||||
duration: 0.23,
|
||||
ease: [0.2, 0.2, 0.8, 1],
|
||||
},
|
||||
},
|
||||
}}
|
||||
drag={siteSettings.experience === 'posthog'}
|
||||
dragControls={controls}
|
||||
dragListener={false}
|
||||
dragMomentum={false}
|
||||
dragConstraints={constraintsRef}
|
||||
onDrag={handleDrag}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragTransitionEnd={handleDragTransitionEnd}
|
||||
onMouseDown={handleMouseDown}
|
||||
onAnimationStart={onAnimationStart}
|
||||
onAnimationComplete={onAnimationComplete}
|
||||
>
|
||||
{!item.minimal && !compact && (
|
||||
<div
|
||||
data-scheme="tertiary"
|
||||
onDoubleClick={handleDoubleClick}
|
||||
className={`flex-shrink-0 w-full flex @md:grid grid-cols-[minmax(100px,auto)_1fr_minmax(100px,auto)] gap-1 items-center py-0.5 pl-1.5 pr-0.5 bg-primary/50 backdrop-blur-3xl skin-classic:bg-primary border-b border-input ${
|
||||
siteSettings.experience === 'boring' ? '' : 'cursor-move'
|
||||
}`}
|
||||
onPointerDown={(e) => controls.start(e)}
|
||||
>
|
||||
<MenuBar
|
||||
menus={[
|
||||
{
|
||||
trigger: (
|
||||
<>
|
||||
<IconDocument className="size-5" />
|
||||
<IconChevronDown className="size-6 -mx-1.5 text-muted group-hover:text-primary data-[state=open]:text-primary" />
|
||||
</>
|
||||
),
|
||||
items: [
|
||||
...(pageOptions || defaultPageOptions),
|
||||
{
|
||||
type: 'item',
|
||||
label: 'Close',
|
||||
onClick: handleClose,
|
||||
shortcut: ['Shift', 'W'],
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="flex-1 truncate flex items-center justify-start @md:justify-center">
|
||||
{menu && menu.length > 0 ? (
|
||||
<Popover
|
||||
trigger={
|
||||
<button className="text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark text-left items-center justify-center text-sm font-semibold flex select-none">
|
||||
{(item.meta?.title && item.meta.title) ||
|
||||
activeInternalMenu?.name}
|
||||
<IconChevronDown className="size-6 -m-1" />
|
||||
</button>
|
||||
}
|
||||
dataScheme="primary"
|
||||
contentClassName="w-auto p-0 border border-primary"
|
||||
header={false}
|
||||
>
|
||||
<FileMenu menu={menu} />
|
||||
</Popover>
|
||||
) : (
|
||||
<div className="text-primary hover:text-primary dark:text-primary-dark dark:hover:text-primary-dark text-left items-center justify-center text-sm font-semibold flex select-none">
|
||||
{item.meta?.title && item.meta.title}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-end">
|
||||
{siteSettings.experience !== 'boring' && (
|
||||
<>
|
||||
<OSButton size="xs" onClick={handleMinimize} className="">
|
||||
<IconMinus className="size-4 relative top-1" />
|
||||
</OSButton>
|
||||
|
||||
<ContextMenu.Root
|
||||
onOpenChange={() => setWindowOptionsTooltipVisible(false)}
|
||||
>
|
||||
<ContextMenu.Trigger
|
||||
className="data-[highlighted]:bg-accent data-[state=open]:bg-accent"
|
||||
asChild
|
||||
>
|
||||
{!item.fixedSize && (
|
||||
<OSButton
|
||||
size="xs"
|
||||
onClick={() => {
|
||||
setWindowOptionsTooltipVisible(false)
|
||||
if (size.width >= window?.innerWidth) {
|
||||
collapseWindow()
|
||||
} else {
|
||||
expandWindow()
|
||||
}
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
setWindowOptionsTooltipVisible(true)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setWindowOptionsTooltipVisible(false)
|
||||
}}
|
||||
className=" group"
|
||||
>
|
||||
<Tooltip
|
||||
trigger={
|
||||
<span>
|
||||
<IconSquare className="size-5 group-hover:hidden" />
|
||||
{!isSSR &&
|
||||
size.width >= window?.innerWidth ? (
|
||||
<IconCollapse45Chevrons className="size-6 -m-0.5 hidden group-hover:block" />
|
||||
) : (
|
||||
<IconExpand45Chevrons className="size-6 -m-0.5 hidden group-hover:block" />
|
||||
)}
|
||||
</span>
|
||||
}
|
||||
open={windowOptionsTooltipVisible}
|
||||
>
|
||||
Right click for more options
|
||||
</Tooltip>
|
||||
</OSButton>
|
||||
)}
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Portal>
|
||||
<ContextMenu.Content
|
||||
className="min-w-[220px] rounded-md bg-white dark:bg-accent-dark p-1 shadow-xl"
|
||||
data-scheme="primary"
|
||||
>
|
||||
<ContextMenu.Label className="px-2.5 text-[13px] leading-[25px] text-muted">
|
||||
Snap to...
|
||||
</ContextMenu.Label>
|
||||
<ContextMenu.Item
|
||||
className="group relative flex h-[25px] select-none items-center rounded px-2.5 text-sm leading-none text-primary hover:bg-accent outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-input-bg data-[disabled]:text-muted"
|
||||
onClick={() => handleSnapToSide('left')}
|
||||
>
|
||||
Left half
|
||||
<div className="ml-auto pl-5 text-secondary group-data-[disabled]:text-muted group-data-[highlighted]:text-primary">
|
||||
<KeyboardShortcut text="Shift" size="xs" />
|
||||
<KeyboardShortcut
|
||||
text={
|
||||
<IconArrowLeft className="size-3 inline-block" />
|
||||
}
|
||||
size="xs"
|
||||
/>
|
||||
</div>
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item
|
||||
className="group relative flex h-[25px] select-none items-center rounded px-2.5 text-sm leading-none text-primary hover:bg-accent outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-input-bg data-[disabled]:text-muted"
|
||||
onClick={() => handleSnapToSide('right')}
|
||||
>
|
||||
Right half
|
||||
<div className="ml-auto pl-5 text-secondary group-data-[disabled]:text-muted group-data-[highlighted]:text-primary">
|
||||
<KeyboardShortcut text="Shift" size="xs" />
|
||||
<KeyboardShortcut
|
||||
text={
|
||||
<IconArrowRight className="size-3 inline-block" />
|
||||
}
|
||||
size="xs"
|
||||
/>
|
||||
</div>
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Separator className="m-[5px] h-px bg-border" />
|
||||
<ContextMenu.Label className="px-2.5 text-[13px] leading-[25px] text-muted">
|
||||
Resize
|
||||
</ContextMenu.Label>
|
||||
<ContextMenu.Item
|
||||
disabled={
|
||||
size.width === (isSSR ? 0 : window?.innerWidth)
|
||||
}
|
||||
className="group relative flex h-[25px] select-none items-center rounded px-2.5 text-sm leading-none text-primary hover:bg-accent outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-input-bg data-[disabled]:text-muted"
|
||||
onClick={expandWindow}
|
||||
>
|
||||
Maximize
|
||||
<div className="ml-auto pl-5 text-secondary group-data-[disabled]:text-muted group-data-[highlighted]:text-primary">
|
||||
<KeyboardShortcut text="Shift" size="xs" />
|
||||
<KeyboardShortcut
|
||||
text={
|
||||
<IconArrowRight className="size-3 inline-block -rotate-90" />
|
||||
}
|
||||
size="xs"
|
||||
/>
|
||||
</div>
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.Content>
|
||||
</ContextMenu.Portal>
|
||||
</ContextMenu.Root>
|
||||
</>
|
||||
)}
|
||||
<Tooltip
|
||||
trigger={<OSButton size="md" onClick={handleClose} icon={<IconX />} />}
|
||||
>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<span>Close window</span>
|
||||
<div>
|
||||
<KeyboardShortcut text="Shift" size="xs" />
|
||||
|
||||
<KeyboardShortcut text="W" size="xs" />
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
ref={contentRef}
|
||||
className={`size-full flex-grow ${
|
||||
chrome ? 'bg-light dark:bg-dark overflow-hidden' : ''
|
||||
}`}
|
||||
>
|
||||
{(!animating || isSSR || item.appSettings?.size?.autoHeight) && (
|
||||
<Router
|
||||
minimizing={minimizing}
|
||||
onExit={() => {
|
||||
if (minimizing) {
|
||||
setMinimizing(false)
|
||||
if (siteSettings.experience === 'posthog') {
|
||||
setAnimating(true)
|
||||
}
|
||||
}
|
||||
}}
|
||||
{...item.props}
|
||||
>
|
||||
{item.element}
|
||||
</Router>
|
||||
)}
|
||||
</div>
|
||||
{!item.fixedSize && !item.minimal && (
|
||||
<motion.div
|
||||
data-scheme="tertiary"
|
||||
className="group absolute right-0 top-0 w-1.5 bottom-6 cursor-ew-resize !transform-none"
|
||||
drag="x"
|
||||
dragMomentum={false}
|
||||
dragConstraints={{ left: 0, right: 0 }}
|
||||
onDrag={(_event, info) => {
|
||||
updateWindow(item, {
|
||||
size: {
|
||||
width: Math.max(size.width + info.delta.x, sizeConstraints.min.width),
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div className="relative w-full h-full">
|
||||
<div className="hidden group-hover:block absolute inset-y-0 right-0 w-[2px] bg-light-8" />
|
||||
<div className="hidden group-hover:block absolute -bottom-6 h-6 right-0 w-[2px] bg-light-8" />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
{!item.fixedSize && !item.minimal && (
|
||||
<motion.div
|
||||
data-scheme="tertiary"
|
||||
className="group absolute bottom-0 left-0 right-6 h-1.5 cursor-ns-resize !transform-none"
|
||||
drag="y"
|
||||
dragMomentum={false}
|
||||
dragConstraints={{ top: 0, bottom: 0 }}
|
||||
onDrag={(_event, info) => {
|
||||
updateWindow(item, {
|
||||
size: {
|
||||
height: Math.max(
|
||||
size.height + info.delta.y,
|
||||
sizeConstraints.min.height
|
||||
),
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div className="relative w-full h-full">
|
||||
<div className="hidden group-hover:block absolute inset-x-0 bottom-0 h-[2px] bg-light-8" />
|
||||
<div className="hidden group-hover:block absolute bottom-0 -right-6 w-6 h-[2px] bg-light-8" />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
{!item.fixedSize && !item.minimal && (
|
||||
<motion.div
|
||||
className="group absolute bottom-0 right-0 w-6 h-6 cursor-se-resize flex items-center justify-center !transform-none"
|
||||
drag
|
||||
dragMomentum={false}
|
||||
dragConstraints={{ left: 0, top: 0, right: 0, bottom: 0 }}
|
||||
onDrag={(_event, info) => {
|
||||
updateWindow(item, {
|
||||
size: {
|
||||
width: Math.max(size.width + info.delta.x, sizeConstraints.min.width),
|
||||
|
||||
height: Math.max(
|
||||
size.height + info.delta.y,
|
||||
sizeConstraints.min.height
|
||||
),
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
<div className="hidden group-hover:block relative w-full h-full border-b border-r border-transparent overflow-hidden rounded-bl">
|
||||
<div className="absolute -bottom-10 -right-10 group-hover:-bottom-5 group-hover:-right-5 transition-all h-8 w-8 bg-accent-2 border-t border-light-8 -rotate-45" />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
</>
|
||||
)}
|
||||
</WindowContainer>
|
||||
</WindowProvider>
|
||||
)
|
||||
}
|
||||
@@ -86,7 +86,7 @@ function AppsPage({ location }) {
|
||||
Do even more cool stuff <br className="hidden lg:block" />
|
||||
<span className="text-blue">PostHog Apps</span>
|
||||
</h2>
|
||||
<p className="my-6 mx-auto text-center text-lg md:text-lg font-semibold mt-2 lg:mt-4 text-primary/75 dark:text-primary-dark/75 max-w-2xl">
|
||||
<p className="my-6 mx-auto text-center text-lg md:text-lg font-semibold mt-2 lg:mt-4 text-secondary max-w-2xl">
|
||||
Apps are built on the <Link to="/docs/api">PostHog API</Link>. They appear right inside PostHog, and
|
||||
if using PostHog.js, apps can also inject code directly into your website or product.
|
||||
</p>
|
||||
|
||||
@@ -30,7 +30,7 @@ export default function AshbyOpenRoles() {
|
||||
return (
|
||||
<li key={title}>
|
||||
<h3>{title}</h3>
|
||||
<ul className="list-none p-0 m-0 mt-4 mb-6 divide divide-y divide-light dark:divide-dark">
|
||||
<ul className="list-none p-0 m-0 mt-4 mb-6 divide divide-y divide-primary">
|
||||
{jobs
|
||||
.filter((job: OpenRoleType) => job.departmentName === title)
|
||||
.map((job: OpenRoleType) => {
|
||||
@@ -45,7 +45,7 @@ export default function AshbyOpenRoles() {
|
||||
return (
|
||||
<li className="" key={title}>
|
||||
<Link
|
||||
className="px-4 py-3 text-base -mb-1 border border-b-3 border-transparent hover:border-light dark:hover:border-dark hover:translate-y-[-1px] hover:bg-light dark:hover:bg-dark active:translate-y-[1px] active:transition-all rounded font-bold flex justify-between"
|
||||
className="px-4 py-3 text-base -mb-1 border border-b-3 border-transparent hover:border hover:translate-y-[-1px] hover:bg-light dark:hover:bg-dark active:translate-y-[1px] active:transition-all rounded font-bold flex justify-between"
|
||||
to={slug}
|
||||
>
|
||||
<div>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React from 'react'
|
||||
import { useChat } from 'hooks/useChat'
|
||||
import { useStaticQuery } from 'gatsby'
|
||||
import { graphql } from 'gatsby'
|
||||
import { IconLightBulb, IconSidebarOpen } from '@posthog/icons'
|
||||
import { CallToAction } from 'components/CallToAction'
|
||||
import { useLayoutData } from 'components/Layout/hooks'
|
||||
import usePostHog from 'hooks/usePostHog'
|
||||
import { useApp } from '../../context/App'
|
||||
import { useLocation } from '@reach/router'
|
||||
|
||||
interface AskMaxProps {
|
||||
border?: boolean
|
||||
@@ -24,7 +25,8 @@ export default function AskMax({
|
||||
}: AskMaxProps) {
|
||||
const posthog = usePostHog()
|
||||
const { compact } = useLayoutData()
|
||||
const { openChat, setQuickQuestions } = useChat()
|
||||
const { openNewChat } = useApp()
|
||||
const location = useLocation()
|
||||
const {
|
||||
allDocsPages: { totalDocsCount },
|
||||
} = useStaticQuery(graphql`
|
||||
@@ -35,14 +37,11 @@ export default function AskMax({
|
||||
}
|
||||
`)
|
||||
|
||||
const borderClasses = border ? 'py-6 mt-4 border-y border-light dark:border-dark' : 'mb-8'
|
||||
const borderClasses = border ? 'py-6 mt-4 border-y border-primary' : 'mb-8'
|
||||
|
||||
const handleChatOpen = () => {
|
||||
posthog?.capture('Opened MaxAI chat')
|
||||
if (quickQuestions) {
|
||||
setQuickQuestions(quickQuestions)
|
||||
}
|
||||
openChat()
|
||||
openNewChat({ path: `ask-max-${location.pathname}`, quickQuestions })
|
||||
}
|
||||
|
||||
if (linkOnly) {
|
||||
@@ -62,7 +61,7 @@ export default function AskMax({
|
||||
>
|
||||
<div className="flex-1 @2xl:flex-[0_0_auto] flex flex-col @lg:flex-row items-center justify-center gap-4">
|
||||
<div>
|
||||
<IconLightBulb className="size-10 inline-block bg-accent dark:bg-accent-dark rounded p-2 text-primary/50 dark:text-primary-dark/50" />
|
||||
<IconLightBulb className="size-10 inline-block bg-accent rounded p-2 text-muted" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col text-center @lg:text-left">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user