React Charts is a popular visualization and charting library for React. It provides a simplified set of performant charts to use with analytics data from PostHog.
To provide examples of what you can do with it, we create a basic Next.js app, set it up to fetch data from PostHog's query API, and visualize it with React Charts.
Don't want to do all the work of querying and visualizing? You can always share or embed insights, dashboards, and more. See sharing docs for more.
Creating a Next.js app
To create a Next.js app, run the following command, choose all the default options, and select the app router.
Terminal
npx create-next-app@latest react-charts-example
This creates a react-charts-example folder with everything we need to get started.
Querying data from PostHog
Assuming you have data in PostHog to query, the next step is to set up our query request to PostHog.
Start by creating a personal API key. You can do this by going to personal API keys in your project settings, clicking Create personal API key, giving it a label, choosing the Performing analytics queries scope (AKA query read), and clicking Create key.
⚠️ Warning: The following is a simplified example. Exposing your personal API key or an endpoint that accepts arbitrary queries (like we do below) exposes your private PostHog data to the public internet, so don't do this in real life. Make sure your personal API key isn't exposed and your query request happens securely on the server side.
Next, go into your react-charts-example folder, then the app folder, and create an api folder. In the api folder, create a query.js file. Here we set up a fetch request to PostHog's query API endpoint using your project ID (from your PostHog URL) and personal API key like this:
app/api/query.js
exportconstfetchQuery=async(payload)=>{
const projectId ="12345";// e.g. if your PostHog dashboard URL is https://us.posthog.com/project/12345
Finally, in our client component, we make the query request using PostHog's query API and display the data:
JavaScript
// app/page.js
'use client'
import{ useState, useEffect }from'react'
import{ fetchQuery }from'./query'
exportdefaultfunctionHome(){
const[data, setData]=useState([])
constfetchData=async()=>{
const payload ={
"query":{
"kind":"HogQLQuery",
"query":"select properties.$current_url from events where properties.$current_url != null limit 10"
},
"name":"get 100 blog urls"
}
try{
const result =awaitfetchQuery(payload);
setData(result.results);
}catch(error){
console.error("Error fetching data:", error);
}
}
useEffect(()=>{
fetchData();
},[]);
return(
<main>
<pre>{JSON.stringify(data,null,2)}</pre>
</main>
)
}
The page we end up with is an ugly collection of non-aggregated data, but we'll fix that next.
Visualizing data with React Charts
With our app and query request set up, it's time to set up the visualization. To start, we install react-charts:
Terminal
npminstall react-charts
Once done, we can import the necessary components, format the data for React Charts, and set up the axes for the visualization. Some useful queries and visualizations include:
Line chart of pageviews by day
A basic query to start with is getting the count of $pageview events by day. To do this, we:
Write a query to select the date and count() of $pageview events grouped and ordered by date.
Change the format of the data from the array PostHog provides the object React Charts expects.
Set up the primaryAxis and secondaryAxes for the data.
Import and use the Chart component to visualize it.
This provides us with a nice visual of pageviews by day.
Bar chart of most popular paths
We can write a similar query to get the top paths by a count of pageviews. We swap in properties.$pathname AKA pathname, filter out null values, and order by the pageview_count. We also reverse the order of the results so the largest count is at the top.
To get all this data to fit, we use a horizontal bar chart. This requires changing our query, data formatting, and axes. This complete component looks like this:
We can do a more complicated visualization of pageviews by browser. The tricky part is formatting the data to work with the visualization. The query data from PostHog looks like this:
JavaScript
[
['2023-05-01','Chrome',100],
['2023-05-01','Firefox',50],
['2023-05-02','Chrome',120],
]
The data we want for the visualization looks like this:
JavaScript
[
{
"label":"Chrome",
"data":[
{
"date":"2023-05-01",
"pageviews":100
},
{
"date":"2023-05-02",
"pageviews":120
}
]
},
{
"label":"Firefox",
"data":[
{
"date":"2023-05-01",
"pageviews":50
},
{
"date":"2023-05-02",
"pageviews":0
}
]
},
]
Making this translation requires the following:
Getting all the unique dates and browsers from the query results.
Creating a map with all the dates and browsers with the pageviews set to zero.
Looping through the results to fill the actual pageview counts.
Converting the map to the required format.
Once done, there are some slight tweaks required to display it, such as using the area elementType. Together, this looks like this:
JavaScript
//... use client, imports
exportdefaultfunctionHome(){
const[data, setData]=useState([])
constfetchData=async()=>{
const payload ={
"query":{
"kind":"HogQLQuery",
"query":`SELECT
toDate(timestamp) AS date,
properties.$browser AS browser,
count() AS pageview_count
FROM events
WHERE event = '$pageview' AND properties.$browser IS NOT NULL