Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Text] Best practice to linkify text? #3148

Closed
ranyefet opened this issue Sep 30, 2015 · 9 comments
Closed

[Text] Best practice to linkify text? #3148

ranyefet opened this issue Sep 30, 2015 · 9 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@ranyefet
Copy link

Hi all,

In my app I have text that returned from the server that contains URLs, i.e:

Some text some text some text http://google.com more text...

I want to replace the URLs in the text with custom component that will open the links in embedded web view.

The problem is that I can't just replace http://google.com with <Link to="http://google.com" /> because its just replacing strings. If I understand correctly I need to transform the text into array like:

["Some text some text some text ", <Link to="http://google.com" />, " more text..."]

I found a similar issue #614 but it looks kinda messy.
Is there a recommended way to do it?

Thanks!

@brentvatne
Copy link
Collaborator

I use this in one app:

'use strict';

import React from 'react-native';
import { Text } from 'react-native';
import Link from 'Link';
import _ from 'lodash-node';
import Colors from 'Colors';

/**
 * Adds links to text with without HTML tags
 * 'This will turn into a link: http://www.facebook.com'
 * Use HTMLView for actual HTML.
 */
export default class HyperText extends React.Component {

  render() {
    var contents;

    if (_.isString(this.props.children)) {
      let tokens = this.props.children.split(/\s/);

      contents = _.map(tokens, (token, i) => {
        let hasSpace = i !== (tokens.length - 1);
        let maybeSpace = hasSpace ? ' ' : '';

        if (token.match(/^http\:\//)) {
          return (
            <Link
              key={i}
              to={{uri: token}}
              style={{color: Colors.tint}}>
              {token}{maybeSpace}
            </Link>
          );
        } else {
          return token + maybeSpace;
        }
      });
    } else {
      console.warn('Attempted to use <HyperText> with nested components. ' +
                   'This component only supports plain text children.');
      return <Text {...this.props} />;
    }

    return (
      <Text {...this.props}>
        {contents}
      </Text>
    );
  }

}

Link is just a component that returns a Text node with an onPress handler that delegates to LinkingIOS to open the url.

These types of questions are best suited for StackOverflow though, so if this answer isn't sufficient feel free to re-post there! 😄 🌈

@ranyefet
Copy link
Author

ranyefet commented Oct 1, 2015

This is awesome, thanks!

@skleest
Copy link

skleest commented Jan 21, 2016

Hi @brentvatne, can I get more explanation on how to use your component please? Posted here (http://stackoverflow.com/questions/34933860/react-native-how-to-detect-link-form-string-and-convert-to-a-link), thank you!

@obipawan
Copy link

@ranyefet you can checkout react-native-hyperlink. It's super simple to use, all you have to do is wrap your views within <Hyperlink /> with an onPress prop
A basic example:

<Hyperlink onPress={(url) => alert(url)} linkStyle={{fontSize:16, color:'blue'}}>
    <Text style={{fontSize:15}}>This text will be parsed to check for clickable strings like https://github.com/obipawan/hyperlink and made clickable.</Text>
</Hyperlink>

@brettdonald
Copy link

brettdonald commented Aug 1, 2017

@obipawan It's simple, but it seems you can't specify a label for the link. Links should be displayed as clickable human-readable text, not a clickable URL. I like how Wikipedia does it:
[https://mediawiki.org MediaWiki] gives you MediaWiki

@obipawan
Copy link

obipawan commented Aug 1, 2017

@brettdonald you most definitely can :)

There's a linkText prop that takes a func that would return a label for the url. Although, I now like the way wikipedia does this

@jose920405
Copy link

jose920405 commented Oct 23, 2017

@brentvatne

Your solution is aplicable to android? because it seems that in android it is not possible for the <Text> to have children.

If indeed it is a case applicable only for ios. The best solution is:

<TextInput multiline={true} editable={false} dataDetectorTypes={'all'} style={styles.textLittleButton}>
    {this.props.user.presentationInfo.textInfo}
</TextInput>

I'm still searching this implementation in android, since dataDetectorTypes is only available in ios.

react-native-hyperlinked-text seems to be the solution, I'll try it

@pstanton
Copy link

this works for me (tested on android)

<Text>My paragraph has <Text onPress={...} style={{color:"red", textDecorationLine: "underline"}}>a link</Text> in it</Text>

@adaerodriguez
Copy link

Thanks @pstanton your solution works amazing!!

@facebook facebook locked as resolved and limited conversation to collaborators Jul 21, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

9 participants