Server-Side Tracking
The Solute SDK provides server-side utilities for tracking events and using feature flags in Next.js Server Components and API routes.
Why Server-Side Tracking?
Server-side tracking offers several advantages:
- Privacy: Track events without exposing tracking code to clients
- Reliability: Events are sent even if JavaScript is disabled
- Performance: No client-side JavaScript overhead
- Security: API keys stay on the server
Track Server Events
Track events from Server Components or API routes:
// app/actions.ts
'use server';
import { trackServerEvent } from '@solute-ai/sdk/nextjs';
export async function createOrder(orderData: any) {
// Create order...
// Track event
await trackServerEvent(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'Order Created',
{
order_id: orderData.id,
amount: orderData.amount,
currency: 'USD',
}
);
}
Server Components
Track events in Server Components:
// app/page.tsx
import { trackServerEvent } from '@solute-ai/sdk/nextjs';
export default async function HomePage() {
// Track page view
await trackServerEvent(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'Page Viewed',
{
page: '/homepage',
}
);
return <div>Home Page</div>;
}
API Routes
Track events in API routes:
// app/api/checkout/route.ts
import { trackServerEvent } from '@solute-ai/sdk/nextjs';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const data = await request.json();
// Process checkout...
// Track event
await trackServerEvent(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'Checkout Completed',
{
order_id: data.orderId,
amount: data.amount,
}
);
return NextResponse.json({ success: true });
}
Server-Side Feature Flags
Get feature flags on the server for Server-Side Rendering (SSR):
// app/page.tsx
import { isServerFeatureEnabled, getServerFeatureFlag } from '@solute-ai/sdk/nextjs';
export default async function HomePage() {
// Check if feature is enabled
const showHero = await isServerFeatureEnabled(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'new-hero-section',
false
);
// Get feature flag value
const heroConfig = await getServerFeatureFlag(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'hero-config',
{ theme: 'default' }
);
return (
<div>
{showHero ? (
<NewHeroSection config={heroConfig} />
) : (
<OldHeroSection />
)}
</div>
);
}
Server-Side Experiments
Get experiment variants on the server:
// app/pricing/page.tsx
import { getServerExperimentVariant } from '@solute-ai/sdk/nextjs';
export default async function PricingPage() {
const variant = await getServerExperimentVariant(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'pricing-test',
'control'
);
return (
<div>
{variant === 'variant-a' ? (
<NewPricingLayout />
) : (
<OriginalPricingLayout />
)}
</div>
);
}
User Context
Get user context from cookies:
// app/profile/page.tsx
import { getUserIdFromCookies, getAnonymousIdFromCookies } from '@solute-ai/sdk/nextjs';
import { trackServerEvent } from '@solute-ai/sdk/nextjs';
export default async function ProfilePage() {
const userId = await getUserIdFromCookies();
const anonymousId = await getAnonymousIdFromCookies();
// Track with user context
await trackServerEvent(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
'Profile Viewed',
{
page: '/profile',
},
{
userId,
anonymousId,
}
);
return <div>Profile Page</div>;
}
Request Context
Get request context (user agent, IP, etc.):
// app/api/track/route.ts
import { getRequestContext, trackServerEvent } from '@solute-ai/sdk/nextjs';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const context = await getRequestContext();
const data = await request.json();
await trackServerEvent(
{
apiKey: process.env.SOLUTE_API_KEY!,
host: 'https://api.solute.dev',
},
data.event,
data.properties,
{
userAgent: context.userAgent,
ip: context.ip,
}
);
return NextResponse.json({ success: true });
}
Environment Variables
Set up server-side environment variables:
# Server-side (private - no NEXT_PUBLIC_ prefix)
SOLUTE_API_KEY=your_api_key_here
SOLUTE_HOST=https://api.solute.dev
Never expose server-side API keys to the client. Don’t use NEXT_PUBLIC_ prefix for server-side variables.
Best Practices
Use server-side tracking for sensitive events
Track sensitive events (purchases, signups) on the server to prevent tampering.
Use feature flags for SSR
Use server-side feature flags to render different content on the server for better SEO and performance.
Never expose server-side API keys. Use environment variables without NEXT_PUBLIC_ prefix.
Wrap server-side tracking calls in try-catch blocks to prevent errors from breaking your app.
Next Steps