Reference
If you have a use case where you wish to show users different content based on their location, then you can do that by using a combination of CloudFront and lambda edge functions.
In this post, I will go through a step-by-step process on how you can do that. I will redirect a user from the UK to a UK-specific page and the others to the rest of the world-specific page.
You can configure CloudFront to add specific HTTP headers whose values are based on characteristics of the viewer request. With these headers, your origin can receive information about the viewer’s device type, geographic location, and more, without the need for custom code to determine this information. If your origin returns different responses based on the information in these headers, you can include them in the cache key so that CloudFront caches the different responses separately.
Source AWS
What that means is that if we serve our application from CloudFront and configure its headers correctly then we can get access to these values in our lambda edge’s origin request lifecycle method
- CloudFront-Viewer-Country **** This contains the two-letter country code for the viewer’s country. For a list of country codes, see ISO 3166–1 alpha-2.
- CloudFront-Viewer-City **** This contains the name of the viewer’s city.
- CloudFront-Viewer-Country-Name **** This contains the name of the viewer’s country.
- CloudFront-Viewer-Country-Region **** This contains a code (up to three characters) that represents the viewer’s region. The region is the first-level subdivision (the broadest or least specific) of the ISO 3166–2 code.
- CloudFront-Viewer-Country-Region-Name **** This contains the name of the viewer’s region. The region is the first-level subdivision (the broadest or least specific) of the ISO 3166–2 code.
- CloudFront-Viewer-Latitude – This contains the viewer’s approximate latitude.
- CloudFront-Viewer-Longitude **** This contains the viewer’s approximate longitude.
- CloudFront-Viewer-Metro-Code **** This contains the viewer’s metro code. This is present only when the viewer is in the United States.
- CloudFront-Viewer-Postal-Code – This contains the viewer’s postal code.
- CloudFront-Viewer-Time-Zone – this Contains the viewer’s time zone, in IANA time zone database format (for example, America/Los_Angeles).
Create a static website on S3
For the purpose of this post, I have built a simple web application using NextJS which has 2 routes –/uk
& /row
. The site is bundled and hosted on S3 as a static website. You can have your web application built & bundled in any library of your choice.
Once you have the bundle ready, go to S3 and create a new bucket and upload the contents of the bundle to this bucket.
Then, go to the properties of the bucket and enable static website hosting like this
After this, grant public access to the content of this bucket by turning these off like this
And lastly, add this bucket policy to grant read access –
bucket policy
Now, you should be able to access your web application by going to the URL provided on the properties of this bucket under the static website hosting like this
Configure CloudFront with custom headers
Create a new distribution and select your S3 bucket with the static website as the origin domain
Then add these custom headers by selecting legacy settings like this. I have selected the ones I wanted to test with, but it is really up to your use case on what you need.
Add lambda edge function
At this point, our CloudFront is ready and loaded with header values that we can access in our lambda edge functions. Head over to the lambda service on your AWS console and make sure that you are in the us-east-1
region. Lambda edge must be deployed in that region.
Create a new function from scratch like this
lambda from scratch
You will see a code editor on the console itself, where you can paste this code and adapt it according to your setup & requirements
I am only interested in knowing the country code of the end-user, which I am extracting from CloudFront’s request headers. Once, I have that, I am redirecting all users from GB/UK to /uk
page and the rest will be redirected to /row
page.
Attach lambda edge to CloudFront
This is the final step that will allow us to execute this lambda function on CloudFront’s origin request function. This is how AWS defines its CloudFront’s events –
After CloudFront receives a request from a viewer (viewer request)Before CloudFront forwards the request to the origin (origin request)After CloudFront receives the response from the origin (origin response)Before CloudFront forwards the response to the viewer (viewer response)
Source AWS
From AWS — Using AWS Lambda with CloudFront Lambda@Edge
Now, to attach the functions, there are 2 ways. You can either copy the arn
of lambda function into CloudFront’s behaviors section like this
or, you can add it as a trigger, directly from the lambda console itself like this
Add a trigger to CloudFront
If you get a permission error from lambda edge, then you have to add lambdaedge
as a trusted entity into your function’s IAM role like this
Wait for your CloudFront distribution to be redeployed, and once that is done, your redirect service should be ready. This is how it looks for me 🎉