DEV Community

MJ
MJ

Posted on • Edited on

Using Lambda@Edge for Single Page Application(SPA) on AWS Cloudfront

Recently, there is a new requirement on the project that I have been working on at work, which is to enable social sharing. It is for a stock photography website which allows users to buy photos at different resolutions, similar to Shutterstock or GettyImages. The new feature requires sharing of individual photo URL on the social sites.

Social Sharing

Implementing such feature is trivial for normal websites where basic metadata can be added to each HTML pages. Since the front-end app is implemented using Vuejs, it complicates. It is due to the fact that social sites like Facebook or Twitter do not executed the javascript on the crawled page for sharing on their sites. Therefore, it is not possible to use library to update the HTML page metadata dynamically.

One of the ways to resolve this is by implementing server side rendering for the pages. But, this will require additional hosting for the front-end app as the current setup leverages AWS S3 and AWS Cloudfront for static web hosting. This setup is considered cost effective and has well taken care of the scalability of the front-end app.

Lambda@Edge

A couple of hours researching on the web led me to discover that Lambda@Edge can be deployed to the AWS Cloudfront to intercept and customize the HTTP request. Depending on the source of request by inspecting the User-Agent header, we can modify the returned response body in the Lambda@Edge function.

So, this is how it works.

Flow Diagram

The green line represents the request flow for normal user access from browser. Then, the red line represents the request coming from social sites.

There are a few limitations on AWS Lambda@Edge as I have written it:

  • The supported runtime for Lambda@Edge for Cloudfront is only Nodejs.
  • The Lambda@Edge function can only be deployed onto the North Virginia region.
  • The Lambda@Edge function timeout can only be configured to 5 secs.
  • The Lambda@Edge function does not support environment variables and I have handled using Gulp script. Or you can try AWS System Manager Parameter Store.
  • The Lambda@Edge function cant be deployed into VPC.

For deployment, you will have to:

  • Publish a new version of your Lambda@Edge function.
  • Update the Cloudfront distribution with the new Lambda ARN.

And you will need to add the required permission to the Lambda role. Refer to here

For sample AWS Lambda@Edge code, please refer to the following Github repo:

mengjiann / aws-lambda-edge-cloudfront

AWS Lambda Edge for Cloudfront

AWS Lambda Edge for Cloudfront

This is a Lambda@Edge function that is used to customize response body for Single Page Application (SPA) served through Cloudfront.

It allows returning static html for social sites (including Facebook, WhatsApp, Twitter) for rich social sharing (due to the nature of Single Page Application - SPA).

Pre-requisite

  • npm - can be installed via Homebrew brew install node
  • gulp-cli - npm install gulp-cli -g

Guide to prepare zip file for deployment

  • Update the externalApi in the environment-config.json.
  • npm install
  • gulp default --env {environment} Environment: dev/ prod
  • archive.zip will be created in the root folder and can be deployed to AWS Lambda

Things to note

  • Environment variables are not supported for the Lambda@Edge deployed to Cloudfront. Therefore, gulp is used to automate the task of replacing the env variables and also create the artifact for uploading. Or AWS System Manager Parameter Store can be used.
  • AWS Lambda…

Reference:

  1. Open Graph Protocol: http://ogp.me/
  2. Vue Social Sharing Plugin: https://github.com/nicolasbeauvais/vue-social-sharing
  3. Vue Server Side Rendering: https://vuejs.org/v2/guide/ssr.html
  4. Official AWS Lambda@Edge doc: https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html
  5. Official AWS Lambda@Edge Limitation: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration

Top comments (0)