Skip to content

Commit 45aceda

Browse files
author
Thomas Turrell-Croft
committed
Change single page applicaiton to static website
1 parent 68f0a89 commit 45aceda

File tree

6 files changed

+29
-23
lines changed

6 files changed

+29
-23
lines changed

README.md

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This repository contains example CloudFront functions and instructions to deploy
66

77
[CloudFront Functions](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html) is a serverless edge compute feature allowing you to run JavaScript code at the 225+ [Amazon CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) edge locations for lightweight HTTP(S) transformations and manipulations. Functions is purpose-built to give you the flexibility of a full programming environment with the performance and security that modern web applications require. At a fraction of the price of [AWS Lambda@Edge](https://aws.amazon.com/lambda/edge/), CloudFront Functions can scale instantly and affordably to support millions of requests per second.
88

9-
CloudFront Functions is natively built into CloudFront, allowing you to easily build, test, and deploy viewer request and viewer response functions entirely within CloudFront. This GitHub repo offers a collection of example code that can be used as a starting point for building functions. You can build functions using the IDE in the CloudFront console, or with the CloudFront APIs/CLI. Once your code is authored, you can test your function against a production CloudFront distribution, ensuring your function will execute properly once deployed. The test functionality in the console offers a visual editor to quickly create test events and validate functions. You can use CloudFront Functions in addition to the existing AWS Lambda@Edge capability that also allows you to run custom code in response to CloudFront events.
9+
CloudFront Functions is natively built into CloudFront, allowing you to easily build, test, and deploy viewer request and viewer response functions entirely within CloudFront. This GitHub repo offers a collection of example code that can be used as a starting point for building functions. You can build functions using the IDE in the CloudFront console, or with the CloudFront APIs/CLI. Once your code is authored, you can test your function against a production CloudFront distribution, ensuring your function will execute properly once deployed. The test functionality in the console offers a visual editor to quickly create test events and validate functions. You can use CloudFront Functions in addition to the existing AWS Lambda@Edge capability that also allows you to run custom code in response to CloudFront events.
1010

1111
CloudFront functions are ideal for lightweight computation tasks on web requests. Some popular use cases are:
1212

@@ -17,35 +17,38 @@ CloudFront functions are ideal for lightweight computation tasks on web requests
1717

1818
## Example CloudFront functions
1919

20-
|Example|Description|
21-
|------|-------|
22-
|[Add a `True-Client-IP` request header](add-true-client-ip-header/)| `True-Client-IP` is an HTTP request header that you can add to incoming CloudFront requests so that the IP address of the viewer (client) is passed along to the origin.|
23-
|[Add HTTP security response headers](add-security-headers/)| This function adds several of the more common HTTP security headers to the response from CloudFront, including HTTP Strict Transport Security (HSTS), Content Security Policy (CSP), `X-Content-Type-Options`, `X-Frame-Options`, and `X-XSS-Protection`.|
24-
|[Perform URL rewrite for single page applications](url-rewrite-single-page-apps/)| You can use this function to perform a URL rewrite to append "index.html" to the end of URLs that don’t include a filename or extension. This is particularly useful for single page applications or statically generated websites using frameworks like React, Angular, Vue, Gatsby, or Hugo.|
25-
|[URL redirect based on a user’s country](redirect-based-on-country)| This function redirects a user to a country-specific version of a site based on the country of the user. In this example, if the user is in Germany, the function redirects the user to the `/de/index.html` page which is the German version of the site. If the user is not in Germany, the request passes through with no modification to the URL.|
26-
|[Add origin request header if missing](add-origin-header/)| This function adds an origin header if it is not present on the incoming request. The origin header, part of cross-origin resource sharing (CORS), is a mechanism using HTTP headers to tell the web server which origin initiated this particular request.|
27-
|[Verify JSON Web Tokens](verify-jwt/)| This function performs a lightweight security token validation using JSON Web Tokens. You can use this type of tokenization to give a user of your site a URL that is time-bound. Once the predetermined expiration time has occurred, the user can no longer access the content at that URL.|
28-
|[Add CORS headers if missing](add-cors-header/)| This function adds an `Access-Control-Allow-Origin` response header if it is not present on the outgoing response from CloudFront.|
29-
|[Add a `Cache-Control` header](add-cache-control-header/)| This function adds a `Cache-Control` response header to the outgoing response from CloudFront for browser caching.|
20+
| Example | Description |
21+
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
22+
| [Add a `True-Client-IP` request header](add-true-client-ip-header/) | `True-Client-IP` is an HTTP request header that you can add to incoming CloudFront requests so that the IP address of the viewer (client) is passed along to the origin. |
23+
| [Add HTTP security response headers](add-security-headers/) | This function adds several of the more common HTTP security headers to the response from CloudFront, including HTTP Strict Transport Security (HSTS), Content Security Policy (CSP), `X-Content-Type-Options`, `X-Frame-Options`, and `X-XSS-Protection`. |
24+
| [Perform URL rewrite for static websites](url-rewrite-static-websites/) | You can use this function to perform a URL rewrite to append "index.html" to the end of URLs that don’t include a filename or extension. This is particularly useful for static websites generated using frameworks like Next.js, Gatsby, or Hugo. |
25+
| [URL redirect based on a user’s country](redirect-based-on-country) | This function redirects a user to a country-specific version of a site based on the country of the user. In this example, if the user is in Germany, the function redirects the user to the `/de/index.html` page which is the German version of the site. If the user is not in Germany, the request passes through with no modification to the URL. |
26+
| [Add origin request header if missing](add-origin-header/) | This function adds an origin header if it is not present on the incoming request. The origin header, part of cross-origin resource sharing (CORS), is a mechanism using HTTP headers to tell the web server which origin initiated this particular request. |
27+
| [Verify JSON Web Tokens](verify-jwt/) | This function performs a lightweight security token validation using JSON Web Tokens. You can use this type of tokenization to give a user of your site a URL that is time-bound. Once the predetermined expiration time has occurred, the user can no longer access the content at that URL. |
28+
| [Add CORS headers if missing](add-cors-header/) | This function adds an `Access-Control-Allow-Origin` response header if it is not present on the outgoing response from CloudFront. |
29+
| [Add a `Cache-Control` header](add-cache-control-header/) | This function adds a `Cache-Control` response header to the outgoing response from CloudFront for browser caching. |
3030

3131
## Deploying a CloudFront function using the AWS CLI
32+
3233
We will use the example that adds cache control headers to responses as our function, but the same process can be used for all the functions with only minor changes.
3334

3435
**Step 1**: Install the [AWS CLI](https://aws.amazon.com/cli/). If you already have the AWS CLI, upgrade to the most recent version.
3536

3637
> Note: The examples below assume you are using version 2 of the AWS CLI. There are breaking changes between v1 and v2 of the AWS CLI, which can be found [here](https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html). In v2 of the AWS CLI, binary parameters are passed as base64-encoded strings by default. If you are using v2 of the AWS CLI, you need to do one of the following:
3738
>
38-
>- You can tell the AWS CLI version 2 to revert to the AWS CLI version 1 behavior by specifying the following line in the `~/.aws/config` file for a given profile: `cli_binary_format=raw-in-base64-out`
39+
> - You can tell the AWS CLI version 2 to revert to the AWS CLI version 1 behavior by specifying the following line in the `~/.aws/config` file for a given profile: `cli_binary_format=raw-in-base64-out`
3940
> - Pass all files using `fileb://`, which treats the file content as unencoded binary.
4041
4142
**Step 2**: Clone this repository.
4243

4344
**Step 3**: Change directories into the repo directory.
45+
4446
```
4547
cd amazon-cloudfront-functions/
4648
```
4749

4850
**Step 4**: Create a CloudFront function.
51+
4952
```
5053
aws cloudfront create-function \
5154
--name add-cache-control-headers \
@@ -71,17 +74,18 @@ aws cloudfront create-function \
7174
}
7275
}
7376
```
77+
7478
Make sure you capture the `ETag` value, since you will need it to publish your function.
7579

7680
**Step 5**: Test the CloudFront function.
7781

7882
To test a function, you need to pass in a JSON request or response object used to simulate a viewer request or response. A sample of the event object format can be found [here](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-event-structure.html). This repo contains test events that you can use to test the example functions.
7983

80-
Test the function using the provided test event by running the following command, using the function's `ETag` (from the previous command's output) as the value for `--if-match`:
84+
Test the function using the provided test event by running the following command, using the function's `ETag` (from the previous command's output) as the value for `--if-match`:
8185

