An Expo module wrapper for the Instalog analytics and logging SDK, making it easy to integrate Instalog into your Expo applications.
npm install @instalog.dev/expo
This package auto-installs necessary native dependencies for Expo projects.
For Android, make sure to add the Instalog Feedback Activity to your AndroidManifest.xml:
<activity
android:name="dev.instalog.mobile.feedback.InstalogFeedbackActivity"
android:label="Instalog"
android:theme="@style/Theme.Instalog" />
This should be placed inside the <application>
tags of your manifest file.
Initialize the Instalog SDK at the beginning of your app:
import { Instalog } from '@instalog.dev/expo';
// Initialize with default settings
await Instalog.initialize('YOUR_API_KEY');
// Or with custom options
await Instalog.initialize('YOUR_API_KEY', {
isLogEnabled: true,
isCrashEnabled: true,
isFeedbackEnabled: true,
isLoggerEnabled: false, // Debug logging
autoCaptureCrashes: true, // Automatically capture unhandled JS errors
errorGrouping: {
enabled: true,
flushIntervalMs: 30000, // 30 seconds
errorThreshold: 5,
timeWindowMs: 60000, // 1 minute
flushOnBackground: true,
requireNetwork: true,
maxErrorsPerGroup: 10,
dynamicFlushInterval: true,
}
});
// Identify your user after initialization
await Instalog.identifyUser("user123");
Identify your users to track their activity across sessions:
await Instalog.identifyUser('user123');
Track user actions and events in your app:
await Instalog.logEvent('button_clicked', {
button_name: 'submit',
screen: 'login',
});
Show a feedback modal to collect user feedback:
await Instalog.showFeedbackModal();
Crash reporting is automatically enabled after initialization. The SDK can automatically capture unhandled JavaScript errors when autoCaptureCrashes
is enabled (default).
You can also manually report crashes:
try {
// Your code that might throw an exception
} catch (error) {
await Instalog.sendCrash('Error name', error.stack || error.toString());
}
For more structured error reporting, you can use the formatErrorReport
helper:
try {
// Your code that might throw an exception
} catch (error) {
const formattedError = Instalog.formatErrorReport(error, errorInfo);
await Instalog.sendCrash('Caught Error', formattedError);
}
For testing, you can simulate a crash:
await Instalog.simulateCrash();
The SDK automatically sets up global error handling when initialized with autoCaptureCrashes: true
(default). This captures unhandled JavaScript errors and reports them to Instalog.
You can test this functionality with:
// This will trigger the global error handler
setTimeout(() => {
throw new Error("Test Global Error");
}, 0);
Initializes the SDK with your API key and optional configuration.
Options:
Option | Type | Default | Description |
---|---|---|---|
isLogEnabled | boolean | false | Enable event logging |
isLoggerEnabled | boolean | false | Enable debug logging |
isCrashEnabled | boolean | false | Enable crash reporting |
isFeedbackEnabled | boolean | false | Enable feedback collection |
autoCaptureCrashes | boolean | true | Automatically capture unhandled JS errors |
errorGrouping | object | (see below) | Configure how errors are grouped and reported |
Error Grouping Options:
Option | Type | Default | Description |
---|---|---|---|
enabled | boolean | true | Enable error grouping |
flushIntervalMs | number | 30000 | Interval to flush error groups (ms) |
errorThreshold | number | 5 | Number of errors to trigger flush |
timeWindowMs | number | 60000 | Time window for grouping errors (ms) |
flushOnBackground | boolean | true | Flush errors when app goes to background |
requireNetwork | boolean | true | Only flush when network is available |
maxErrorsPerGroup | number | 10 | Max errors to store per group |
dynamicFlushInterval | boolean | true | Adjust flush interval based on error volume |
Identifies the current user.
Logs an event with optional parameters.
Shows the feedback collection modal.
Manually sends a crash report.
Formats an error into a structured report for sending.
Simulates a crash for testing.
import { Instalog } from "@instalog.dev/expo";
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, View, TouchableOpacity, SafeAreaView } from "react-native";
export default function App() {
const apiKey = "YOUR_API_KEY";
useEffect(() => {
const initialize = async () => {
await Instalog.initialize(apiKey, {
isLogEnabled: true,
isCrashEnabled: true,
isFeedbackEnabled: true,
isLoggerEnabled: true,
});
await Instalog.identifyUser("expo_test_user");
};
initialize();
}, []);
const handleSendEvent = async () => {
await Instalog.logEvent("button_clicked", {
timestamp: new Date().toISOString(),
screen: "demo_screen",
});
};
const handleShowFeedback = async () => {
await Instalog.showFeedbackModal();
};
const handleSimulateCrash = async () => {
await Instalog.simulateCrash();
};
const handleTestGlobalError = () => {
setTimeout(() => {
throw new Error("Test Global Error");
}, 0);
};
const handleManualErrorReport = async () => {
await Instalog.sendCrash(
"Manual Test Error",
"This is a stack trace for a manually reported error\nLine 1\nLine 2\nLine 3"
);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={handleSendEvent}
>
<Text style={styles.buttonText}>Send Event</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={handleShowFeedback}
>
<Text style={styles.buttonText}>Show Feedback</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={handleSimulateCrash}
>
<Text style={styles.buttonText}>Simulate Crash</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={handleTestGlobalError}
>
<Text style={styles.buttonText}>Test Global Error</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={handleManualErrorReport}
>
<Text style={styles.buttonText}>Manual Error Report</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#fff",
},
buttonContainer: {
alignItems: "center",
},
button: {
backgroundColor: "#8860E6",
padding: 15,
borderRadius: 8,
marginVertical: 10,
width: 200,
alignItems: "center",
},
buttonText: {
color: "#fff",
fontWeight: "bold",
},
});
MIT