Objective
At OpenPecha, we recently added Matomo analytics to our translation editor tool so we can learn how people use it—while still protecting their privacy. In this post, I’ll walk you through how we set up Matomo tracking in our React app using the @datapunt/matomo-tracker-react package. The full code is based on our Matomo Tracker repository README and
Wiki user guide.
Setting Up Matomo in Our Translation Editor
1. Installation
First, install the React tracker package:
npm install @datapunt/matomo-tracker-react
2. Configuration in App.tsx
We set up Matomo at the top level of our app:
import { MatomoProvider, createInstance } from "@datapunt/matomo-tracker-react";
const instance = createInstance({
urlBase: "https://track.pecha.org/",
siteId: 2,
srcUrl: "https://track.pecha.org/matomo.js",
disabled: false,
heartBeat: {
active: true,
seconds: 10,
},
linkTracking: false,
configurations: {
disableCookies: true,
setSecureCookie: true,
setRequestMethod: "POST",
},
});
function App() {
return (
<MatomoProvider value={instance}>
{/* Application components */}
</MatomoProvider>
);
}
urlBasepoints to our Matomo server.- Heartbeat pings every 10 seconds to measure time on page.
- Cookies are turned off for better privacy.
- POST requests and secure cookies improve security.
3. Tracking Page Views with RouteTracker
We made a RouteTracker component that sends a page view each time the route changes:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { useMatomo } from "@datapunt/matomo-tracker-react";
import { useAuth } from "../auth/use-auth-hook";
const RouteTracker = () => {
const location = useLocation();
const { trackPageView, pushInstruction } = useMatomo();
const { isAuthenticated, currentUser } = useAuth();
useEffect(() => {
trackPageView({
documentTitle: document.title || location.pathname,
href: window.location.href,
customDimensions: [
{
id: 1,
value: isAuthenticated ? "loggedIn" : "notLoggedIn",
},
],
});
if (currentUser?.email) {
pushInstruction("setUserId", currentUser.email);
}
}, [location, isAuthenticated, trackPageView]);
return null;
};
export default RouteTracker;
- Tracks each page view.
- Adds a custom dimension to mark logged-in vs. guest users.
- Sets the user’s email as the Matomo user ID when they’re logged in.
4. Tracking Project Creation Events
In our Forms.tsx component, we track when someone makes a new project:
const handleCreateProject = () => {
//send event
trackEvent({
category: "submission",
action: "create",
name: "create-project", // optional
documentTitle: document.title, // optional
href: window.location.href, // optional
});
// Rest of the function...
}
Why this matters:
- Form Submissions: We see how often people start new projects.
- Action Categories: Labeling it as
"submission"with action"create"lets us filter these events easily. - Context: We capture page title and URL to know exactly where it happened.
- Conversion Tracking: Project creation is a key step—tracking it helps us measure success and find problems.
5. Tracking Search Results
In our ProjectList component, we track what people search for and how many results they get:
import { useMatomo } from "@datapunt/matomo-tracker-react";
const ProjectList = () => {
const { searchQuery } = useSearch();
const { trackSiteSearch } = useMatomo();
// ...other code...
useEffect(() => {
const result_count = projects?.length;
if (searchQuery && data?.pagination) {
trackSiteSearch({
keyword: searchQuery,
category: "search project",
count: result_count,
});
}
}, [searchQuery, projects, data?.pagination, trackSiteSearch]);
// ...rest of component...
};
keyword: The term the user searched.count: How many items showed up.category: Helps group search events in the analytics dashboard.
Benefits We’ve Gained
- User Journeys: We see exactly how people move through the app.
- Popular Features: We know which parts get the most use.
- Better Search: Search-tracking data guides improvements.
- Privacy First: Our settings keep user data safe.
Implementation Tips
- Debounce input events so you don’t send too many tracker calls.
- Track login state with a custom dimension for extra insight.
- Add route tracking early in your app to catch all page views.
- Review privacy settings—disable cookies if you can.
- Use POST requests for larger, more secure payloads.
Watch the live integration of Matomo on translations.pecha.tools by clicking here.
Integrating Matomo Analytics with React Frontend By Tashi Dhondup + Tenzin Kunsang
Conclusion
Adding Matomo to our React translation editor gave us clear, privacy-friendly insights into how people use our tool. By following the guide and code in the Matomo Tracker repo and its wiki, you can quickly add similar tracking to your own React apps. With these analytics in place, you can make data-driven decisions and keep your users’ data safe.
Reference:
- Matomo Tracker repo
- Custom User Guide: wiki
- Matomo Developer: API Reference
- Matomo Developer: Tracking API
- Matomo Developer: Tracking JavaScript API
- Matomo Developer: SPA Tracking Guide
- Matomo FAQ: Tracking in React Apps
- npm: @datapunt/matomo-tracker-react – createInstance() usage
- npm: @datapunt/matomo-tracker-react – Track page view example
- npm: @datapunt/matomo-tracker-react – Link click tracking
- npm: @datapunt/matomo-tracker-react – Optional dependencies & disableCookies
- npm: @datapunt/matomo-tracker-js – Dependents & usage examples
- Matomo JavaScript Tracking Guide: Trigger a goal conversion
- Matomo Developer: Tracking JS – Consent handling