[url_launcher] Fixed missing # in links href when opening in new tab on the web (#4221)

diff --git a/AUTHORS b/AUTHORS
index 0ca697b..f5dc823 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -65,3 +65,4 @@
 Alex Li <google@alexv525.com>
 Rahul Raj <64.rahulraj@gmail.com>
 Daniel Roek <daniel.roek@gmail.com>
+TheOneWithTheBraid <the-one@with-the-braid.cf>
diff --git a/packages/url_launcher/url_launcher_web/AUTHORS b/packages/url_launcher/url_launcher_web/AUTHORS
index 493a0b4..2678aab 100644
--- a/packages/url_launcher/url_launcher_web/AUTHORS
+++ b/packages/url_launcher/url_launcher_web/AUTHORS
@@ -64,3 +64,4 @@
 Anton Borries <mail@antonborri.es>
 Alex Li <google@alexv525.com>
 Rahul Raj <64.rahulraj@gmail.com>
+TheOneWithTheBraid <the-one@with-the-braid.cf>
\ No newline at end of file
diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md
index 7ac1402..a434b7a 100644
--- a/packages/url_launcher/url_launcher_web/CHANGELOG.md
+++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.0.9
+
+- Fixes invalid routes when opening a `Link` in a new tab
+
 ## 2.0.8
 
 * Updates the minimum Flutter version to 2.10, which is required by the change
@@ -17,7 +21,7 @@
 
 ## 2.0.4
 
-* Add `implements` to pubspec.
+- Add `implements` to pubspec.
 
 ## 2.0.3
 
diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart
index 3e2a025..3b75e05 100644
--- a/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart
+++ b/packages/url_launcher/url_launcher_web/example/integration_test/link_widget_test.dart
@@ -7,6 +7,7 @@
 
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter_web_plugins/flutter_web_plugins.dart';
 import 'package:integration_test/integration_test.dart';
 import 'package:url_launcher_platform_interface/link.dart';
 import 'package:url_launcher_web/src/link.dart';
@@ -51,6 +52,25 @@
       // Check that the same anchor has been updated.
       expect(anchor.getAttribute('href'), uri2.toString());
       expect(anchor.getAttribute('target'), '_self');
+
+      final Uri uri3 = Uri.parse('/foobar');
+      await tester.pumpWidget(Directionality(
+        textDirection: TextDirection.ltr,
+        child: WebLinkDelegate(TestLinkInfo(
+          uri: uri3,
+          target: LinkTarget.self,
+          builder: (BuildContext context, FollowLink? followLink) {
+            return Container(width: 100, height: 100);
+          },
+        )),
+      ));
+      await tester.pumpAndSettle();
+
+      // Check that internal route properly prepares using the default
+      // [UrlStrategy]
+      expect(anchor.getAttribute('href'),
+          urlStrategy?.prepareExternalUrl(uri3.toString()));
+      expect(anchor.getAttribute('target'), '_self');
     });
 
     testWidgets('sizes itself correctly', (WidgetTester tester) async {
diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart
index 24d694f..36903b0 100644
--- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart
+++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart
@@ -1,4 +1,4 @@
-// Mocks generated by Mockito 5.0.16 from annotations
+// Mocks generated by Mockito 5.0.17 from annotations
 // in regular_integration_tests/integration_test/url_launcher_web_test.dart.
 // Do not manually edit this file.
 
@@ -643,8 +643,6 @@
   bool dispatchEvent(_i2.Event? event) =>
       (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]),
           returnValue: false) as bool);
-  @override
-  String toString() => super.toString();
 }
 
 /// A class which mocks [Navigator].
@@ -749,6 +747,4 @@
   _i3.Future<dynamic> share([Map<dynamic, dynamic>? data]) =>
       (super.noSuchMethod(Invocation.method(#share, [data]),
           returnValue: Future<dynamic>.value()) as _i3.Future<dynamic>);
-  @override
-  String toString() => super.toString();
 }
diff --git a/packages/url_launcher/url_launcher_web/lib/src/link.dart b/packages/url_launcher/url_launcher_web/lib/src/link.dart
index d3fa4a8..4498e74 100644
--- a/packages/url_launcher/url_launcher_web/lib/src/link.dart
+++ b/packages/url_launcher/url_launcher_web/lib/src/link.dart
@@ -11,7 +11,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/rendering.dart';
 import 'package:flutter/services.dart';
-
+import 'package:flutter_web_plugins/flutter_web_plugins.dart' show urlStrategy;
 import 'package:url_launcher_platform_interface/link.dart';
 
 /// The unique identifier for the view type to be used for link platform views.
@@ -163,6 +163,7 @@
   final BuildContext context;
 
   late html.Element _element;
+
   bool get _isInitialized => _element != null;
 
   Future<void> _initialize() async {
@@ -221,7 +222,13 @@
     if (uri == null) {
       _element.removeAttribute('href');
     } else {
-      _element.setAttribute('href', uri.toString());
+      String href = uri.toString();
+      // in case an internal uri is given, the url mus be properly encoded
+      // using the currently used [UrlStrategy]
+      if (!uri.hasScheme) {
+        href = urlStrategy?.prepareExternalUrl(href) ?? href;
+      }
+      _element.setAttribute('href', href);
     }
   }
 
diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml
index 8860eeb..c45c062 100644
--- a/packages/url_launcher/url_launcher_web/pubspec.yaml
+++ b/packages/url_launcher/url_launcher_web/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Web platform implementation of url_launcher
 repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher_web
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
-version: 2.0.8
+version: 2.0.9
 
 environment:
   sdk: ">=2.12.0 <3.0.0"