http_inspect_view

A debug-only HTTP inspector for Flutter apps. Intercepts every Dio request/response, shows OS notifications per request, and lets you shake the device to open a full log viewer โ€” with no widget wrapper required.

Active only in debug and profile builds. Completely silent in release.


Features

  • ๐Ÿ”Œ Zero-widget setup โ€” just add the Dio interceptor
  • ๐Ÿ“‹ Full log viewer โ€” method, status, headers, request & response body, duration
  • ๐Ÿ”” OS notifications per request (tap to open the inspector)
  • ๐Ÿ“ณ Shake-to-open the log viewer at any time
  • ๐Ÿงท Draggable FAB โ€” optional always-on button to open the inspector manually
  • ๐ŸชŸ Screen or bottom sheet โ€” choose how the inspector is presented when opened
  • ๐Ÿ”— Share logs as cURL, plain text, or JSON
  • ๐Ÿ” Search & filter by URL or HTTP method
  • ๐Ÿ”Ž In-tab search โ€” search, highlight, and jump through matches in headers and body
  • โš—๏ธ Try Request โ€” edit any logged request and re-send it directly from the inspector

Platform setup

iOS

1 โ€” AppDelegate.swift

import Flutter
import UIKit
import flutter_local_notifications

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    // Required for flutter_local_notifications background isolate
    FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { registry in
      GeneratedPluginRegistrant.register(with: registry)
    }
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

2 โ€” Info.plist

Add the motion permission for shake-to-open:

<key>NSMotionUsageDescription</key>
<string>This app uses motion sensors to open the HTTP inspector by shaking the device.</string>

Android

AndroidManifest.xml

Add the notification permission for Android 13+ (API 33+):

<!-- Required for local notifications on Android 13+ -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

Usage

1 โ€” Add the Dio interceptor

import 'package:http_inspect_view/http_inspect_view.dart';

dio.interceptors.add(
  HttpInspectorInterceptor(
    // Pass a getter โ€” evaluated at tap/shake time, not at DI setup time.
    // This avoids a stale reference if NavigationService.navigatorKey is
    // reassigned to AppRouterConfig.navigatorKey after runApp().
    navigatorKey: () => NavigationService.navigatorKey,
  ),
);

Disable notifications but keep shake-to-open:

dio.interceptors.add(
  HttpInspectorInterceptor(
    navigatorKey: () => NavigationService.navigatorKey,
    showNotification: false,
  ),
);

Open the inspector as a bottom sheet instead of a fullscreen route โ€” useful when this is added to a Flutter module embedded in a native app, where a fullscreen route pushed on the module's own navigator may not surface over the host app's native screens:

dio.interceptors.add(
  HttpInspectorInterceptor(
    navigatorKey: () => NavigationService.navigatorKey,
    presentation: HttpInspectorPresentation.bottomSheet,
  ),
);

Enable a draggable FAB โ€” a small button overlaid on top of the app that opens the inspector on tap (drag it anywhere on screen). This is the most reliable way to open the inspector in a Flutter module embedded in a native app, where notification taps may not reach the module's navigator:

dio.interceptors.add(
  HttpInspectorInterceptor(
    navigatorKey: () => NavigationService.navigatorKey,
    presentation: HttpInspectorPresentation.bottomSheet,
    showFab: true,
  ),
);

2 โ€” Optional: HttpInspector widget

Wrap your root widget if you need explicit hot-reload safety or lifecycle control. Not required for normal use โ€” the interceptor starts everything automatically, including presentation and showFab.

HttpInspector(
  navigatorKey: () => NavigationService.navigatorKey,
  presentation: HttpInspectorPresentation.bottomSheet,
  showFab: true,
  child: MyApp(),
)

How it works

Trigger Behaviour
Every request completes OS notification appears (tap to open inspector)
Shake the device Inspector list opens (fullscreen dialog, or bottom sheet if presentation: bottomSheet)
Tap the draggable FAB (showFab: true) Same as shake โ€” opens per the configured presentation
Tap any log entry Full detail view: Overview ยท Request ยท Response tabs
๐Ÿ” icon in detail page Animated search bar slides in โ€” highlights & navigates matches in headers and body
โš—๏ธ icon in detail page Opens Try Request: edit method, URL, headers, body and send โ€” result shown inline and logged to the list
Share button cURL command ยท full text ยท JSON export

Try Request

The Try Request screen lets you replay and modify any captured request without leaving the app:

  • Pre-filled from the tapped log entry (method, full URL, all headers, body)
  • Change any field โ€” switch method via the colored badge dropdown, edit headers row-by-row (add / remove), rewrite the body in a dark code editor
  • Tap Send โ€” the request fires immediately and:
    • The response appears inline (status badge, duration, pretty-printed JSON body or error)
    • The request is added to the inspector list as a normal entry โ€” tap it to view full details, share, or try again

Additional information

  • All data is stored in memory only โ€” cleared when the app restarts.
  • To clear logs at runtime, tap the ๐Ÿ—‘ button in the inspector list.
  • The inspector is a no-op in release builds โ€” no tree-shaking required.