Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mrtonyhuynh/56d950f272f197b7ceb239950120dddb to your computer and use it in GitHub Desktop.
Save mrtonyhuynh/56d950f272f197b7ceb239950120dddb to your computer and use it in GitHub Desktop.
AWS Lambda @edge function to generate og:meta tags for facebook
'use strict';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const https = require('https');
export const handler = async(event, context, callback) => {
let content = "";
let userAgent = false;
const request = event.Records[0].cf.request;
const headers = request.headers;
if(headers){
userAgent = request.headers['user-agent'];
}
// NOTE: Identify the facebook share request by user-agent header
// I added few more, but 'facebookexternalhit' is the most important one
let prerender = /Facebot|FacebookBot|facebookexternalhit|twitterbot/i.test(userAgent[0].value);
if(prerender){
let path = request.uri;
let options = {
// NOTE: link to your API endpoint
hostname: "<api-endpoint>",
path: path,
headers: {
"Content-Type": "application/json",
}
}
const initialResponse = await new Promise((resolve, reject) => {
const req = https.get(options, function(res) {
res.on('data', chunk => {
content += chunk;
});
res.on('end', () => {
resolve({
statusCode: 200,
body: content.toString()
});
});
});
req.on('error', (e) => {
reject({
statusCode: 400,
body: e
});
});
});
// Our API returns the meta data in JSON format so we need to parse it
let data = JSON.parse(initialResponse.body);
// NOTE: We need to get the full url of the page we are sharing
let ogUrl = `https://${headers['host'][0]['value']}${request.uri}`
// NOTE: We need to generate the HTML code with the meta data
// Our meta keys fetched from API are:
// metaTitle - title of the page
// metaDescription - description of the page
// metaImageUrl - image of the page
// if any of these are different, don't forget to change them in the code below (f.e. og:locale)
// The fb:app_id is the id of your facebook app
let htmlContent = `
<\!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${data.metaTitle}</title>
<meta property="fb:app_id" content="<your-fb-app-id>">
<meta property="og:title" content="${data.metaTitle}" />
<meta property="og:description" content="${data.metaDescription}" />
<meta property="og:image" content="${data.metaImageUrl}" />
<meta property="og:url" content="${ogUrl}" />
<meta property="og:type" content="website" />
<meta property="og:locale" content="sk_SK" />
</head>
<body>
</body>
</html>
`;
const response = {
status: '200',
statusDescription: 'OK',
headers: {
"content-type": [{
"key": "Content-Type",
"value": "text/html; charset=utf-8"
}],
"cache-control": [{
"key": "Cache-Control",
"value": "max-age=100"
}]
},
body: htmlContent,
};
callback(null, response);
} else {
callback(null, request);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment