Host Options
Example:
module.exports = {
hosts: [{
domain: 'example.net',
root: './build/site',
fallback: { 200: './app.html' },
directories: { trailingSlash: 'never' },
accessControl: { allowOrigin: '*' },
headers: [{ fields: { 'X-Frame-Options': 'deny' } }],
manifest: [{ get: '/app.html', push: '/app.css' }]
}]
}
Table of Contents
- hosts[].domain
- hosts[].root
- hosts[].fallback
- hosts[].directories
- hosts[].accessControl
- hosts[].headers[]
- hosts[].manifest
- hosts[].redirects[]
hosts[].domain
Default: ''
or 'localhost'
(only for the default site, see serveDefaultSite)
The DNS hostname of the site. May be specified as an Internationalized Domain Name (IDN) containing non-ASCII characters.
Multiple sites on the same server can each have their own configuration.
Examples:
module.exports = {
hosts: [
{ domain: 'example.net' },
{ domain: 'xn--yfro4i67o.example.net' },
{ domain: '🦄.example.net' }
]
}
hosts[].root
The path to the base directory containing static files to serve.
module.exports = {
hosts: [{
root: './website'
}]
}
If no root is specified, the server tries to auto-detect static site generator or packaging tool output directories. For example: ./dist
, ./public
, ./_site
, and many more.
If no directory is auto-detected, the current working directory is used. A warning message is logged to indicate this fallback behaviour.
hosts[].fallback
Default: {}
(no fallback)
An object mapping HTTP status code to file paths.
Typically used for client side routing.
Fallbacks are supported for:
200
to serve a missing file as a success response.404
to serve a missing file as an error response.
Example for client-side routing (e.g. SPA or PWA):
module.exports = {
hosts: [{
fallback: { 200: './app.html' }
}]
}
Example for "Not Found" error pages:
module.exports = {
hosts: [{
fallback: { 404: './page-not-found.html' }
}]
}
hosts[].directories
Behaviour of directory paths in clean URLs.
hosts[].directories.trailingSlash
Default: 'always'
Enforces a consistent ending character for directory paths.
The value is a string that can be:
'always'
to use an HTTP redirect to append a/
at the end of the directory name.'never'
to use an HTTP redirect to strip any/
at the end of the directory name.
hosts[].accessControl
Settings related to Cross-Origin Resource Sharing (CORS). The server responds to OPTIONS
method requests with the appropriate response headers to allow (or deny) third-party access.
hosts[].accessControl.allowOrigin
Default: '*'
If specified, sets this value as the Access-Control-Allow-Origin
header on every response.
hosts[].headers[]
Sets custom HTTP response headers. The headers
array contains header objects. Each header object has the fields
and uri
properties.
module.exports = {
hosts: [{
headers: [
{
fields: {
'Content-Security-Policy': "default-src 'self'",
'Feature-Policy': "payment 'none'",
'Strict-Transport-Security': 'max-age=31536000',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'X-Frame-Options': 'SAMEORIGIN',
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff'
}
},
{
uri: '/service-worker.js',
fields: {
'Service-Worker-Allowed': '/'
}
},
{
uri: '/scripts/{filename}.{hash}.js',
fields: {
'Cache-Control': 'public, max-age=31536000, immutable'
}
},
{
fields: {
'Set-Cookie': ['foo=bar', 'bar=baz']
}
}
]
}]
}
hosts[].headers[].fields
fields
is a required object whose property names and values are the HTTP headers to set on the response.
Property names must be valid HTTP header field names. Only case-insensitive alphanumeric characters (A
through Z
, and 0
through 9
) and hyphens (-
dash) are allowed.
Example | Validity |
---|---|
Referrer-Policy |
Allowed |
:status |
Not Allowed |
Values may contain named template segments in braces. The values are substituted using matches from the uri
template.
Values may also be arrays of strings to set multiple headers with the same name.
hosts[].headers[].uri
uri
is an optional string as a URI Template. The header fields are applied only if the request pathname matches the route.
If no uri
property is set, the fields
headers are applied to all responses.
hosts[].manifest
The manifest
property declares which files or URLs need to be pushed as dependencies for any request. Using HTTP/2 Server Push (PUSH_PROMISE
frames) can eliminate round trips between browser and server and speed up resource loading.
The manifest
property type can be:
- Array: Inline manifest, see the HTTP/2 Server Push Manifest specification for details and examples.
- String: File path of an external manifest. This path is relative to the server configuration file.
Example: Inline manifest
module.exports = {
hosts: [{
manifest: [
// Example:
{
// When serving the homepage,
get: '**/*.html',
// push all CSS and JS files.
push: ['**/*.css', '**/*.js']
}
]
}]
}
Example: External manifest file
Using an external file is useful when using a build tool that traces dependencies to automatically generate the manifest.
This example shows a static website in the ./dist
directory. The first section runs the @commonshost/manifest
command line interface (CLI) tool to trace all HTML/JS/CSS files for dependencies. The automatically generated manifest is stored as ./manifest
. The second section shows a reference to this external manifest.
$ npx @commonshost/manifest generate ./dist ./manifest.json
module.exports = {
hosts: [{
manifest: './manifest.json'
}]
}
hosts[].redirects[]
Create redirects from gone pages to new pages.
Custom redirects help preserve inbound links and maintain search engine rankings & optimisation (SEO). As a website's content changes, pages are often moved around. Redirects are used to avoid leaving broken links from external sites to your old pages.
Tip: Use a fallback page (See: hosts[].fallback
) to capture inbound links to no-longer-existing pages. With proper analytics reporting you can build a list of the most frequently visited broken links, and redirect them somewhere more useful.
Examples:
module.exports = {
hosts: [{
redirects: [
// Old page to new page
{ from: '/old/page', to: '/new/page' },
// Old page to a different website
{ from: '/somewhere', to: 'https://new.example.net/other/site' },
// Override the HTTP status code to use a temporary redirect
{ from: '/promotion', to: '/summer-special', status: 307 },
// Use URI Template pattern matching to preserve variables
{ from: '/shop{?sort,product}',
to: '/store/item{/product}{?sort}' }
]
}]
}
hosts[].redirects[].from
from
is a required string as a URI Template.
Only paths on the current site can be matched.
hosts[].redirects[].to
to
is a required string as a URI Template.
This path may be relative to the current origin (a.k.a. domain name) or an absolute URL pointing to a different origin.
hosts[].redirects[].status
status
is an optional integer from 300 through 399.
The default status code is 308 which means Permanent Redirect. Use 307 to generate a Temporary Redirect.
See the IANA list of assigned HTTP status codes: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml