Last active
February 1, 2024 15:41
-
-
Save karpolan/ecce9c372bebb448ee04cc240ca5c8aa to your computer and use it in GitHub Desktop.
AWS CloudFront function for SPA, SSG and SEO. Redirects www URL to non-www URI, also adds missing `/index.html` to the link
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Based on this thread https://github.com/aws-samples/amazon-cloudfront-functions/issues/11 | |
*/ | |
function getQueryParamsAsString(querystring) { | |
if (!querystring || querystring.length < 1) { | |
return ''; // There is no query params | |
} | |
const str = []; | |
for (const param in querystring) { | |
const query = querystring[param]; | |
const multiValue = query.multiValue; | |
if (multiValue) { | |
str.push(multiValue.map((item) => param + '=' + item.value).join('&')); | |
} else if (query.value === '') { | |
str.push(param); | |
} else { | |
str.push(param + '=' + query.value); | |
} | |
} | |
if (str.length < 1) { | |
return ''; // No query parms were parsed | |
} | |
const result = '?' + str.join('&'); | |
return result | |
} | |
/** | |
* CloudFront function to redirect `https://www.*` and `http://www.*` URI to `to https://*` | |
* Also adds missing `/index.html` to the end of URI, useful for SPA and SSG websites. | |
* Supports query params for redirects. | |
* @example: `http://www.xxx.com/page/?param=1` -> `https://xxx.com/page/?param=1` | |
* @example: `https://www.xxx.com/page/?param=1` -> `https://xxx.com/page/?param=1` | |
* @example: `https://xxx.com/page/` -> `https://xxx.com/page/index.html` | |
* @example: `https://xxx.com/page` -> `https://xxx.com/page/index.html` | |
* @example: `https://xxx.com/page/?ref=user1` -> `https://xxx.com/page/index.html?ref=user1` | |
* @example: `https://xxx.com/page?ref=user1` -> `https://xxx.com/page/index.html?ref=user1` | |
*/ | |
function handler(event) { | |
const request = event.request; | |
const uri = request.uri; | |
// Redirect .www to https + non-www | |
if (request.headers["host"] && request.headers["host"].value.startsWith("www.")) { | |
const queryParamsToApplied = getQueryParamsAsString(request.querystring) | |
const response = { | |
statusCode: 301, | |
statusDescription: 'Moved Permanently', | |
headers: { | |
'location': { value: 'https://' + request.headers["host"].value.replace('www.', '') + uri + queryParamsToApplied } | |
} | |
}; | |
return response; // Stop processing request here | |
} | |
// Add missing /index.html part | |
if (uri.endsWith('/')) { | |
// Check whether the URI is missing a file name. | |
request.uri += 'index.html'; | |
} else if (!uri.includes('.')) { | |
// Solution for the root and folders | |
request.uri += '/index.html'; | |
} | |
return request; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment