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.
Basic Usage
Get access to the complete Grain client instance:
import { useGrainAnalytics } from '@grainql/analytics-web/react' ;
function Component () {
const grain = useGrainAnalytics ();
// Use any client method
grain . setUserId ( 'user_123' );
grain . track ( 'event' , { data: 'value' });
await grain . flush ();
return < div > ...</ div > ;
}
This hook gives you the full client API for operations not covered by specialized hooks.
When to Use
Use useGrainAnalytics when you need:
User identification : setUserId(), identify()
User properties : setProperty()
Manual flushing : flush()
Template events : trackLogin(), trackPurchase(), etc.
Advanced config : fetchConfig(), preloadConfig()
Client management : destroy()
For common operations, prefer specialized hooks:
useConfig for configurations
useTrack for event tracking
useAllConfigs for multiple configs
User Identification
Set user ID when users log in:
function LoginHandler () {
const grain = useGrainAnalytics ();
const { user } = useAuth ();
useEffect (() => {
if ( user ) {
grain . identify ( user . id );
} else {
grain . setUserId ( null );
}
}, [ user , grain ]);
return < div > ...</ div > ;
}
Note : If you pass userId to GrainProvider, this happens automatically. Only use this hook if you need manual control.
User Properties
Set attributes for user profiles:
function ProfilePage () {
const grain = useGrainAnalytics ();
const handleUpgrade = async () => {
await grain . setProperty ({
plan: 'premium' ,
upgrade_date: new Date (). toISOString ()
});
// Show success message
};
return < button onClick ={ handleUpgrade }> Upgrade </ button > ;
}
Template Events
Use pre-built event methods:
function CheckoutPage () {
const grain = useGrainAnalytics ();
const handleCheckout = async ( order ) => {
await grain . trackCheckout ({
orderId: order . id ,
total: order . total ,
currency: 'USD' ,
paymentMethod: 'credit_card' ,
success: true
});
// Continue with checkout
};
return < button onClick ={ handleCheckout }> Checkout </ button > ;
}
Manual Flushing
Force send events immediately:
function CriticalAction () {
const grain = useGrainAnalytics ();
const handleAction = async () => {
grain . track ( 'critical_action' , { data: 'value' });
// Ensure event is sent before navigation
await grain . flush ();
router . push ( '/next-page' );
};
return < button onClick ={ handleAction }> Continue </ button > ;
}
Preload Configurations
Load configs before rendering:
function App () {
const grain = useGrainAnalytics ();
const [ ready , setReady ] = useState ( false );
useEffect (() => {
const loadConfigs = async () => {
await grain . preloadConfig ([
'hero_text' ,
'button_color' ,
'feature_enabled'
]);
setReady ( true );
};
loadConfigs ();
}, [ grain ]);
if ( ! ready ) return < div > Loading ...</ div > ;
return < HomePage />;
}
Now configs are available synchronously in child components.
Get Current User ID
Check who’s currently identified:
function UserStatus () {
const grain = useGrainAnalytics ();
const userId = grain . getUserId ();
return (
< div >
{ userId ? `Logged in as: ${ userId } ` : 'Anonymous' }
</ div >
);
}
Advanced Configuration
Fetch configurations with specific options:
function Component () {
const grain = useGrainAnalytics ();
const loadConfig = async () => {
const response = await grain . fetchConfig ({
immediateKeys: [ 'feature_flag' ],
properties: {
plan: 'premium' ,
location: 'US'
}
});
console . log ( 'Snapshot ID:' , response . snapshotId );
console . log ( 'Configs:' , response . configurations );
};
return < button onClick ={ loadConfig }> Load Config </ button > ;
}
Configuration Listeners
Add listeners for config changes:
function Component () {
const grain = useGrainAnalytics ();
useEffect (() => {
const listener = ( configs ) => {
console . log ( 'Configs updated:' , configs );
// Update UI or trigger actions
};
grain . addConfigChangeListener ( listener );
return () => {
grain . removeConfigChangeListener ( listener );
};
}, [ grain ]);
return < div > ...</ div > ;
}
Note : Usually not needed with hooks. useConfig and useAllConfigs handle updates automatically.
Cleanup
The client is automatically cleaned up when the provider unmounts. Manual cleanup is rarely needed:
function Component () {
const grain = useGrainAnalytics ();
useEffect (() => {
return () => {
// Only if you need manual cleanup
grain . destroy ();
};
}, [ grain ]);
return < div > ...</ div > ;
}
Stable Reference
The client reference returned by this hook is stable and won’t change between renders:
function Component () {
const grain = useGrainAnalytics ();
// Safe to use in effects without listing as dependency
useEffect (() => {
grain . track ( 'mounted' );
}, []); // grain is stable, no need in dependencies
return < div > ...</ div > ;
}
Authentication Flow Example
Complete authentication integration:
function AuthHandler () {
const grain = useGrainAnalytics ();
const { user } = useAuth ();
useEffect (() => {
const setupUser = async () => {
if ( user ) {
// Identify user
grain . identify ( user . id );
// Set user properties
await grain . setProperty ({
email: user . email ,
plan: user . plan ,
signup_date: user . createdAt
});
// Track login
await grain . trackLogin ({
method: user . loginMethod ,
success: true
});
} else {
// Clear user ID on logout
grain . setUserId ( null );
}
};
setupUser ();
}, [ user , grain ]);
return null ;
}
Next Steps
Core Methods API See all available methods
User Identification Learn about user tracking
Template Events Pre-built event methods