You can contribute to the PostHog documentation, handbook, and blog in two ways:
You can create a pull request in GitHub for any page that has an Edit this page link on it. In this situation you must edit the page using the GitHub web editor interface. This method is suitable for text-only edits and basic file manipulation, such as renaming.
You can run the posthog.com website locally and make changes there by creating a branch of the master codebase, committing changes to that branch and raising a pull request to merge those changes. This is the recommended method as it allows you to quickly preview your changes, as well as perform more complex changes easily.
Below, we'll explain how to set up option two.
Editing posthog.com locally
Before you begin
In order to run the PostHog website locally, you need the following installed:
- Git – version control system
- Node.js – server runtime
- Yarn (version 1.x) – package manager for Node.js
- Apple Rosetta (version 2) – dynamic binary translator for Apple silicon
If you are unfamiliar with using Git from the command line (or just prefer graphical interfaces), use the GitHub Desktop app.
You may also want to familiarize yourself with these resources:
Cloning the posthog.com repository
The posthog.com codebase is on GitHub at https://github.com/PostHog/posthog.com. To work on it locally, first you need to clone it to your disk:
via the command line
You can clone the codebase from the command line using the following command:
Terminalgit clone git@github.com:PostHog/posthog.com.gitvia GitHub Desktop
You can also clone the repository with GitHub Desktop installed, from the posthog.com repository page, click the Code button and select Open with GitHub Desktop from the dropdown that appears.
You will then be prompted by the browser to confirm if you want to open the GitHub Desktop application. Select the affirmative action that has text such as Open GitHub Desktop.
Once GitHub Desktop has opened you will be prompted to confirm the repository that is being cloned and the location on disk where you wish the code to be stored.
Click Clone to clone the posthog.com repository to your local disk.
Once the clone has completed the GitHub Desktop interface will change to the following:
To view the code for the website click Open in Visual Studio Code. Dialogs may appear around permissions and trust as you open Visual Studio Code.
Once you have Visual Studio Code open, select the Terminal menu option. Within the dropdown select New Terminal. This will open a new terminal window within Visual Studio Code:
Don't worry! We only need to run a few commands in the command line.
Running posthog.com locally
If you're using an Apple Silicon Mac (M1) then you'll need to run the following commands before using yarn:
rm -rf ./node_modulesbrew install vips
Type the following into the command line and press return:
yarn
This runs the Yarn tool. When run standalone like this, it installs the dependency packages used by posthog.com. This may take a few minutes.
Once this command has finished executing, run the following:
yarn start
This runs the local clone of the website, which you can use to preview changes you make before pushing them live. It takes a bit of time for some file processing and compilation to take place, but once it's completed you can access the locally running version of posthog.com via by visiting http://localhost:8001
in your web browser.
Any time you want to preview changes you are making to the local version of the website, all you have to do is run the yarn start
again, wait for the command to finish running and then open http://localhost:8001
in your web browser.
Environment variables
Our website uses various APIs to pull in data from sites like GitHub (for contributors) and Ashby (our applicant tracking system). Without setting these environment variables, you may see various errors when building the site. Most of these errors are dismissible, and you can continue to edit the website.
If you're a core team member and need this data locally, you can:
- Ask the Website & Docs team files located for access to our Vercel account
- Install the Vercel CLI
- Run
vercel pull
- Open
.vercel/.env.development.local
- Copy a value and run in your terminal like:
export VARIABLE_NAME=VALUE
Finding the content to edit
Once you have cloned the repo, the contents/
directory contains a few key areas:
docs/
= all of the documentation for PostHog's platformhandbook/
= the PostHog company handbookblog/
= our blog posts
Inside each of these are a series of markdown files for you to edit.
Making edits
Creating a new Git branch
When editing locally, changes should be made on a new Git branch. Branches should be given an "at a glance" informative name. For example, posthog-website-contribution
.
via the command line You can create a new Git branch from the command line by running:
Terminalgit checkout -b [new-branch-name]For example:
Terminalgit checkout -b posthog-website-contribution
via GitHub Desktop
You can also create a new branch in GitHub Desktop by selecting the dropdown next to the Current Branch name and clicking New Branch.
Then, in the dialog that follows, entering the new branch name.
Once you have a new branch, you can make changes.
Markdown details
Frontmatter
Most PostHog pages utilize frontmatter as a way of providing additional data to the page. Available frontmatter varies based on the template the page uses. Templates are determined based on the folder the file resides in:
Blog
Markdown files located in `/contents/blog``
---date: 2021-11-16title: The state of plugins on PostHogrootPage: /blogauthor: ["yakko-majuri"]featuredVideo: https://www.youtube-nocookie.com/embed/TCyCryTiTbQfeaturedImage: https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/blog/running-content.pngfeaturedImageType: fullcategory: Guidestags: ["Using PostHog", "Privacy"]seo: {metaTitle: Overview of PostHog PluginsmetaDescription: Learn about the current state of plugins on PostHog and get valuable insights into their functionality and performance.}---
date
: the date the blog was postedtitle
: the title that appears at the top of the blog post and on the blog listing pagerootPage
: necessary for listing all blog posts on /blog. should always be set to/blog
author
: the author(s) of the post. correlates to your handle located in /src/data/authors.jsonfeaturedVideo
: the iframe src of the video that appears at the top of the post. replaces the featured image on post pages.featuredImage
: the Cloudinary URL of the image that appears at the top of the post and on the blog listing pagefeaturedImageType
:standard
|full
- determines the width of the featured image on the blog postcategory
: the broader category the post belongs to. one of the following:CEO diaries
Engineering
General
Inside PostHog
PostHog news
Product growth
Startups
Using PostHog
tags
: the more specific tag(s) the post belongs to. an array containing any number of the following:ClickHouse
Comparisons
Explainers
Feature flags
Guides
Launch week
Marketing
Offsites
Open source
Privacy
Product analytics
Product engineers
Product metrics
Product updates
Release notes
Startups
Y Combinator
seo
: object containing SEO metadata:metaTitle
: StringmetaDescription
: String
Tutorials
Markdown files located in /contents/tutorials
---date: 2022-02-14title: How to filter out internal usersauthor: ["joe-martin"]featuredTutorial: falsefeaturedVideo: https://www.youtube-nocookie.com/embed/2bptTniYPGctags: ['filters', 'settings']---
date
: the date the tutorial was postedtitle
: the title that appears at the top of the tutorial and on the tutorial listing pageauthor
: the author(s) of the tutorial. Ccrrelates to your handle located in /src/data/authors.jsonfeaturedTutorial
: determines if tutorial should be featured on the homepagefeaturedVideo
: the iframe src of the video that appears at the top of the tutorialfeaturedImage
: the Cloudinary URL of the image that appears at the top of the tutorial and on the tutorial listing pagetags
: the tag(s) the tutorial belongs to. an array containing any number of the following:actions
apps
cdp
cohorts
configuration
correlation analysis
dashboards
data management
events
experimentation
feature flags
filters
funnels
group analytics
heatmaps
hogql
insights
lifecycle
paths
persons
product analytics
product os
retention
sentry
session replay
sessions
settings
site-apps
stickiness
subscriptions
surveys
toolbar
trends
user paths
zapier
seo
: object containing SEO metadata:metaTitle
: StringmetaDescription
: String
Docs & Handbook
Markdown files located in /contents/docs and /contents/handbook
---title: Contribute to the website: documentation, handbook, and blog---
title
: the title that appears at the top of the handbook / doc pageseo
: object containing SEO metadata:metaTitle
: StringmetaDescription
: String
Comparison pages
Create a table on a "PostHog vs..." page with the following components. (You can see examples of how this is used in this pull request.)
Import the components at the top of the post content (after frontmatter):
import { ComparisonTable } from 'components/ComparisonTable'import { ComparisonRow } from 'components/ComparisonTable/row'import { ComparisonHeader } from 'components/ComparisonTable/header'
Create a table like:
<ComparisonTable column1="Company name 1" column2="Company name 2"><ComparisonHeader category="Optional header row" /><ComparisonRow column1={true} column2="Text" feature="Feature name" description="Feature descrpition" /></ComparisonTable>
In ComparisonRow
:
- Values for
column1
andcolumn2
can be:{true}
|{false}
|"Text string"
feature
is required butdescription
can be omitted (only if not using that column for the entire table)
Customers
Markdown files located in /contents/customers
---title: How Hasura improved conversion rates by 10-20% with PostHogcustomer: Hasuralogo: https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/hasura/logo.svgfeaturedImage: https://res.cloudinary.com/dmukukwp6/image/upload/posthog.com/contents/images/customers/hasura/featured.jpgindustries:- Developer toolusers:- Engineering- UI- UX- Marketing teamstoolsUsed:- Funnel Analysis- Session Recording- Self-Hosting---
title
: the title of the case studycustomer
: the name of the customerlogo
: the customer logofeaturedImage
: the Cloudinary URL of the image that appears in the card on the customers listing pageindustries
: a list of industries that apply to the companyusers
: a list of user types that use the company's producttoolsUsed
: a list of highlighted PostHog tools used by the companyseo
: object containing SEO metadata:metaTitle
: StringmetaDescription
: String
Plain
If the file doesn't reside in one of the above folders, it uses the plain template.
---title: Example ComponentsshowTitle: falsewidth: lgnoindex: true---
title
: the title that appears at the top of the pageshowTitle
:false
- if omitted, the title will appear at the top of the pagewidth
:sm
|md
|lg
|full
- determines the width of the pagenoindex
:true
|false
- determines whether to index the page or notseo
: object containing SEO metadata:metaTitle
: StringmetaDescription
: String
You can often refer to the source of existing pages for more examples, but if in doubt, you can always ask for help.
Images/GIFs
If you need to upload images, you can upload them to Cloudinary
To include an image in a markdown file, you can use Cloudinary URLs, like so:
![Twin Peaks](https://res.cloudinary.com/dmukukwp6/image/upload/v1710055416/posthog.com/contents/handbook/engineering/images/02/IMG_4294-scaled.jpg)
In this case, Twin Peaks
is the alt-text applied to the image.
Links to/from the navigation
Once you've made a new markdown file, you should link to it from the sidebar where appropriate.
The sidebar is generated from src/navs/index.js
.
Redirects
Redirects are managed in vercel.json
which is located in the root folder.
To declare a new redirect, open vercel.json
and add an entry to the redirects
list:
{ "source": "/docs/contributing/stack", "destination": "/docs/contribute/stack" }
The default HTTP status code is 308 (permanent), but if the redirect should be temporary (307), it can be updated like this:
{ "source": "/docs/contributing/stack", "destination": "/docs/contribute/stack", "permanent": false }
Committing changes
It's best to create commits that are focused on one specific area. For example, create one commit for textual changes and another for functional ones. Another example is creating a commit for changes to a section of the handbook and a different commit for updates to the documentation. This helps the pull request review process and also means specific commits can be cherry picked.
via the command line
First, stage your changes:
Terminalgit add [path-to-file]For example:
Terminalgit add contents/docs/contribute/updating-documentation.mdOnce all the files that have been changed are staged, you can perform the commit:
Terminalgit commit -m '[short commit message]'For example:
Terminalgit commit -m 'Adding details on how to commit'via GitHub Desktop
Files that have been changed can be viewed within GitHub Desktop along with a diff of the specific change.
Select the files that you want to be part of the commit by ensuring the checkbox to the left of the file is checked within GitHub Desktop. Then, write a short descriptive commit message and click the Commit to... button.
Push changes to GitHub
In order to request that the changes you have made are merged into the main website branch you must first push them to GitHub.
via the command line
Terminalgit push origin [branch-name]For example:
Terminalgit push origin posthog-website-contributionWhen this is done, the command line will show output similar to the following:
Terminalposthog-website-contribution $ git push origin posthog-website-contributionTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0remote:remote: Create a pull request for 'posthog-website-contribution' on GitHub by visiting:remote: https://github.com/PostHog/posthog.com/pull/new/posthog-website-contributionremote:To github.com:PostHog/posthog.com.git* [new branch] posthog-website-contribution -> posthog-website-contributionThis output tells you that you can create a pull request by visiting a link. In the case above, the link is
https://github.com/PostHog/posthog.com/pull/new/posthog-website-contribution
. Follow the link to complete your pull request.via GitHub Desktop
Once you have committed the changes you want to push to GitHub, click the Push origin button.
Create a pull request
Create a pull request to request that your changes be merged into the main branch of the repository.
via the command line
Navigate to the link shown when you push your branch to GitHub. For example,
https://github.com/PostHog/posthog.com/pull/new/posthog-website-contribution
shown below:Terminalposthog-website-contribution $ git push origin posthog-website-contributionTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0remote:remote: Create a pull request for 'posthog-website-contribution' on GitHub by visiting:remote: https://github.com/PostHog/posthog.com/pull/new/posthog-website-contributionremote:To github.com:PostHog/posthog.com.git* [new branch] posthog-website-contribution -> posthog-website-contributionvia GitHub Desktop
With the branch published, click the Create pull request button.
This will open up a page on github.com in your default web browser.
If you are pushing to an existing branch, navigate to the posthog.com repo and switch to the new branch using the dropdown:
Then, open the Contribute dropdown and click the Open pull request button.
Make the pull request title descriptive name and complete the detail requested in the body.
If you know who you would like to review the pull request, select them in the Reviewers dropdown.
Preview branch
After a series of checks are run (to ensure nothing in your pull request breaks the website), Vercel will generate a preview link available in the Vercel bot comment. This includes all of your changes, so you can preview before your pull request is merged.
Note: Checks are run automatically for PostHog org members and previous contributors. First time contributors will require authorization for checks to be run by a PostHog org member.
Deployment
To get changes into production, the website deploys automatically from master
. The build takes 5-10 minutes.