SEO optimizations with Cloudformation
Tags: website, aws, cloudformation, cloudfront
Published: 2023-12-29 15:49:52

---
title: SEO optimizations with Cloudformation
published: true
date: 2023-12-15 17:49:53 UTC
tags: Website,AWS,Cloudformation,Cloudfront
canonical_url: 
---

(Original post: https://marcoaguzzi.it/2023/12/15/SEO-optimization-cloudformation/)

Looking (again) at SEO metrics, I wanted to fix two misbehaviors of the website: compression and error pages.  
Let’s get through the process:

# HTTP compression

This has been an easy one. The SEO tool wanted the site to accept compression, so moving from requesting this (locahost:4000 is the local hexo server where the html rendering is immediately visible):

```
GET / HTTP/1.1Host: localhost:4000Accept-Encoding: gzip, deflate, br
```

and getting no matching compression to asking for this:

```
GET / HTTP/1.1Host: marcoaguzzi.itAccept-Encoding: gzip, deflate, br
```

and be answered

```
Content-Encoding: br
```

which is the confirmation that Brotli compression is enabled.

## Cloudformation snippet

The configuration should be done in the cloudfront serving the site hosted on S3. Namely, in the DefaultCacheBehavior by adding _Compress: True_ to the yaml. The other settings required in the cache (enable gzip and enable brotli) are already served by referencing the pre-made _CachingOptimized_ _CachePolicy_. Here’s the snippet: for clarity, the _CachePolicyId_ is referenced in a map,  
and, in this case, its value is _658327ea-f89d-4fab-a63d-7e88639e58f6_

```
"DefaultCacheBehavior": { "Compress": true, ..., "CachePolicyId": { "Fn::FindInMap": ["CacheMapping", "Global", "CachingOptimized"] }, ...}
```

## References

- [https://docs.aws.amazon.com/cloudfront/latest/APIReference/API\_DefaultCacheBehavior.html](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DefaultCacheBehavior.html)
- [https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html)
- [https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html)

# Custom error pages

The plugin managing the pagination of the website renders links to page “0” and “last page + 1” (they’re hidden, though). Crawling the website and pointing to those links, cloudfront replies with a 403 because the pages are not mapped in the S3 bucket. Instead of exposing the 403 error with an awkward cloudfront xml, it could be better to serve a page styled as the rest of the website, and maybe returning HTTP 200 code, thus the human user will see a courtesy page, but the http client won’t know that it hit a wrong path.

This can be achieved by instructing cloudfront to serve custom error pages when a HTTP error is raised. The path of the custom error pages must be present in the served S3 bucket.

## Edit the Cloudformation template

In the _DistributionConfig_ property section of _CloudfrontDistribution_ resource, adding a _CustomErrorResponses_ array will do the job. In this case only the HTTP 403 error is fired for unknown paths (per the S3 bucket configuration, there should be no 404 error),  
so one line in the array will be enough. The object is quite self-explanatory: _ErrorCode_ is the error fired, _ResponseCode_ is the error code to be returned to the client, and _ResponsePagePath_ is the page to be shown:

```
"CloudFrontDistribution": { "Properties": { "DistributionConfig": { "CustomErrorResponses":[{ "ErrorCode" : 403, "ResponseCode" : 200, "ResponsePagePath" : "/errors/403.html" }], } }}
```

## Hexo page

The error page has been created like any other page in the site that is accessible from the topbar menu:

```
hexo new page errors
```

and a folder _errors_ with an _index.md_ file is created.  
Next, the _index.md_ file has been renamed to _403.md_ in order for it to be rendered as _403.html_ (with the _hexo generate_ command), as the _ResponsePagePath_ value states. The rendered html can then be pushed on git and deployed as any other article.  
For reference, the actual error page is [here](/errors/403.html).

# The full Gist

The full parent cloudformation template can be found in this gist:

#Click to view cloudformation template on gist<script src="https://gist.github.com/maguzzi/47473c9561292301d8669aa903698181.js"></script>