Skip to content

Instantly share code, notes, and snippets.

@karpolan
Last active February 1, 2024 15:41
Show Gist options
  • Save karpolan/ecce9c372bebb448ee04cc240ca5c8aa to your computer and use it in GitHub Desktop.
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
/**
* 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