lambit v0.3.2
Lambit 
A suite of modern hosting features for running static websites on AWS with Lambda@Edge functions. This library lets you mimic the functionality of static hosting services with things such as pushState routing and custom redirects, but with the power of CloudFront and Lambda running in your own AWS account. Total control for a fraction of the cost.
If you're not familiar with Lambda@Edge, read up on it here. You can also checkout my getting started tutorial for utilizing Lambda@Edge with static sites.
Install
$ npm install -S lambitNote: You need to bundle the
lambitdependency along with your Lambda function code before uploading to AWS. Check out node-lambda for a quick way to bundle and deploy.
Getting Started
After you create your AWS Lambda function with a Node.js runtime, simply call lambit with your config object in place of the usual function code. It will handle everything related to the event for you.
const lambit = require('lambit')
exports.handler = lambit({
cleanUrls: true,
rewrites: [
{ source: '/*', to: '/index.html' }
]
})You will need to attach this function to three out of the four triggers on your CloudFront distribution:viewer-request origin-request viewer-response
If you want to write some custom code in your Lambda function to run alongside Lambit, just initialize it inside your function after you've done your thing:
exports.handler = (event, context, callback) => {
/* custom code goes here */
lambit({
cleanUrls: true,
rewrites: [
{ source: '/*', to: '/index.html' }
]
})(event, context, callback)
}API
lambit (config: Object)
cleanUrlsType:
boolean/array
Default:falseIf
true, will redirect all URLs with an.htmlextension and append.htmlfor origin requests on urls without an extension. It will also redirect any urls with an index file at the suffix (/hi/index.html=>/hi/). If an array is used, it should be an array of URL patterns to enable clean urls for.cleanUrls: true // or cleanUrls: ['/blog*', '/team/*']rewritesType:
array
Default: noneA list of rewrites that will change the URL sent to the origin without responding with a redirect. Useful for pushState routing. Must define
sourceandtofor each rewrite.rewrites: [{ source: '/*', to: '/index.html' }]redirectsType:
array
Default: noneA list of redirects that will return an early response sending client to a new URL. Must define
source,toand an optionalcodethat defaults to301.redirects: [{ source: '/blog{name+}', to: 'https://medium.com/@jsonmaur{name}', code: 302 }]protectType:
object
Default: noneThe authentication details for your site (only Basic Auth is supported at the moment.) You must define
username,passwordand an optionalsourceif you want to protect a subpath on your site.protect: { source: '/admin*', username: 'janedoe', password: 's3cr3t' }headersType:
array
Default: noneA list of custom response headers sent to the client. Each header must define
name,valueand an optionalsourcefor only returning headers for specific paths.headers: [{ name: 'Access-Control-Allow-Origin', value: '*', source: '/cors' }]wwwType:
boolean
Default: noneIf
true, all paths will be redirected to a www version of the site. Iffalse, all paths will be redirected to a non-www version of the site (the apex in most cases.) If undefined, no action will take place for either.www: true
Path Matching
For any config value that accepts a source key, you can specify a custom pattern to test against the URL. If a match is found, the operation will continue. If no matches are found, well... you get the picture. Path matching can be used for clean URLs, rewrites, redirects, headers and protect.
Segments
{
source: '/hello/{name}',
to: '/wazzup/{name}'
}The above example will parse the URL and if it matches source, will extract name from the URL and construct a new URL in the destination.
You can make a segment optional by appending ? or a named wildcard by appending +. You can have as many segments as you want in the URL, but you can't have two segments right next to each other as in /{segment1}{segment2}, two segments with the same name as in /{segment}/{segment}, or a segment next to a wildcard as in /{segment}*. The segment name must only contain letters, numbers and underscores.
Examples
/{greeting}- Will match
/hello, but not/hello/jane
- Will match
/{greeting}/{name}- Will match
/hello/jane, but not/hello/jane/doeor/hello
- Will match
/{greeting?}- Will match
/and/hello, but not/hello/jane
- Will match
/{greeting+}- Will match
/hello,/hello/janeand/hello/jane/doe
- Will match
/{greeting+}/doe- Will match
/hello/doeand/hello/jane/doe, but not/hello
- Will match
Wildcards
{
source: '/hello/*',
to: '/wazzup'
}The above example will match anything prepended with /hello/ such as /hello/jane and /hello/jane/doe/really/long/path. Using * in your pattern is an "unnamed wildcard", meaning you can't extract the value and use it in your destination. If you want to use the extracted value in your destination, you can use a named wildcard as shown in the section above.
Examples
/hello*- Will match
/hello,/helloooand/hello/jane
- Will match
/hello/*- Will match
/hello/janeand/hello/jane/doe, but not/hello
- Will match
/*/jane*- Will match
/hello/janeand/hello/jane/doe, but not/hello/doe
- Will match
Custom Regex
{
source: /hello/(.*)/,
to: '/wazzup/{1}'
}If you need to be really flexible with your pattern matching, you can define your own regular expression. Any capture groups will be extracted from the matching URL and made available in the destination as numbered segments such as {1} and {2}.