···
+
import 'package:flutter/foundation.dart';
+
import 'package:flutter/material.dart';
+
import 'package:url_launcher/url_launcher.dart';
+
/// Utility class for safely launching external URLs
+
/// Provides security validation and error handling for opening URLs
+
/// in external browsers or applications.
+
UrlLauncher._(); // Private constructor to prevent instantiation
+
/// Allowed URL schemes for security
+
static const _allowedSchemes = ['http', 'https'];
+
/// Launches an external URL with security validation
+
/// Returns true if the URL was successfully launched, false otherwise.
+
/// - Only allows http and https schemes
+
/// - Blocks potentially malicious schemes (javascript:, file:, etc.)
+
/// - Opens in external browser for user control
+
/// If [context] is provided and mounted, shows a user-friendly error message
+
/// when the URL cannot be opened.
+
static Future<bool> launchExternalUrl(
+
final uri = Uri.parse(url);
+
// Validate URL scheme for security
+
if (!_allowedSchemes.contains(uri.scheme.toLowerCase())) {
+
debugPrint('Blocked non-http(s) URL scheme: ${uri.scheme}');
+
_showErrorIfPossible(context, 'Invalid link format');
+
// Check if URL can be launched
+
if (await canLaunchUrl(uri)) {
+
return await launchUrl(uri, mode: LaunchMode.externalApplication);
+
debugPrint('Could not launch URL: $url');
+
// ignore: use_build_context_synchronously
+
_showErrorIfPossible(context, 'Could not open link');
+
} on FormatException catch (e) {
+
debugPrint('Invalid URL format: $url - $e');
+
// ignore: use_build_context_synchronously
+
_showErrorIfPossible(context, 'Invalid link format');
+
} on Exception catch (e) {
+
debugPrint('Error launching URL: $url - $e');
+
// ignore: use_build_context_synchronously
+
_showErrorIfPossible(context, 'Could not open link');
+
/// Shows an error snackbar if context is available and mounted
+
static void _showErrorIfPossible(BuildContext? context, String message) {
+
if (context != null && context.mounted) {
+
).showSnackBar(SnackBar(content: Text(message)));