React Native 링크 프리뷰 만들기

Written on October 1, 2020

채팅방이나 트위터, 페이스북에 공유하고 싶은 웹페이지의 url을 많이 공유하는데, 이 때 url만 표기가 된다면 내용을 알기 어렵기 때문에 해당 페이지의 썸네일, 제목, 내용 등이 미리보기 형식으로 표시해 주는 것이 필요하다.

이 때 사용될 수 있는 기본적인 방법이 Open Graph Tag를 이용하는 것이다. 웹 페이지에 대한 간략한 정보를 Open Graph protocol에 따라 <head> 영역에 입력해 두면, 다른 서비스 에서는 이 정보를 읽어 미리보기 화면을 만들어 사용자 들에게 웹 페이지에 대한 공통적인 정보를 주는 것이다.


기본적인 Metadata는 아래와 같다.

<head>
......
<meta property="og:title" content="제목"/>
<meta property="og:type" content="데이터의 타입 (article, website, image...)"/>
<meta property="og:url" content="사이트 주소"/>
<meta property="og:description" content="데이터에 대한 설명"/>
<meta property="og:image" content="데이터의 썸네일/이미지 주소"/>
......
</head>

기본적으로, 전달하고자 하는 링크의 html을 가져와 og tag를 파싱한 후 og tag 정보로 미리보기 ui를 표현하면 된다. 따라서 html을 파싱하기만 하면 간단하게 구현할 수 있는데, 관련 라이브러리 중 react-native-cheerio 라이브러리를 사용해 보았다. 하지만 라이브러리를 사용하는데 로드가 많이 걸려서 다른 방법을 찾아 보다가 정규표현식으로도 html 파싱을 구현해 보았다.

react-native-cheerio 라이브러리 사용

npm i react-native-cheerio

react-native-cheerio의 사용법은 간단한데, 우선cheerio.load 메서드를 사용해 html을 파싱한다. 그리고 “og:title”이라는 property를 가진 meta tag의 content 속성값을 가지고 오는 것은 아래와 같이 표현할 수 있다.

const cheerio = require('react-native-cheerio');
const $ = cheerio.load(html);
const content = $(`meta[property="og:title"]`).attr('content');

og:title, og:description, og:image, og.url 값을 파싱하는 코드는 아래와 같이 작성할 수 있다.

...
import axios from 'axios';
const cheerio = require('react-native-cheerio');

const fetchHtml = async (link: string) => {
    return await axios.get(link);
};

const parseHtml = (html: string) => {
    const properties = ['title', 'description', 'image', 'url'];
    const meta: MetaData = {};
    const cheerio = require('react-native-cheerio');
    const $ = cheerio.load(html);
    properties.forEach((p) => {
        const content = $(`meta[property="og:${p}"]`).attr('content');
        if (content) {
          meta[p] = content;
        }
    });
    return meta;
};

const findOGTags = async (link:string) => {
    try{
      const {data} = await fetchHtml(url);
      const meta = await parseHtml(data);
    }catch(e){
      console.log(e);
    }
}

정규표현식 사용

위의 코드에서 parseHtml 부분만 변형하여 정규표현식을 사용한 코드는 아래와 같이 작성할 수 있다.

const parseHtml = (html: string) => {
    const metaTagOGRegex = /<meta[^>]*(?:property=[ '"]*og:([^'"]*))?[^>]*(?:content=["]([^"]*)["])?[^>]*>/gi;
    const matches = html.match(metaTagOGRegex);
    const meta: MetaData = {};

    if (matches) {
        const metaPropertyRegex = /<meta[^>]*property=[ "]*og:([^"]*)[^>]*>/i;
        const metaContentRegex = /<meta[^>]*content=[ "]([^"]*)[^>]*>/i;
        matches.forEach((m) => {
            const propertyMatch = metaPropertyRegex.exec(m);
            if (propertyMatch) {
                const property = metaPropertyRegex.exec(propertyMatch[0]);
                const content = metaContentRegex.exec(propertyMatch[0]);
                if (property && content) {
                    meta[property[1]] = content[1];
                }
            }
        });
    }
    return meta;
}

위의 코드에서 얻은 meta data를 활용하여 원하는 대로 미리보기 ui 뷰를 그려줄 수 있다.

link_preview_ios link_preview_aos

👩🏻‍💻 배우는 것을 즐기는 프론트엔드 개발자 입니다
부족한 블로그에 방문해 주셔서 감사합니다 🙇🏻‍♀️

in the process of becoming the best version of myself