Last active
October 31, 2025 13:38
-
-
Save icecandy/94e0e1ca7c6673bb35af888108a93b84 to your computer and use it in GitHub Desktop.
For Medium article: "How to get standard web behaviour from RichText links in Flutter web"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //lib/main.dart | |
| import 'package:flutter/material.dart'; | |
| import 'package:flutter/gestures.dart'; | |
| import 'package:url_launcher/url_launcher.dart'; | |
| import 'package:url_launcher/link.dart'; | |
| const String URL_EXAMPLE = 'https://www.flutter.dev'; | |
| final RichText richTextExample = RichText( | |
| text: TextSpan( | |
| style: TextStyle(fontSize: 16, height: 1.6, color: Colors.black87), | |
| children: [ | |
| TextSpan( | |
| text: 'Welcome to our sample text widget. For instance, you can add a ', | |
| ), | |
| TextSpan( | |
| text: 'hyperlink ', | |
| style: TextStyle(color: Colors.deepOrange, fontSize: 18, fontWeight: FontWeight.bold), | |
| recognizer: TapGestureRecognizer() | |
| ..onTap = () async { | |
| Uri uri = Uri.parse(URL_EXAMPLE); | |
| if (await canLaunchUrl(uri)) { | |
| await launchUrl(uri); | |
| } | |
| }, | |
| ), | |
| TextSpan( | |
| text: ' using a TextSpan or a ', | |
| ), | |
| WidgetSpan( | |
| alignment: PlaceholderAlignment.baseline, | |
| baseline: TextBaseline.alphabetic, | |
| child: Link( | |
| uri: Uri.parse(URL_EXAMPLE), | |
| target: LinkTarget.blank, | |
| builder: (BuildContext context, Future<void> Function()? followLink) { | |
| return GestureDetector( | |
| child: MouseRegion( | |
| cursor: SystemMouseCursors.click, | |
| child: Text( | |
| 'hyperlink', | |
| style: TextStyle(color: Colors.deepPurple, fontSize: 18, fontWeight: FontWeight.bold), | |
| ), | |
| ), | |
| onTap: () async { | |
| if (followLink != null) await followLink(); | |
| }, | |
| ); | |
| }, | |
| ), | |
| ), | |
| TextSpan( | |
| text: ' using a WidgetSpan.', | |
| ), | |
| ], | |
| ), | |
| ); | |
| void main() { | |
| runApp(const MainApp()); | |
| } | |
| class MainApp extends StatelessWidget { | |
| const MainApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| home: Scaffold( | |
| appBar: AppBar(title: const Text('Web Links Example')), | |
| body: SingleChildScrollView( | |
| child: Align( | |
| alignment: AlignmentDirectional.topCenter, | |
| child: Padding( | |
| padding: const EdgeInsets.symmetric(vertical: 100, horizontal: 15), | |
| child: SizedBox(width: 400, child: richTextExample), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment