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.
What is Personalization?
Personalization means showing different content to different users based on who they are, what they’ve done, or what they prefer. It makes your app feel tailored to each person.
Examples :
Premium users see advanced features
New users see onboarding tips
Users in different regions see localized content
Basic Personalization
Show different content based on user plan:
import { useConfig } from '@grainql/analytics-web/react' ;
function Hero () {
const { user } = useAuth ();
const { value : message } = useConfig ( 'hero_message' , {
properties: {
plan: user . plan
}
});
return < h1 >{message || 'Welcome!' } </ h1 > ;
}
Dashboard setup :
Free users: “Upgrade to unlock premium features”
Premium users: “Welcome back, premium member”
Enterprise users: “Your dedicated dashboard”
User Properties
Set properties to describe users:
function App () {
const grain = useGrainAnalytics ();
const { user } = useAuth ();
useEffect (() => {
if ( user ) {
grain . setUserId ( user . id );
grain . setProperty ({
plan: user . plan ,
signup_date: user . signupDate ,
location: user . country ,
language: user . language
});
}
}, [ user , grain ]);
return < AppContent />;
}
Now all configurations can use these properties for personalization.
Multi-Property Personalization
Combine multiple properties:
function Offer () {
const { user } = useAuth ();
const { value : offer } = useConfig ( 'special_offer' , {
properties: {
plan: user . plan ,
location: user . country ,
days_since_signup: calculateDays ( user . signupDate )
}
});
if ( ! offer ) return null ;
return < OfferBanner text ={ offer } />;
}
Dashboard rules :
New users (< 7 days) in US: “Get 20% off your first month”
Free users (> 30 days) in EU: “Upgrade now, save 15%”
All others: No offer
Content Localization
Show localized content:
function Pricing () {
const { user } = useAuth ();
const { value : currency } = useConfig ( 'currency' , {
properties: { location: user . country }
});
const { value : price } = useConfig ( 'monthly_price' , {
properties: { location: user . country }
});
return (
< div >
< h3 > Monthly Plan </ h3 >
< p >{ currency }{ price } / month </ p >
</ div >
);
}
US users see “$29”, UK users see “£24”, EU users see “€27”.
Behavioral Personalization
Personalize based on user behavior:
function Dashboard () {
const grain = useGrainAnalytics ();
const { user } = useAuth ();
// Set behavior properties
useEffect (() => {
grain . setProperty ({
login_count: user . loginCount . toString (),
last_feature_used: user . lastFeature ,
engagement_level: user . engagementScore
});
}, [ user , grain ]);
const { value : tutorialVisible } = useConfig ( 'show_tutorial' , {
properties: {
login_count: user . loginCount . toString ()
}
});
return (
<>
{ tutorialVisible === ' true ' && < Tutorial />}
< MainContent />
</>
);
}
Dashboard rule : Show tutorial if login_count < 5.
Time-Based Personalization
Personalize based on user tenure:
function WelcomeMessage () {
const { user } = useAuth ();
const daysSinceSignup = Math . floor (
( Date . now () - new Date ( user . signupDate ). getTime ()) / ( 1000 * 60 * 60 * 24 )
);
const { value : message } = useConfig ( 'welcome_message' , {
properties: {
days_since_signup: daysSinceSignup . toString ()
}
});
return < h2 >{message || 'Welcome!' } </ h2 > ;
}
Dashboard rules :
Day 1: “Welcome! Let’s get you started”
Days 2-7: “You’re off to a great start”
Days 8-30: “You’re getting the hang of it”
30+: “Thanks for being with us”
Feature Access Control
Control feature access by plan:
function AdvancedAnalytics () {
const { user } = useAuth ();
const { value : access } = useConfig ( 'analytics_access' , {
properties: {
plan: user . plan
}
});
if ( access !== 'granted' ) {
return (
< div >
< h3 > Advanced Analytics </ h3 >
< p > Upgrade to premium to unlock </ p >
< UpgradeButton />
</ div >
);
}
return < AnalyticsDashboard />;
}
Dashboard rule : if plan === 'premium' || plan === 'enterprise', return 'granted'.
Personalized Onboarding
Tailor onboarding to user type:
function Onboarding () {
const { user } = useAuth ();
const { value : onboardingType } = useConfig ( 'onboarding_flow' , {
properties: {
user_role: user . role ,
company_size: user . companySize
}
});
const flows = {
'solo' : < SoloOnboarding />,
'team' : < TeamOnboarding />,
'enterprise' : < EnterpriseOnboarding />
};
return flows [ onboardingType || 'solo' ];
}
Different onboarding for solopreneurs vs. teams vs. enterprises.
Recommendation Engine
Show personalized recommendations:
function Recommendations () {
const { user } = useAuth ();
const { value : recommendedFeatures } = useConfig ( 'recommended_features' , {
properties: {
plan: user . plan ,
features_used: user . featuresUsed . join ( ',' ),
industry: user . industry
}
});
const features = recommendedFeatures ?. split ( ',' ) || [];
return (
< div >
< h3 > Recommended for You </ h3 >
{ features . map ( feature => (
< FeatureCard key = { feature } name = { feature } />
))}
</ div >
);
}
Personalized Notifications
Customize notification preferences:
function NotificationCenter () {
const { user } = useAuth ();
const { value : notificationFreq } = useConfig ( 'notification_frequency' , {
properties: {
plan: user . plan ,
engagement_level: user . engagement
}
});
// High engagement users: real-time
// Medium engagement: daily digest
// Low engagement: weekly summary
return < Notifications frequency ={ notificationFreq || 'daily' } />;
}
Dynamic Pricing
Show personalized pricing:
function PricingCard () {
const { user } = useAuth ();
const { value : discount } = useConfig ( 'pricing_discount' , {
properties: {
plan: user . plan ,
days_since_signup: calculateDays ( user . signupDate ),
location: user . country
}
});
const basePrice = 29 ;
const discountAmount = parseInt ( discount || '0' );
const finalPrice = basePrice - ( basePrice * discountAmount / 100 );
return (
< div >
< h3 > Upgrade to Pro </ h3 >
{ discountAmount > 0 && (
< p className = "discount" > { discountAmount } % off special offer !</ p >
)}
< p className = "price" > $ { finalPrice } / month </ p >
</ div >
);
}
Testing Personalization
Test your personalization logic:
// Test with different user properties
const testCases = [
{ plan: 'free' , expected: 'Upgrade to unlock' },
{ plan: 'premium' , expected: 'Welcome back!' },
{ plan: 'enterprise' , expected: 'Your dashboard' }
];
testCases . forEach (({ plan , expected }) => {
const message = getConfigWithProperties ( 'hero_message' , { plan });
expect ( message ). toBe ( expected );
});
Best Practices
1. Start Simple : Begin with plan-based personalization, add complexity gradually.
2. Provide Defaults : Always have fallback content.
3. Respect Privacy : Only collect properties users consent to.
4. Test Thoroughly : Verify each personalization path works.
5. Monitor Performance : Track if personalization improves metrics.
Next Steps
User Properties Learn about user properties
Remote Config Master configuration management
A/B Testing Test personalization strategies