Documentation Index Fetch the complete documentation index at: https://docs.grainql.com/llms.txt
Use this file to discover all available pages before exploring further.
Install the Package
Initialize Grain
Call init() once at your app’s entry point. No provider or wrapper component needed:
// src/main.tsx or src/index.tsx
import { init } from '@grainql/tag' ;
init ({ tenantId: 'your-tenant-id' });
// ... rest of your app setup
Replace 'your-tenant-id' with the alias from your dashboard (not the UUID).
Pro tip : Store your tenant ID in an environment variable like VITE_GRAIN_TENANT_ID or REACT_APP_GRAIN_TENANT_ID.
Page views, heatmap clicks, scroll depth, and DOM snapshots are tracked automatically. No manual setup required.
Track Events
Import track directly from @grainql/tag and call it from any component:
import { track } from '@grainql/tag' ;
function SignupButton () {
const handleClick = () => {
track ( 'signup_clicked' , {
location: 'hero' ,
button_text: 'Get Started'
});
};
return < button onClick = { handleClick } > Get Started </ button > ;
}
Events are automatically batched and sent every few seconds. No manual flushing needed.
Identify Users
Associate events with a specific user after login:
import { identify } from '@grainql/tag' ;
function LoginForm () {
const handleLogin = async ( email : string , password : string ) => {
const user = await yourLoginFunction ( email , password );
identify ( user . id );
};
return < form onSubmit = { handleLogin } > ... </ form > ;
}
Consent Management
Grain is cookieless by default with daily rotating IDs. When you need explicit consent handling:
import { getInstance } from '@grainql/tag' ;
function ConsentBanner () {
const handleAccept = () => {
const grain = getInstance ();
grain ?. consent . grant ();
};
const handleDecline = () => {
const grain = getInstance ();
grain ?. consent . revoke ();
};
return (
< div >
< p > We use analytics to improve your experience. </ p >
< button onClick = { handleAccept } > Accept Analytics </ button >
< button onClick = { handleDecline } > Decline </ button >
</ div >
);
}
Complete Example
Here’s a small app that puts it all together:
// src/main.tsx
import React from 'react' ;
import ReactDOM from 'react-dom/client' ;
import { init } from '@grainql/tag' ;
import App from './App' ;
// Initialize Grain once at startup
init ({ tenantId: 'your-tenant-id' });
ReactDOM . createRoot ( document . getElementById ( 'root' ) ! ). render (
< React.StrictMode >
< App />
</ React.StrictMode >
);
// src/App.tsx
import { track , identify , getInstance } from '@grainql/tag' ;
function App () {
const handleSignup = ( userId : string ) => {
identify ( userId );
track ( 'signup_completed' , { method: 'email' });
};
return (
< div >
< h1 > Welcome! </ h1 >
< button onClick = { () => track ( 'cta_clicked' , { location: 'hero' }) } >
Get Started
</ button >
</ div >
);
}
export default App ;
Automatic page views : Grain Tag hooks into the History API to track navigation automatically. You do not need a PageViewTracker component or manual page_viewed calls — this works out of the box with React Router and other History API-based routers.
Cleanup on Unmount
If you need to tear down Grain (e.g., for testing or HMR), use destroy():
import { useEffect } from 'react' ;
import { init , destroy , isInitialized } from '@grainql/tag' ;
function App () {
useEffect (() => {
if ( ! isInitialized ()) {
init ({ tenantId: 'your-tenant-id' });
}
return () => {
destroy ();
};
}, []);
return < YourApp /> ;
}
What’s Next?
Core API Reference See all available methods and options
User Identification Learn about tracking users across sessions
Next.js Integration App Router and Pages Router setup
Event Best Practices Learn what to track and how to structure events
TypeScript users : @grainql/tag ships with full TypeScript declarations. You’ll get autocomplete and type checking out of the box.
Need Remote Config or React Hooks?
If you need remote configuration, feature flags, or React hooks (useConfig, useTrack, GrainProvider), install @grainql/analytics-web instead. See the Analytics Web React SDK for details.