shelf_asset_router 1.2.0 copy "shelf_asset_router: ^1.2.0" to clipboard
shelf_asset_router: ^1.2.0 copied to clipboard

A multi-route asset handler for Shelf that serves Flutter bundled assets with flexible routing configuration, perfect for WebView integration.

example/lib/main.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_asset_router/shelf_asset_router.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Shelf Asset Router Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const WebViewExample(),
    );
  }
}

class WebViewExample extends StatefulWidget {
  const WebViewExample({super.key});

  @override
  State<WebViewExample> createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  HttpServer? _server;
  int? _serverPort;
  WebViewController? _webViewController;
  bool _isLoading = true;
  String? _errorMessage;

  @override
  void initState() {
    super.initState();
    _startServer();
  }

  Future<void> _startServer() async {
    try {
      // Create asset handler with route configuration
      final assetHandler = AssetHandler.create([
        const AssetRoute(
          basePath: 'assets/webapp',
          defaultDocument: 'index.html',
        ),
      ]);

      // Create request handler pipeline with logging middleware
      final handler = const Pipeline()
          .addMiddleware(logRequests())
          .addHandler(assetHandler);

      // Start HTTP server on localhost with random available port
      _server = await shelf_io.serve(
        handler,
        InternetAddress.loopbackIPv4,
        0, // Use 0 to let system assign available port
      );

      setState(() {
        _serverPort = _server!.port;
        _isLoading = false;
      });

      debugPrint('Server started on http://localhost:$_serverPort');

      // Initialize WebView controller
      _initializeWebView();
    } catch (e) {
      setState(() {
        _errorMessage = 'Failed to start server: $e';
        _isLoading = false;
      });
    }
  }

  void _initializeWebView() {
    _webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageStarted: (url) {
            debugPrint('Page started loading: $url');
          },
          onPageFinished: (url) {
            debugPrint('Page finished loading: $url');
          },
          onWebResourceError: (error) {
            debugPrint('Web resource error: ${error.description}');
          },
        ),
      )
      ..loadRequest(Uri.parse('http://localhost:$_serverPort/assets/webapp/'));
  }

  @override
  void dispose() {
    _server?.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Shelf Asset Router Example'),
        actions: [
          if (_serverPort != null)
            IconButton(
              icon: const Icon(Icons.refresh),
              onPressed: () {
                _webViewController?.reload();
              },
              tooltip: 'Reload',
            ),
        ],
      ),
      body: _buildBody(),
    );
  }

  Widget _buildBody() {
    if (_isLoading) {
      return const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(),
            SizedBox(height: 16),
            Text('Starting server...'),
          ],
        ),
      );
    }

    if (_errorMessage != null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Icon(Icons.error_outline, size: 64, color: Colors.red),
              const SizedBox(height: 16),
              Text('Error', style: Theme.of(context).textTheme.headlineSmall),
              const SizedBox(height: 8),
              Text(
                _errorMessage!,
                textAlign: TextAlign.center,
                style: const TextStyle(color: Colors.red),
              ),
            ],
          ),
        ),
      );
    }

    if (_webViewController == null) {
      return const Center(child: Text('Initializing WebView...'));
    }

    return Column(
      children: [
        Container(
          color: Colors.blue.shade50,
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              const Icon(Icons.info_outline, size: 16),
              const SizedBox(width: 8),
              Expanded(
                child: Text(
                  'Server running on http://localhost:$_serverPort',
                  style: const TextStyle(fontSize: 12),
                ),
              ),
            ],
          ),
        ),
        Expanded(child: WebViewWidget(controller: _webViewController!)),
      ],
    );
  }
}
0
likes
160
points
46
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A multi-route asset handler for Shelf that serves Flutter bundled assets with flexible routing configuration, perfect for WebView integration.

Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

crypto, flutter, mime, shelf

More

Packages that depend on shelf_asset_router