uxlens_sdk 0.1.3
uxlens_sdk: ^0.1.3 copied to clipboard
UxLens session replay & analytics SDK for Flutter apps.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:uxlens_sdk/uxlens_sdk.dart';
import 'screens/home_screen.dart';
import 'screens/login_screen.dart';
import 'screens/session_inspector_screen.dart';
import 'screens/webview_screen.dart';
// Backend wiring (UXLENS_ENDPOINT/UXLENS_API_KEY) comes from assets/.env —
// bundled into the app at build time like any other asset (see
// assets/.env.example and pubspec.yaml), so no keys live in source and a
// plain `flutter run` (or the IDE's Run button) just works with no special
// flags. Missing/unset values fall back to Phase 1 local-only mode.
Future<Map<String, String>> _loadEnvAsset() async {
final env = <String, String>{};
try {
final raw = await rootBundle.loadString('assets/.env');
for (final rawLine in raw.split('\n')) {
final line = rawLine.trim();
if (line.isEmpty || line.startsWith('#')) continue;
final i = line.indexOf('=');
if (i == -1) continue;
env[line.substring(0, i).trim()] = line.substring(i + 1).trim();
}
} catch (_) {
// No assets/.env bundled — fine, just runs in local-only mode.
}
return env;
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final env = await _loadEnvAsset();
final apiKey = env['UXLENS_API_KEY'];
// Single init call, before runApp: this is the entire SDK setup an
// integrating app needs to do.
UxLens.start(
config: UxLensConfig(
frameRate: 3,
apiKey: (apiKey == null || apiKey.isEmpty) ? null : apiKey,
// Keep the on-device session inspector working while uploading.
alsoWriteLocal: true,
// Custom regex masking rule: anything card-number-shaped in a
// widget's semantics gets blacked out, no matter how it's labeled.
// The home screen's "Ref: 4111 ..." row demos this.
sensitiveLabelPatterns: const [
r'\b\d{4}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b',
],
// Record every session in this demo. Drop below 1.0 in production to
// trade replay coverage for storage cost — sampled-out sessions cost
// nothing on-device and never upload.
sampleRate: 1.0,
),
);
runApp(const UxLensExampleApp());
}
/// Demonstrates the entire Phase 1 integration surface: wrap the app in
/// [UxLensRecorder], register [UxLens.instance]'s navigator observer, and
/// everything else (frame capture, touch capture, masking, buffering) runs
/// automatically.
class UxLensExampleApp extends StatelessWidget {
const UxLensExampleApp({super.key});
@override
Widget build(BuildContext context) {
return UxLensRecorder(
child: MaterialApp(
title: 'UxLens SDK Example',
debugShowCheckedModeBanner: false,
navigatorObservers: [UxLens.instance!.navigatorObserver],
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF5B5FEF),
brightness: Brightness.light,
),
),
initialRoute: '/login',
routes: {
'/login': (_) => const LoginScreen(),
'/home': (_) => const HomeScreen(),
'/inspector': (_) => const SessionInspectorScreen(),
'/webview': (_) => const WebViewScreen(),
},
),
);
}
}