Provider Components
API reference for Adopture provider components
Provider Components API Reference
Complete reference for Adopture provider components that wrap your Next.js application.
AdoptureProvider
Provider component for Next.js App Router applications.
import { AdoptureProvider } from '@adopture/next';
<AdoptureProvider config={config} fallback={fallback} loadingComponent={loading}>
{children}
</AdoptureProvider>Props
| Prop | Type | Required | Description |
|---|---|---|---|
children | ReactNode | ✅ | Your application components |
config | NextAdoptureConfig | ❌ | Configuration options |
fallback | ReactNode | ❌ | Fallback component for errors |
loadingComponent | ReactNode | ❌ | Loading component during initialization |
NextAdoptureConfig Type
interface NextAdoptureConfig {
apiKey?: string;
apiUrl?: string;
debug?: boolean;
batchSize?: number;
flushInterval?: number;
timeout?: number;
}Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | process.env.NEXT_PUBLIC_ADOPTURE_API_KEY | Your Adopture API key |
apiUrl | string | 'https://api.adopture.com' | API endpoint URL |
debug | boolean | false | Enable debug logging |
batchSize | number | 50 | Events to batch before sending |
flushInterval | number | 5000 | Interval (ms) to flush events |
timeout | number | 10000 | Request timeout (ms) |
Basic Usage
import { AdoptureProvider } from '@adopture/next';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AdoptureProvider>
{children}
</AdoptureProvider>
</body>
</html>
);
}Advanced Configuration
import { AdoptureProvider } from '@adopture/next';
const adoptureConfig = {
debug: process.env.NODE_ENV === 'development',
batchSize: 100,
flushInterval: 3000,
timeout: 15000,
};
const LoadingFallback = () => (
<div className="flex items-center justify-center h-screen">
<div>Initializing analytics...</div>
</div>
);
const ErrorFallback = () => (
<div className="bg-yellow-50 p-4 rounded">
<p>Analytics temporarily unavailable</p>
</div>
);
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AdoptureProvider
config={adoptureConfig}
loadingComponent={<LoadingFallback />}
fallback={<ErrorFallback />}
>
{children}
</AdoptureProvider>
</body>
</html>
);
}AdopturePagesProvider
Provider component for Next.js Pages Router applications.
import { AdopturePagesProvider } from '@adopture/next';
<AdopturePagesProvider config={config} fallback={fallback} loadingComponent={loading}>
{children}
</AdopturePagesProvider>Props
Same as AdoptureProvider but optimized for Pages Router.
Usage
import { AdopturePagesProvider } from '@adopture/next';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<AdopturePagesProvider>
<Component {...pageProps} />
</AdopturePagesProvider>
);
}Advanced Configuration
import { AdopturePagesProvider } from '@adopture/next';
import type { AppProps } from 'next/app';
const adoptureConfig = {
debug: process.env.NODE_ENV === 'development',
batchSize: 50,
flushInterval: 5000,
};
export default function App({ Component, pageProps }: AppProps) {
return (
<AdopturePagesProvider
config={adoptureConfig}
fallback={<div>Analytics unavailable</div>}
>
<Component {...pageProps} />
</AdopturePagesProvider>
);
}AdoptureBootstrap
Component for injecting server-side bootstrap data.
import { AdoptureBootstrap } from '@adopture/next';
<AdoptureBootstrap data={bootstrapData} />Props
| Prop | Type | Required | Description |
|---|---|---|---|
data | BootstrapData | ✅ | Server-side bootstrap data |
BootstrapData Type
interface BootstrapData {
config: NextAdoptureConfig;
sessionId: string;
timestamp: number;
initialUserId?: string;
initialUserProperties?: UserProperties;
}Usage
import { AdoptureProvider, AdoptureBootstrap } from '@adopture/next';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const bootstrapData = {
config: {
apiKey: process.env.NEXT_PUBLIC_ADOPTURE_API_KEY,
debug: process.env.NODE_ENV === 'development',
},
sessionId: 'session-123',
timestamp: Date.now(),
initialUserId: 'user-456',
initialUserProperties: {
plan: 'premium',
email: 'user@example.com',
},
};
return (
<html lang="en">
<head>
<AdoptureBootstrap data={bootstrapData} />
</head>
<body>
<AdoptureProvider>
{children}
</AdoptureProvider>
</body>
</html>
);
}useAdopture
Hook to access the Adopture context directly.
import { useAdopture } from '@adopture/next';
const {
tracker,
isInitialized,
isLoading,
error,
config
} = useAdopture();Returns
| Property | Type | Description |
|---|---|---|
tracker | NextAdoptureTracker | null | Tracker instance |
isInitialized | boolean | Whether tracker is initialized |
isLoading | boolean | Whether tracker is loading |
error | Error | null | Initialization error |
config | NextAdoptureConfig | null | Current configuration |
Example
'use client';
import { useAdopture } from '@adopture/next';
export function DebugPanel() {
const { tracker, isInitialized, isLoading, error, config } = useAdopture();
if (isLoading) {
return <div>Loading Adopture...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
if (!isInitialized) {
return <div>Adopture not initialized</div>;
}
return (
<div className="debug-panel">
<h3>Adopture Debug Panel</h3>
<p>Status: {isInitialized ? 'Ready' : 'Not Ready'}</p>
<p>Debug Mode: {config?.debug ? 'On' : 'Off'}</p>
<p>Batch Size: {config?.batchSize}</p>
<p>Flush Interval: {config?.flushInterval}ms</p>
</div>
);
}useAdoptureTracker
Hook to access the tracker instance directly.
import { useAdoptureTracker } from '@adopture/next';
const tracker = useAdoptureTracker();Returns
| Property | Type | Description |
|---|---|---|
tracker | NextAdoptureTracker | null | Tracker instance or null |
Example
'use client';
import { useAdoptureTracker } from '@adopture/next';
export function AdvancedTracking() {
const tracker = useAdoptureTracker();
const handleAdvancedEvent = async () => {
if (tracker) {
// Direct access to tracker methods
await tracker.track('advanced-event', {
timestamp: Date.now(),
complex: true,
});
}
};
return (
<button onClick={handleAdvancedEvent}>
Advanced Event
</button>
);
}Environment Configuration
Configure providers through environment variables:
# Required
NEXT_PUBLIC_ADOPTURE_API_KEY=your_api_key_here
# Optional - Provider configuration
NEXT_PUBLIC_ADOPTURE_API_URL=https://api.adopture.com
NEXT_PUBLIC_ADOPTURE_DEBUG=true
NEXT_PUBLIC_ADOPTURE_BATCH_SIZE=50
NEXT_PUBLIC_ADOPTURE_FLUSH_INTERVAL=5000
NEXT_PUBLIC_ADOPTURE_TIMEOUT=10000Error Handling
Provider-Level Error Handling
const ErrorFallback = ({ error }: { error: Error }) => (
<div className="error-boundary">
<h2>Analytics Error</h2>
<p>{error.message}</p>
<button onClick={() => window.location.reload()}>
Retry
</button>
</div>
);
<AdoptureProvider
fallback={<ErrorFallback error={new Error('Sample error')} />}
>
{children}
</AdoptureProvider>Global Error Handling
'use client';
import { useAdopture } from '@adopture/next';
import { useEffect } from 'react';
export function GlobalErrorHandler() {
const { error } = useAdopture();
useEffect(() => {
if (error) {
console.error('Adopture initialization failed:', error);
// Report to error tracking service
// errorTracker.captureException(error);
}
}, [error]);
return null;
}Performance Considerations
Lazy Loading
import { lazy, Suspense } from 'react';
const AdoptureProvider = lazy(() =>
import('@adopture/next').then(mod => ({ default: mod.AdoptureProvider }))
);
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Suspense fallback={<div>Loading...</div>}>
<AdoptureProvider>
{children}
</AdoptureProvider>
</Suspense>
</body>
</html>
);
}Conditional Loading
const shouldLoadAdopture = process.env.NODE_ENV === 'production';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{shouldLoadAdopture ? (
<AdoptureProvider>
{children}
</AdoptureProvider>
) : (
children
)}
</body>
</html>
);
}Best Practices
- Single Provider: Only use one provider per application
- Environment Variables: Use environment variables for configuration
- Error Boundaries: Always provide fallback components
- Performance: Consider lazy loading for non-critical applications
- Development: Use debug mode during development
- Testing: Disable or mock providers in tests
TypeScript Support
All provider components are fully typed:
import type {
NextAdoptureConfig,
NextAdoptureProviderProps,
BootstrapData,
NextAdoptureContext,
} from '@adopture/next';Migration Guide
From Other Analytics
If migrating from other analytics providers:
// Before (Google Analytics)
<GoogleAnalyticsProvider>
{children}
</GoogleAnalyticsProvider>
// After (Adopture)
<AdoptureProvider>
{children}
</AdoptureProvider>Gradual Migration
For gradual migration, you can run both providers:
<GoogleAnalyticsProvider>
<AdoptureProvider>
{children}
</AdoptureProvider>
</GoogleAnalyticsProvider>Then gradually replace tracking calls and remove the old provider when ready.