8286
```
8387
aws cloudfront test-function \
84-
--name add-cache-control-headers \
88+
--name add-cache-control-headers \
8589
--if-match EXXXXXXXXX \
8690
--event-object fileb://add-cache-control-header/test-event.json
8791
@@ -108,11 +112,12 @@ aws cloudfront test-function \
108112
}
109113
}
110114
```
115+
111116
The function is running successfully since we did not receive an error message and there is a `FunctionOutput` object returned. Inside the `FunctionOutput` object, we can see the `cache-control` header was added as expected.
112117

113-
**Step 6**: Publish your CloudFront function.
118+
**Step 6**: Publish your CloudFront function.
114119

115-
If you received a similar response (to the one above) from the `test-function` command, you can publish the function.
120+
If you received a similar response (to the one above) from the `test-function` command, you can publish the function.
116121

117122
```
118123
aws cloudfront publish-function \
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
## URL rewrite to append index.html to the URI for single page applications
1+
## URL rewrite to append index.html to the URI for static websites
22

33
**CloudFront Functions event type: viewer request**
44

5-
You can use this function to perform a URL rewrite to append `index.html` to the end of URLs that don't include a filename or extension. This is particularly useful for single page applications or statically-generated websites using frameworks like React, Angular, Vue, Gatsby, or Hugo. These sites are usually stored in an S3 bucket and served through CloudFront for caching. Typically, these applications remove the filename and extension from the URL path. For example, if a user went to `www.example.com/blog`, the actual file in S3 is stored at `<bucket-name>/blog/index.html`. In order for CloudFront to direct the request to the correct file in S3, you need to rewrite the URL to become `www.example.com/blog/index.html` before fetching the file from S3. This function intercepts incoming requests to CloudFront and checks that there is a filename and extension. If there isn't a filename and extension, or if the URI ends with a "/", the function appends index.html to the URI.
5+
You can use this function to perform a URL rewrite to append `index.html` to the end of URLs that don't include a filename or extension. This is particularly useful for static websites generated using tools like Next.js Gatsby or Hugo. These sites are usually stored in an S3 bucket and served through CloudFront for caching. Users expect that a request for a URL that does not include a filename or extention are rewitten to append index.html. For example, if a user went to `www.example.com/blog`, the actual file in S3 is stored at `<bucket-name>/blog/index.html`. In order for CloudFront to direct the request to the correct file in S3, you need to rewrite the URL to become `www.example.com/blog/index.html` before fetching the file from S3. This function intercepts incoming requests to CloudFront and checks that there is a filename and extension. If there isn't a filename and extension, or if the URI ends with a "/", the function appends index.html to the URI.
66

77
There is a feature in CloudFront called the [default root object](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html) that allows you to specify an index document that applies to the root object only, but not on any subfolders. For example, if you set up index.html as the default root object and a user goes to `www.example.com`, CloudFront automatically rewrites the request to `www.example.com/index.html`. But if a user goes to `www.example.com/blog`, this request is no longer on the root directory, and therefore CloudFront does not rewrite this URL and instead sends it to the origin as is. This function handles rewriting URLs for the root directory and all subfolders. Therefore, you don't need to set up a default root object in CloudFront when you use this function (although there is no harm in setting it up).
88

@@ -13,22 +13,23 @@ There is a feature in CloudFront called the [default root object](https://docs.a
1313
To validate that the function is working as expected, you can use the JSON test objects in the `test-objects` directory. To test, use the `test-function` CLI command as shown in the following example:
1414

1515
```
16-
$ aws cloudfront test-function --if-match EXXXXXXXXXXXX --name url-rewrite-single-page-apps --event-object fileb://url-rewrite-single-page-apps/test-objects/file-name-no-extension.json
16+
$ aws cloudfront test-function --if-match EXXXXXXXXXXXX --name url-rewrite-static-websites --event-object fileb://url-rewrite-static-websites/test-objects/file-name-no-extension.json
1717
```
1818

19-
If the function has been set up correctly, you should see the `uri` being updated to `index.html` in the `FunctionOutput` JSON object:
19+
If the function has been set up correctly, you should see the `uri` being appened with `index.html` in the `FunctionOutput` JSON object:
20+
2021
```
2122
{
2223
"TestResult": {
2324
"FunctionSummary": {
24-
"Name": "url-rewrite-single-page-apps",
25+
"Name": "url-rewrite-static-websites",
2526
"Status": "UNPUBLISHED",
2627
"FunctionConfig": {
2728
"Comment": "",
2829
"Runtime": "cloudfront-js-1.0"
2930
},
3031
"FunctionMetadata": {
31-
"FunctionARN": "arn:aws:cloudfront::1234567890:function/url-rewrite-single-page-apps",
32+
"FunctionARN": "arn:aws:cloudfront::1234567890:function/url-rewrite-static-websites",
3233
"Stage": "DEVELOPMENT",
3334
"CreatedTime": "2021-04-09T21:53:20.882000+00:00",
3435
"LastModifiedTime": "2021-04-09T21:53:21.001000+00:00"
@@ -40,4 +41,4 @@ If the function has been set up correctly, you should see the `uri` being update
4041
"FunctionOutput": "{\"request\":{\"headers\":{\"host\":{\"value\":\"www.example.com\"},\"accept\":{\"value\":\"text/html\"}},\"method\":\"GET\",\"querystring\":{\"test\":{\"value\":\"true\"},\"arg\":{\"value\":\"val1\"}},\"uri\":\"/blog/index.html\",\"cookies\":{\"loggedIn\":{\"value\":\"false\"},\"id\":{\"value\":\"CookeIdValue\"}}}}"
4142
}
4243
}
43-
```
44+
```

0 commit comments

Comments
 (0)