Analytics

BusinessDash's analytics packages let you track page views and custom events from your own site, with data appearing in your BusinessDash dashboard's analytics section.

// Core analytics — send raw events
import { trackEvent, identifyUser } from '@businessdash/sdk/analytics-core'

identifyUser({ id: 'user-1', email: 'jane@example.com' })
trackEvent({ name: 'view_pricing', properties: { plan: 'growth' } })

React

import { AnalyticsProvider, useTrack } from '@businessdash/sdk/react-analytics'

function App() {
  return (
    <AnalyticsProvider apiKey={process.env.NEXT_PUBLIC_BD_PK}>
      <PageViewTracker />
      <PricingPage />
    </AnalyticsProvider>
  )
}

function PricingPage() {
  const track = useTrack()
  return (
    <button onClick={() => track('click_cta', { location: 'pricing-hero' })}>
      Get started
    </button>
  )
}

Events appear in your BusinessDash dashboard under Analytics — real-time and aggregated views.

Reading visitor counts back

The tracker above only records. To put a number on the page — "1,204 visitors", or a view count under a portfolio item — read the counts back with the analytics client:

import { createBdApiClient } from '@businessdash/sdk'

const bd = createBdApiClient({
  apiKey: process.env.NEXT_PUBLIC_BD_PK!,   // publishable key is fine here
  baseUrl: process.env.NEXT_PUBLIC_BD_PACKAGE_API_BASE_URL!,
})

// Site-wide, all time
const all = await bd.site(siteId).analytics.pageViews()
if (all.available) {
  console.log(`${all.total.views} views · ${all.total.visitors} visitors`)
}

// One page, last 30 days
const home = await bd.site(siteId).analytics.pageViews({ paths: ['/'], days: 30 })

// A batch of pages in one round-trip — e.g. a view count per portfolio item
const items = await bd.site(siteId).analytics.pageViews({
  paths: ['/work/atrium', '/work/harbor', '/work/mesa'],
})
if (items.available) {
  for (const p of items.paths) console.log(`${p.path}: ${p.views}`)
}

Pass paths for a per-path breakdown (each requested path comes back, 0 if it has no views yet) plus a combined total; omit them for a site-wide total. days windows the count; omit for all-time. Branch on .available — visitor analytics is a plan feature, so an org without it gets { available: false } rather than an error.

visitors is an approximation. It counts distinct daily-rotating anonymous ids — exact within a single day, and over a longer window it counts a returning visitor once per day they came. It never identifies anyone. Use views for the precise pageview number, visitors for a "roughly this many people" figure.

These counts become public the moment you read them with a publishable key. That's the point for an on-page counter — but if you'd rather keep your traffic numbers private, read them server-side with a secret key and decide what to render. The scope (analytics:read) returns only totals for your own site: never an event, an IP, or a visitor id.

A drop-in visitor counter

In a React Server Component, this is the whole thing — a live count on the page:

// components/VisitorCount.tsx (Server Component)
import { bd } from '@/lib/bd'   // your configured createBdApiClient

export async function VisitorCount({ siteId }: { siteId: string }) {
  const result = await bd.site(siteId).analytics.pageViews()
  if (!result.available) return null
  return (
    <p className="text-sm text-muted-foreground">
      {result.total.views.toLocaleString()} views
    </p>
  )
}

The same call works at build time, in a route handler, or on the client — pick the one that fits how fresh the number needs to be.