Butler

A fully-featured static server for your sites and apps. Includes support for HTML5 pushState, redirects, custom routes, proxied routes, clean URLs, custom error pages, and more. Butler is the open-sourced version of what powers Zab hosting.
Get Started
$ npm install butler -g
$ npm install butler --save
Then go into your project folder, setup your config from the options below, and run
$ butler
You can also use programmatically by importing the module. This will return a promise, which resolves when the server starts, returning an object with the URI and the server config.
import butler from 'butler'
butler().then((res) => {
})
You cannot currently use Butler as middleware in an existing server, but support is coming soon.
Config
You can customize the behavior of Butler with a file called butler.config.js
located in the root of your project. The file should export an object using CommonJS like the example below.
module.exports = {
root: 'dist',
}
Options
-
root
The root folder of your compiled site (where your index.html lives) relative to the directory you run Butler from.
Type: string
Default: dist
-
port
The port to serve your site on. This will be overridden by the PORT environment variable if it is set.
Type: integer
Default: 8000
-
host
The host to serve your site on. This will be overridden by the HOST environment variable if set.
Type: string
Default: 0.0.0.0
-
errorPage
Sets a custom 404 error page to use. Butler will serve a default 404 page if you don't specify one. File should be relative to your Butler config file.
Type: string
Default: Butler 404 page
-
cleanUrls
Lets you drop .html
from your URLs (zab.io/about
instead of zab.io/about.html
). When a URL with .html
is requested, we will drop it automatically with a 301 redirect.
Type: boolean
Default: true
-
pushState
A quick way to enable HTML5 pushState in your server. When enabled, all URLs that are not assets will fallback to /index.html
. This is a shortcut to defining /** => /index.html
in your routes.
Type: boolean
Default: false
-
forceSSL
Forces your site to be accessed over https by redirecting to the secure version of your site. Only enable this if you have a valid SSL certificate configured on your server!
Type: boolean
Default: false
-
redirects
You can specify certain URLs to be redirected to other locations, both internally and externally. This list is prioritized from top to bottom, and whichever route matches first will return. See Redirects for more info.
Type: array
of objects
Default: []
from
URL to matchto
URL to redirect totype
Redirect code to use. Defaults to 301
.
-
proxies
You can proxy any URL within your site to an external site, whether it's your API, blog, or a site full of kittens. This list is prioritized from top to bottom, and whichever route matches first will return. See Proxies for more info.
Type: array
of objects
Default: []
src
URL to matchdest
URL to proxy toheaders
Array of headers
-
routes
You can specify custom routes for your site, without being limited to your file structure (such as using aboutUs.html
for zab.io/about
). This list is prioritized from top to bottom, and whichever route matches first will return. See Routes for more info.
Type: array
Default: []
src
URL to matchdest
File to use for route
-
headers
Allows you to set custom response headers on your site globally or for specific routes. A good use case for this would be adding a CORS configuration. See Headers for more info.
Type: array
Default: []
name
Name of your headervalue
Value of your headerurl
Only apply header if URL matches this pattern
Redirects
You can specify certain URLs to be redirected to other locations, both internally and externally. This list is prioritized from top to bottom, and whichever route matches first will return. Supports segments to carry over values from the original URL, as well as splats for wildcards. You can also redirect to external sites by using an absolute url.
redirects: [
{ from: '/old/path', to: '/new/path' },
{ from: '/old/path', to: '/new/path', type: 302 },
{ from: '/name/:firstName', to: '/path/:firstName' },
{ from: '/google/**', to: 'https://www.google.com/#q=$1' },
]
Proxies
Proxies are a powerful feature in Butler. They allow you to mask outside URLs behind routes in your site. This is useful to solve issues with CORS, to mask the url of your APIs, and many other things. You can also send custom headers to the destination, following the same structure as headers. This list is prioritized from top to bottom, and whichever route matches first will return. Supports segments to carry over values from the original URL, as well as splats for wildcards. We will automatically set the Host
header to the host of the destination.
proxies: [
{
src: '/api/**',
dest: 'https://api.zab.io/**',
headers: [
{ name: 'x-custom-header', value: 'kittens' },
],
},
]
With the above example, going to mysite.com/api/user/12345
will proxy the request to https://api.zab.io/user/12345
. This is different than a redirect, because visitors will still see the original url with mysite.com
in their address bar.
Routes
You can specify custom routes for your site, without being limited to your file structure (such as using aboutUs.html
for zab.io/about
). Supports segments to carry over values from the original URL, as well as splats for wildcards. This list is prioritized from top to bottom, and whichever route matches first will return. Any URL with a file extension other than .html
will simply bypass the router.
routes: [
{ src: '/about', dest: 'aboutUs.html' },
{ src: '/contact', dest: 'contact-page.html' },
]
Allows you to set custom response headers on your site globally or for specific routes. A good use case for this would be adding a CORS configuration.
headers: [
{ name: 'Access-Control-Allow-Origin', value: '*' },
{ name: 'X-Special', value: 'Hi', url: '/special/**' },
]
Segments
Segments are a simple way of carrying over values from the old URL to the new URL. Any piece of your path preceded with :
is treated as a segment, and will carry over. For example, if you define the redirect /name/:firstName => /path/:firstName
, going to yoursite.com/name/jason
will redirect to yoursite.com/path/jason
.
Splats
Splats are a simple way of defining wildcards in your URLs. Putting **
anywhere in your source will allow anything to be matched there. It will also replace whatever the splat covers in the new URL if you include **
there as well. For example, if you define the redirect /blog/** => https://medium.com/@jsonmaur/**
, going to yoursite.com/blog/my-post
will redirect to https://medium.com/@jsonmaur/my-post
.
License
MIT © Zab Labs