How do I use <a> anchor elements in Flutter web?

335

Solution

The url_launcher package actually has a built-in solution for this that not many are aware of: the link library. This library provides a Link widget that fixes all of the mentioned problems:

  • Shows link preview on hover (by inserting an <a> element on web).
  • Works on all browsers (not blocked as a popup, never).
  • Opens as fast as on regular HTML pages.
  • Also works on mobile by default.

Usage

The Link widget can be used like this:

return MouseRegion(
  cursor: SystemMouseCursors.click,
  child: Link(
    uri: Uri.parse('https://creativemaybeno.dev'),
    target: LinkTarget.blank,
    builder: (context, followLink) {
      return GestureDetector(
        onTap: followLink,
        child: const Text(
          'my amazing link',
          style: TextStyle(
            decoration: TextDecoration.underline,
            // The default link color according to the HTML living standard.
            // See https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3,
            // which defines :link { color: #0000EE; }.
            color: Color(0xff0000ee),
          ),
        ),
      );
    },
  ),
);

As you can see, you simply need to specify the uri that should be opened on tap as well as the target which defines how the link is opened. Read through the docs to learn more.

Now, the Link widget provides you with a builder that passes a followLink callback. You simply call this upon your desired on tap action (pass it to a GestureDetector for example).
You do not have to use a Text widget as a child - you can actually use anything, e.g. a button.

Just note that the <a> anchor preview will be shown on hover of the whole area taken up by the child widget. So try to not make the button / child very large :)

Share:
335
creativecreatorormaybenot
Author by

creativecreatorormaybenot

Updated on December 31, 2022

Comments

  • creativecreatorormaybenot
    creativecreatorormaybenot 10 months

    Current setup (using launch)

    I want to use links in my Flutter web app and currently do it like this (using the url_launcher package):

    return MouseRegion(
      cursor: SystemMouseCursors.click,
      child: GestureDetector(
        onTap: () {
          launch('https://creativemaybeno.dev');
        },
        child: const Text(
          'my amazing link',
          style: TextStyle(
            decoration: TextDecoration.underline,
          ),
        ),
      ),
    );
    

    What works using launch

    There are three things that this code snippet does right:

    • Fully works on mobile
    • Shows click cursor on hover on web
    • Opens the link on web in most cases

    What does not work using launch

    However, there are a number of issues I have with this on web compared to using an <a> anchor element in regular HTML:

    • Link preview is not shown in the bottom-left corner of the browser.
      This is what it looks like on regular HTML pages:

    screenshot

    • Links seem to be opening more slowly than the ones in regular web apps

    • Safari blocks my links completely ("blocked a pop-up")

    Especially the links not working on Safari as well as the link preview not showing I really need to get resolved in order to have a smooth web experience. How do I achieve that?