Low-level link (text, URLs, emails) parsing library in Dart

Last update: Dec 11, 2021

linkify pub package

Low-level link (text, URLs, emails) parsing library in Dart.

Required Dart >=2.12 (has null-safety support).

Flutter library.

Pub - API Docs - GitHub

Install

Install by adding this package to your pubspec.yaml:

dependencies:
  linkify: ^4.0.0

Usage

import 'package:linkify/linkify.dart';

linkify("Made by https://cretezy.com [email protected]");
// Output: [TextElement: 'Made by ', UrlElement: 'https://cretezy.com' (cretezy.com), TextElement: ' ', EmailElement: '[email protected]' ([email protected])]

Options

You can pass LinkifyOptions to the linkify method to change the humanization of URLs (turning https://example.com to example.com):

linkify("https://cretezy.com");
// [UrlElement: 'https://cretezy.com' (cretezy.com)]

linkify("https://cretezy.com", options: LinkifyOptions(humanize: false));
// [UrlElement: 'https://cretezy.com' (https://cretezy.com)]
  • humanize: Removes http/https from shown URLs
  • removeWww: Removes www. from shown URLs
  • looseUrl: Enables loose URL parsing (should parse most URLs such as abc.com/xyz)
    • defaultToHttps: When used with [looseUrl], default to https instead of http
  • excludeLastPeriod: Excludes . at end of URLs

Linkifiers

You can pass linkifiers to linkify as such:

linkify("@cretezy", linkifiers: [UserTagLinkifier()]);

Available linkifiers:

  • EmailLinkifier
  • UrlLinkifier
  • UserTagLinkifier

Custom Linkifier

You can write custom linkifiers for phone numbers or other types of links. Look at the URL linkifier for an example.

This is the flow:

  • Calls parse in the linkifier with a list of LinkifyElement. This starts as [TextElement(text)]
  • Your parsers then splits each element into it's parts. For example, [TextElement("Hello https://example.com")] would become [TextElement("Hello "), UrlElement("https://example.com")]
  • Each parsers is ran in order of how they are passed to the main linkify function. By default, this is URL and email linkifiers

GitHub

https://github.com/Cretezy/linkify
Comments
  • 1. added support for phone number

    I have added support for phone numbers like +91 99999 99999 +1 123 123 123 +41 (555) 555 555 9999999999 , etc Regex is: ^((?:.|\n)*?)((tel:)?([+0-9]{2,4}?\s?[0-9\s()]{8,15}))

    I have also added a way for user to provide a custom regex, in the linkify method using phoneRegex - which is an optional named parameter, so no breaking change is introduced

    Reviewed by mannprerak2 at 2019-03-30 20:14
  • 2. Text preceded by an /r/n (carriage return + linefeed) causes REGEX parser to fail

    Hello!

    Great plugin! Saved me so much time fiddling with text spans!!!!

    I ran into one problem, I'm pulling text from a database connection and the text is returned with carriage returns and linefeeds, which seems to make the REGEX parser fail. To fix it, I do a text replace of all '\r\n' to simply '\n' and Linkify works perfectly.

    Might be something to look at in a future release, but in the interim the fix is easy as in the below code:

    Linkify(
      text: widget.kennel['kennelDescription'].toString().replaceAll('\r\n', '\n'),
      style: bodyStyle,
      linkStyle: bodyStyleYellow,
      humanize: true,
      onOpen: (LinkableElement link) async {
        if (await canLaunch(link.url)) {
          await launch(link.url);
        } else {
          Utilities.showAlert(context, 'Unable to open link', 'The app was unable to open ${link.url}', 'OK');
        }
      },
    ),
    
    
    Reviewed by James-A-White at 2019-06-03 19:18
  • 3. Email RegExp should be simpler.

    Currently, the only way to know if an email address is valid is to send an email address (and potentially wait for an action, like clicking a link to validate, etc.)

    tl;dr

    Please use this RegExp:

    r'[email protected]+'
    

    (No need for mailto: too)

    Boring stuff below

    Some examples for perfectly valid email addresses:

    [email protected]
    [email protected]
    [email protected]
    #[email protected]
    [email protected]
    %[email protected]
    &[email protected]
    '[email protected]
    *[email protected]
    [email protected]
    [email protected]
    /[email protected]
    [email protected]
    [email protected]
    ^[email protected]
    [email protected]
    `[email protected]
    {[email protected]
    |[email protected]
    }[email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    [email protected]
    "very.(),:;<>[]\".VERY.\"[email protected]\\ \"very\".unusual"@strange.example.com
    [email protected]
    [email protected]
    #!$%&'*+-/=?^_`{}|[email protected]
    "()<>[]:,;@\\\"!#$%&'-/=?^_`{}| ~.a"@example.org
    [email protected]
    [email protected]
    [email protected][2001:DB8::1]
    

    These addresses above are all valid!

    If you really, really want to be kinda (covers 99.99% of the cases) compatible with some of the RFCs, you can use this RegExp (I use it in production, but lately considering to drop it):

    r'^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*\.?$'
    

    More info:

    Reviewed by komapeb at 2019-06-17 21:25
  • 4. Could not able to find the linkify without https://

    example : facebook.com www.google.com

    used loose, http://facebook.com considered url.

    if i used loose, all dots (.) consider that url. example. http://1. or something. also considered url.

    Please fix it asap.

    Reviewed by SureShDood at 2020-05-28 07:29
  • 5. Not able to detect Multiple URL.

    I am trying two display two URLs with the below code but it's detecting only the first one. This is how it's displaying in the application.

    Screenshot 2020-06-09 at 5 20 22 PM

    Linkify(
              onOpen: (link) async => {
                if (await canLaunch(link.url))
                  {
                    await launch(link.url),
                  }
                else
                  {
                    throw 'Could not launch $link',
                  }
              },
              text: message,
              style: TextStyle(
                color: color,
                fontSize: fontSize,
                fontWeight: fontWeight,
                fontFamily: Fonts.TITLE,
              ),
              options: LinkifyOptions(humanize: false),
            ),
    

    flutter_linkify: ^3.1.3

    [βœ“] Flutter (Channel stable, v1.17.0, on Mac OS X 10.14.5 18F132, locale en-IN)

    [βœ“] Android toolchain - develop for Android devices (Android SDK version 29.0.2) [βœ“] Xcode - develop for iOS and macOS (Xcode 11.3.1) [βœ“] Android Studio (version 3.6) [βœ“] VS Code (version 1.45.1) [βœ“] Connected device (1 available)

    Reviewed by iavsm at 2020-06-09 11:45
  • 6. [Url Linkifier] Expand to cover www. urls

    This commit expands the UrlLinkifier to pick up http://, https://, and www. urls. If the url it picks up doesn't start with http:// or https://, then it will prepend http:// (or https:// depending on linkify options) to make it launchable from urlLauncher.

    Reviewed by SpencerLindemuth at 2020-06-17 17:12
  • 7. Fix loose URL not being parsed if the text have a non loose URL

    This PR fixes #40 where a text with both loose and not loose URLs was not being properly parsed.

    I've added 2 tests that reproduce the issue and then fixed it.

    The main issue is that even if the looseUrl option is set to true, the first match is using the full _urlRegex, so if the text contains both a loose and a not loose URL the first part of the text is parsed as TextElement even it has a loose URL.

    Reviewed by EsteveAguilera at 2021-05-27 12:04
  • 8. Could not able to identify the valid url

    I have tried to without https://, Could not able to get the valid url.

    Example. I try to give www.facebook.com , facebook.com it's not recognised the valid url. i given the looseUrl option true. All dots (.) considered the url format.

    Reviewed by SureShDood at 2020-05-28 07:21
  • 9. looseUrl highlighting words at end of sentence with punctuation

    SelectableLinkify( onOpen: onOpen, text: "github.com test.", style: TextStyle(color: Colors.black), linkStyle: TextStyle( color: Colors.blue ), options: LinkifyOptions( looseUrl: true ), ), The above code results in the following text to be highlighted: Screen Shot 2020-07-16 at 18 52 04

    The looseUrl option has done a good job of identifying most loose urls but its also highlighting anything with a period at the end. Is it possible to modify the _looseUrlRegex to require there be at least one non-whitespace character?

    Reviewed by edgarhernandezch at 2020-07-17 01:55
  • 10. Considers words at the end of a sentence as a valid url when looseUrl = true.

    Hey!

    Really thanks for making this package and it has proven to be quite useful for us. There's one issue however that I found. If looseUrl is set to true then words at the end of sentences are also considered as valid links. It disregards the space after the period. I'm not sure if this is the right package for this issue but I'm still going to add it here.

    Here's a live example. Screenshot 2020-06-08 at 2 37 39 PM

    And here's a code snippet.

    Linkify(
                text: text,
                maxLines: maxLines,
                overflow: TextOverflow.clip,
                textAlign: TextAlign.start,
                options: LinkifyOptions(
                  looseUrl: true,
                ),
                onOpen: (link) async {
                  if (await canLaunch(link.url)) {
                    await launch(link.url);
                  }
                },
    )
    

    I'm using package version flutter_linkify: 3.1.2 and flutter version 1.12.13+hotfix.8.

    Looking forward to hearing from you! Thanks again for this package. Cheers.

    Reviewed by MustansirZia at 2020-06-08 09:08
  • 11. Linkify highlights also "." at the end of a link.

    A "." at the end of a link should not highlighted. Like: www.google.de.

    Code:

    Linkify(
        style: _greyTextStyle(context),
        linkStyle: linkStyle(context),
        text: "Besuche fΓΌr weitere Informationen einfach https://www.sharezone.info.",
    )
    

    Result: image

    Reviewed by nilsreichardt at 2020-01-30 00:09
  • 12. Quotation mark characters are not detected in links

    For example, in the link (example.com/over/there?name="ferret") it is highlighted until the quotation mark. Edit: Only applicable for loose URL.

    Reviewed by atillaturkmen at 2022-02-07 21:35
  • 13. Support UserTagLinkifier on Safari

    The regex used on UserTagLinkifier contains a negative lookbehind, which is unsupported on Safari.

    In order to being able to use the linkifier on Safari, I removed the lookbehind from the regex and refactored the code to do the same thing that the original regex.

    I also fixed some user tag tests that were failing.

    Reviewed by jdosornio at 2021-12-16 06:36
  • 14. ✨ Add Origin Text

    Current State

    Currently there is not a way to capture the original text that contributed to a LinkifyElement. Instead, only the modified text is available.

    Desired State

    A LinkifyElement has the property originText where the original text is captured.

    Why

    An example of this is when parsing text containing a URL i.e.

    ssuper.co is one way to specify a website, https://ssuper.co is another way
    

    If using humanize=False, we get this when we recreate the phrase from the parsed elements

    https://ssuper.co is one way to specify a website, https://ssuper.co is another way
    

    Or, if using humanize=True, we get this

    ssuper.co is one way to specify a website, ssuper.co is another way
    

    This is an issue when using Linkify to parse text for a TextEditingController. Because the original text is not recoverable from LinkifyElement, there is no way to reliably mirror the original text the user types. Having an originText property fixes this.

    Current Workaround: https://stackoverflow.com/a/65914757

    Reviewed by ghunkins at 2021-12-09 16:15
  • 15. The loose url regex does not support domains with more than 4 letter

    The part of the loose url regex recognizing the domain is [a-z]{2,4} (https://github.com/Cretezy/linkify/blob/master/lib/src/url.dart#L10) while nowadays there are many domains name with more than 4 letters like .design, .travel, .cloud, etc.

    Reviewed by gianmarcocalbi at 2021-09-21 21:29

Related

Package provides light widgets [for Linkify, Clean] and extensions for strings that contain bad words/URLs/links/emails/phone numbers
Package provides light widgets [for Linkify, Clean] and extensions for strings that contain bad words/URLs/links/emails/phone numbers

Package provides light widgets [for Linkify, Clean] and extensions for strings that contain bad words/URLs/links/emails/phone numbers

Jun 6, 2022
Link-extractor - A Simple utility for extracting media urls from different websites

Link Extractor A Simple utility for extracting media urls from differennt social

Feb 5, 2022
Easy to use text widget for Flutter apps, which converts inlined urls into working, clickable links
Easy to use text widget for Flutter apps, which converts inlined urls into working, clickable links

LinkText Easy to use text widget for Flutter apps, which converts inlined URLs into clickable links. Allows custom styling. Usage LinkText widget does

Jun 4, 2022
Receive sharing photos, videos, text, URLs, or any other file types from another app.
Receive sharing photos, videos, text, URLs, or any other file types from another app.

Receive Sharing Files To Flutter App Through Other Apps Receive sharing photos, videos, text, URLs, or any other file types from another app. Visit :

May 9, 2022
Dart library for parsing relative date and time.

Dateparser Dart library for parsing relative date and time. Examples just now a moment ago tomorrow today yesterday 10 days remaining 2 hours ago 2 mo

Jun 22, 2022
Allows send emails from flutter using native platform functionality.

flutter_email_sender Allows send emails from flutter using native platform functionality. In android it opens default mail app via intent. In iOS MFMa

Jun 23, 2022
A library for parsing and encoding IEEE-754 binary floating point numbers.

Dart IEEE754 library This library provides decoding and transforming IEEE754 floating point numbers in binary format, double format, or as exponent an

Dec 24, 2021
Masked text field - A flutter package for masked text field for formet your text and good UI
Masked text field - A flutter package for masked text field for formet your text and good UI

Masked Text Field Masked Text Field Features A package for masked text field for

May 27, 2022
Write iOS&Android Code using Dart. This package liberates you from redundant glue code and low performance of Flutter Channel.
Write iOS&Android Code using Dart. This package liberates you from redundant glue code and low performance of Flutter Channel.

Dart_Native Dart_Native operates as both a code generator tool and a bridge to communicate between Dart and native APIs. Replaces the low-performing F

Jun 28, 2022
Simple Flutter text highlighting at the character-level.
Simple Flutter text highlighting at the character-level.

substring_highlight Highlight Flutter text at the character-level. Designed for case-insensitive search-term highlighting, a single search term sub-st

Mar 17, 2022
A routing package that lets you navigate through guarded page stacks and URLs using the Router and Navigator's Pages API, aka "Navigator 2.0".
A routing package that lets you navigate through guarded page stacks and URLs using the Router and Navigator's Pages API, aka

A Flutter package to help you handle your application routing and synchronize it with browser URL. Beamer uses the power of Router and implements all

Jun 24, 2022
A Video and Audio player that can play from local assets, local files and network URLs with the powerful controls
A Video and Audio player that can play from local assets, local files and network URLs with the powerful controls

Video/Audio Player in Flutter with Powerful controls How can we play videos in Flutter? There is a library directly from the Flutter team simply calle

Jan 31, 2022
Flutter blue plus - Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android and iOS
Flutter blue plus - Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android and iOS

Introduction FlutterBluePlus is a bluetooth plugin for Flutter, a new app SDK to

Jun 20, 2022
Feb 10, 2022
A class for parsing strings using a sequence of patterns.

This package exposes a StringScanner type that makes it easy to parse a string using a series of Patterns. For example: import 'dart:math' as math; i

Apr 29, 2022
Fluter-json - App Demonstrating JSON Data Parsing with various flutter widgets
Fluter-json - App Demonstrating JSON Data Parsing with various flutter widgets

users_list Flutter App to Demonstrate JSON Parsing Getting Started This project is a starting point for a Flutter application. A few resources to get

Jul 10, 2021
Flutter RSS feed parsing - A demo application of flutter which parse RSS XML contents to the flutter application
Flutter RSS feed parsing - A demo application of flutter which parse RSS XML contents to the flutter application

Flutter RSS feed parsing demo This is demo application of flutter which shows ho

Jun 4, 2022
Binding and high-level wrapper on top of libssh - The SSH library!

Dart Binding to libssh version 0.9.6 binding and high-level wrapper on top of libssh - The SSH library! libssh is a multiplatform C library implementi

Dec 20, 2021
Complete example to download reels from instagram link and save to gellery
Complete example to download reels from instagram link and save to gellery

Flutter-Reels-downloader-for-instagram A Flutter project to download reels from instagram via link. Features: Download instagram reels Play reels Save

Jun 11, 2022