Facebook post preview with ReactJS and AWS Lambda
Tags: showdev, react, javascript, beginners
Published: 2018-07-03 01:36:22

---
title: Facebook post preview with ReactJS and AWS Lambda
published: true
description: React JS app built using AWS Lambda and hosted on Netlify
tags: showdev, react, javascript, beginners
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pxfetg8lcuy3fr36i8n7.png
---

I'm currently focused on learning more about React. For me, the best way to learn something is to build a small project that's not a todo list (lol).

That being said, I've decided to build a small app that receives an URL, fetch the meta tags (especially the open graph tags) and build a preview based on facebook.

To accomplish this task I've chosen ReactJS and AWS Lambda (hosted on Netlify).


### The Lambda function

The lambdas task is pretty simple. Receive an URL, parse and fetch the meta tags, looking for the Open Graph tags.

The **open-graph-scraper** npm package almost got the entire job done, so here is the final code of the lambda:

```js
import ogs from "open-graph-scraper";
import getUrl from "get-urls";
import urlParser from "url";

export function handler(event, context, callback) {
  const text = event.queryStringParameters.q;
  const urls = getUrl(text);

  // Return if there is no urls in text
  if (!urls.size) {
    return callback(null, {
      statusCode: 200,
      body: JSON.stringify({
        text: text,
        meta: null,
        error: ["Empty url in text"]
      })
    });
  }

  // Retrieve first URL in text - urls are already normalized
  const url = [...urls][0];
  const options = { url };

  ogs(options, (error, results) => {
    const statusCode = results.success ? 200 : 500;
    callback(null, buildResponseObject(statusCode, results, text));
  });
}

function getUrlDomain(url) {
  const urlObj = urlParser.parse(url);
  return urlObj.host;
}

function cleanText(text) {
  return text.replace(/(?:https?|ftp):\/\/[\n\S]+/g, "");
}

function buildResponseObject(statusCode, result, text) {
  let meta = statusCode === 200 ? result.data : null;

  if (meta) {
    let images = meta.ogImage;

    if (images instanceof Array) {
      meta.ogImage = images[0];
    }

    let domain = meta.ogUrl;

    if (domain) {
      meta.ogUrl = getUrlDomain(meta.ogUrl);
    }
  }

  const body = {
    meta: meta,
    text: cleanText(text),
    error: statusCode !== 200 ? result.error : null
  };

  return {
    statusCode,
    body: JSON.stringify(body)
  };
}
```

### The Frontend
As I mentioned at the beginning of the post, react was chosen to build the client interface.

The packages used are:

```json
  "dependencies": {
    "get-urls": "^7.2.0",
    "netlify-lambda": "^0.4.0",
    "open-graph-scraper": "^3.3.0",
    "react": "^16.4.1",
    "react-content-loader": "^3.1.2",
    "react-dom": "^16.4.1",
    "react-scripts": "1.1.4",
    "styled-components": "^3.3.2"
  },
```

And here is the result:

![screenshot](https://thepracticaldev.s3.amazonaws.com/i/pxfetg8lcuy3fr36i8n7.png)

### Contributing

It's free and open source! 

The code is [hosted on Github](https://github.com/hugodias/facebook-post-preview) and you can [see it in action here](https://facebook-preview.netlify.com).

I'm looking forward to your feedback, folks.

Thanks