Home > Mobile >  Render anchor tag as hyperlink in React-Native Text Component
Render anchor tag as hyperlink in React-Native Text Component

Time:11-18

I am using expo react-native to show the data from an API.

API is returning HTML with <p> and <a> tags. I am using the Text component of react-native to show data but it is showing the <a> tag as it is. I want to show the hyperlink created through that anchor tag.

I already applied renderHTML package but using this, other tags like <br/> and <p> tags are getting ignored and the text is looking very cluttered.

CodePudding user response:

Use react-native-webview to render HTML content in webview You can use this package even in expo managed workflow https://www.npmjs.com/package/react-native-webview

CodePudding user response:

Here is the solution to rendering HTML properly in your react native app.
Install react-native-render-html.

npm i react-native-render-html

Create a component called "HtmlViewer.js":
HtmlViewer.js

import React from 'react';
import HTML from 'react-native-render-html';
import { View, Dimensions, StyleSheet, Text } from 'react-native';

const width = Dimensions.get('window').width;

const HtmlViewer = ({ text, style }) => {
  // first check that html is empty or not, otherwise something it display large spacing
  if (
    !text ||
    text === '' ||
    text === ' ' ||
    text === null ||
    text === undefined ||
    text === '<p ><br></p>' ||
    text === '<p ><br></p>' ||
    text === '<p ><br></p>' ||
    text === '<p ><br></p>' ||
    text === '<p ><br></p>' ||
    text === '<p><br></p>'
  ) {
    return null;
  }
  return (
    <View
      style={style}>
      <HTML
        source={{
          html: text.replace(/(\r\n|\n|\r)/gm, ''), // use replace to remove new line
        }}
        contentWidth={width}
        renderers={{
          h1: (htmlAttribs, children, convertedCSSStyles, passProps) => (
            <Text
              style={htmlViewStyle[htmlAttribs.class]}
              key={passProps.key}>
              {children}
            </Text>
          ),
          h2: (htmlAttribs, children, convertedCSSStyles, passProps) => (
            <Text
              style={htmlViewStyle[htmlAttribs.class]}
              key={passProps.key}>
              {children}
            </Text>
          ),
          h3: (htmlAttribs, children, convertedCSSStyles, passProps) => (
            <Text
              style={htmlViewStyle[htmlAttribs.class]}
              key={passProps.key}>
              {children}
            </Text>
          ),
          p: (htmlAttribs, children, convertedCSSStyles, passProps) => (
            <Text
              style={htmlViewStyle[htmlAttribs.class]}
              key={passProps.key}>
              {children}
            </Text>
          ),
          span: (htmlAttribs, children, convertedCSSStyles, passProps) => (
            <Text style={htmlViewStyle[htmlAttribs.class]} key={passProps.key}>
              {children}
            </Text>
          ),
        }}
        allowWhitespaceNodes={false}
        classesStyles={htmlViewStyle}
        tagsStyles={{
          h1: {
            fontSize: 38,
          },
          h2: {
            fontSize: 34,
          },
          h3: {
            fontSize: 30,
          },
          p: {
            fontSize: 18,
          },
          rawtext: {
            fontSize: 16,
          },
          textwrapper: {
            fontSize: 16,
          },
        }}
      />
    </View>
  );
};

const htmlViewStyle = StyleSheet.create({
  'ql-align-center': {
    textAlign: 'center',
  },
  'ql-align-left': {
    textAlign: 'left',
  },
  'ql-align-right': {
    textAlign: 'right',
  },
  'ql-align-justify': {
    textAlign: 'justify',
  },
});

export default HtmlViewer;

Use this component to render your HTML.

import HtmlViewer from '../yourcomponentPath/HtmlViewer.js'
...
...
<HtmlViewer text={yourHtmlText} />
  • Related