pieowl

How to add analytics to React

Add cookie-free analytics to your React app with the Pieowl Web SDK. Track page views, custom events and user behavior.

Pieowl TeamBeginner · 8 min · 8 Oct 2026
Guide · React

Analytics shows you how people use your React app. The Pieowl Web SDK works with React and React Router out of the box. You get page views, custom events and user identification without a separate React package.

The tracker never sets a cookie, so in many cases you don't need a consent banner for your analytics. See when you still do.

Prerequisites

  • A React project (Vite, Create React App or similar)
  • A Pieowl account (start a 14-day free trial)
  • Your Client ID from the Pieowl dashboard

Install the SDK

The Pieowl Web SDK is a small package that runs in any browser app, React included. Install it with npm. pnpm and yarn work the same way.

npm install @pieowl/web

Create a Pieowl instance

Create one file for your Pieowl instance. That keeps your setup in one place and lets you import the instance anywhere.

src/lib/pieowl.ts
import { Pieowl } from '@pieowl/web';

export const pieowl = new Pieowl({
  clientId: 'YOUR_CLIENT_ID',
});

Pieowl tracks a page view each time the URL changes. This works with React Router, TanStack Router and other client-side routers. What Pieowl collects by itself (page views, clicks on links to other sites, data-track clicks) is set in Settings → Site → What Pieowl counts, not in code.

Using environment variables

In production, keep your Client ID in an environment variable. Vite and Create React App read them in different ways.

src/lib/pieowl.ts (Vite)
import { Pieowl } from '@pieowl/web';

export const pieowl = new Pieowl({
  clientId: import.meta.env.VITE_PIEOWL_CLIENT_ID,
});
src/lib/pieowl.ts (Create React App)
import { Pieowl } from '@pieowl/web';

export const pieowl = new Pieowl({
  clientId: process.env.REACT_APP_PIEOWL_CLIENT_ID,
});

Initialize on app load

Import the instance in your app's entry point so it starts when your app loads. That's all you need for automatic page views.

src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './lib/pieowl'; // Start Pieowl

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Track page views

By default, Pieowl tracks a page view each time the URL changes. This works with React Router and any router that uses the History API.

If you want to track page views yourself, for example to add route data, call screenView from a component that listens for route changes.

src/components/PageTracker.tsx
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { pieowl } from '../lib/pieowl';

export function PageTracker() {
  const location = useLocation();

  useEffect(() => {
    pieowl.screenView({
      search: location.search,
    });
  }, [location.pathname, location.search]);

  return null;
}

screenView uses the current URL and page title. Put this component near the root of your app, inside your router. If you use it, turn off Page views in Settings → Site so page views are not counted twice.

Track custom events

Import the Pieowl instance wherever you want to track an event. track takes an event name and an optional object of properties.

src/components/SignupButton.tsx
import { pieowl } from '../lib/pieowl';

export function SignupButton() {
  const handleClick = () => {
    pieowl.track('button_clicked', {
      button_name: 'signup',
      button_location: 'hero',
    });
  };

  return (
    <button type="button" onClick={handleClick}>
      Sign Up
    </button>
  );
}

Track form submissions

Form tracking helps you see conversion rates and where users drop off.

src/components/ContactForm.tsx
import { useState } from 'react';
import { pieowl } from '../lib/pieowl';

export function ContactForm() {
  const [email, setEmail] = useState('');

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    pieowl.track('form_submitted', {
      form_name: 'contact',
      form_location: 'homepage',
    });

    // Your form submission logic
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Enter your email"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Use data attributes for declarative tracking

You can also track clicks with data-track attributes, without writing JavaScript.

<button
  data-track="button_clicked"
  data-button-name="signup"
  data-button-location="hero"
>
  Sign Up
</button>

When someone clicks this button, Pieowl sends a button_clicked event. The other data-* attributes become properties in camelCase: buttonName and buttonLocation. This needs Clicks you marked in your code to be on in Settings → Site (it is by default).

Identify users

When a user logs in, call identify to link their activity to a profile. This unlocks per-user analytics and cohorts.

src/hooks/useAuth.ts
import { useEffect } from 'react';
import { pieowl } from '../lib/pieowl';

export function useAuth(user: User | null) {
  useEffect(() => {
    if (user) {
      pieowl.identify({
        profileId: user.id,
        firstName: user.firstName,
        lastName: user.lastName,
        email: user.email,
        properties: {
          plan: user.plan,
          signupDate: user.createdAt,
        },
      });
    }
  }, [user]);
}

Pieowl keeps the profile ID in memory, not in a cookie or local storage. After a full page reload, call identify again. A hook like this one does that for you.

Clear user data on logout

When a user logs out, clear the profile so new events are not linked to them.

src/components/LogoutButton.tsx
import { pieowl } from '../lib/pieowl';

export function LogoutButton({ onLogout }: { onLogout: () => void }) {
  const handleLogout = () => {
    pieowl.clear();
    onLogout();
  };

  return <button onClick={handleLogout}>Logout</button>;
}

Set global properties

Properties set with setGlobalProperties are sent with every event. Use them for things like the app version or feature flags.

src/App.tsx
import { useEffect } from 'react';
import { pieowl } from './lib/pieowl';

export default function App() {
  useEffect(() => {
    pieowl.setGlobalProperties({
      app_version: '1.0.0',
      environment: import.meta.env.MODE,
    });
  }, []);

  return <div>{/* Your app */}</div>;
}

Verify your setup

Open your React app and visit a few pages. Click the elements that send custom events. Then open the Pieowl dashboard and check the realtime view.

No events? Check the browser console for errors. Make sure your Client ID is correct and that no ad blocker is blocking requests to api.pieowl.com. The Network tab in your browser's developer tools shows whether requests are being sent.

Next steps

The Web SDK can do more, such as profile counters and event filters. Read the Web SDK documentation for the full API.

For server-side tracking in your API routes, see the Node.js analytics guide, which covers the @pieowl/sdk package.

Does Pieowl work with React Router?

Yes. Pieowl tracks a page view each time the URL changes. This works with React Router and any router that uses the History API. Page views is on by default in Settings → Site.

Can I use Pieowl with class components?

Yes. Import the Pieowl instance and call its methods. The instance doesn't depend on React, so it works anywhere in your code.

Does Pieowl use cookies?

No. The tracker never sets a cookie and stores nothing on your visitors' devices. In many cases that means no consent banner for your analytics. See Do you need a cookie banner?.

Does Pieowl help with GDPR?

Pieowl is built for GDPR: no cookies, no stored IPs. Your data is stored in the EU. Ask your legal advisor about your own setup.

Your first dashboard in five minutes.

14-day free trial, no card needed. Cloud in the EU. No cookies.