ws-resources.json
ws-resources.json is an optional file at the root of the site folder that configures the site.
The file itself is not published as part of the site.
| Field | Type | What it does |
|---|---|---|
headers | glob pattern → { header: value } | HTTP headers of the files that match. |
routes | pattern → path of a resource | Paths that serve another resource (for single-page apps). |
redirects | path pattern → { location, status_code } | HTTP redirects. |
metadata | object | link, image_url, description, project_url, creator: shown through the Display of the Site. |
site_name | text | Name of the Site. |
object_id | 0x… | The published Site. Written by deploy; with it, deploy updates that site. |
ignore | list of glob patterns | Files that are not published. |
Unknown fields are an error (for example site-name instead of site_name).
Example
The example site of the project uses every field except object_id (the strings are translated
here):
{
"site_name": "Example site on IOTA",
"metadata": {
"description": "A static site on the IOTA storage network, published from an IOTA wallet.",
"creator": "IOTA Storage"
},
"headers": {
"/estilo.css": { "Cache-Control": "public, max-age=3600" },
"/*.svg": { "Cache-Control": "public, max-age=86400" }
},
"routes": {
"/app/*": "/index.html"
},
"redirects": {
"/antiguo": { "location": "/docs/", "status_code": 301 },
"/blog/**": { "location": "/docs/", "status_code": 302 }
},
"ignore": ["/borradores/*"]
}
This documentation is itself published as a site, with this file:
{
"site_name": "IOTA Storage docs",
"headers": {
"/assets/**": {
"cache-control": "public, max-age=31536000, immutable"
},
"/es/assets/**": {
"cache-control": "public, max-age=31536000, immutable"
}
}
}
headers
Each key is a glob pattern on the path of the file (starting with /); each value is an object of
HTTP headers and their values, all as text.
- If several patterns match a file, the one with more path segments wins. Headers of different patterns are not merged.
- Header names are stored in lower case.
- Every resource also gets
content-encoding: identityand acontent-typefrom the file extension (a table of the usual web types,wasmandmdincluded), unless the matching pattern sets them. An unknown extension getsapplication/octet-stream. Thecontent-typehas nocharset; set it yourself if you need it.
Glob syntax:
| Pattern | Matches |
|---|---|
*, ** | Any sequence of characters, including /. ** must be a whole path segment (/assets/**). |
? | One character. |
[abc], [a-z], [!abc] | One character of the class, or not of the class. |
So /*.svg matches /logo.svg and also /img/icons/logo.svg.
routes
Each key is a path pattern and each value is the path of a resource of the site. When a path has no
resource (and no index.html below it, and no redirect), the portal serves the resource of the
route that matches.
*matches any sequence of characters, and the longest matching pattern wins.- A pattern can have at most two
*and none of( ) [ ] { } + ? ^ $ | \. - The destination must be a file of the site; otherwise publishing fails.
The typical use is a single-page app: "/app/*": "/index.html" serves /index.html for
/app/settings, /app/users/42 and so on.
redirects
Each key is a path pattern, and each value is an object with location (a path of the site or a
full URL) and status_code, one of 301, 302, 303, 307 or 308.
- Patterns are globs by segment:
*matches within one segment and does not cross/;**matches any number of segments. A segment can have at most one*, and a pattern at most one**. - If several patterns match, the most specific wins: more literal characters and, on a tie, fewer
*. - Redirects apply only to paths that have no resource. A redirect to the same path gives a 508 error.
For example:
"redirects": {
"/old-page": { "location": "/index.html", "status_code": 308 },
"/documentation": { "location": "https://docs.iotastorage.com", "status_code": 301 },
"/images/**/*": { "location": "/logo.svg", "status_code": 302 }
}
metadata and site_name
metadata accepts only link, image_url, description, project_url and creator, as text.
They are stored in the Site and shown through its Display, for example by wallets and
explorers.
site_name is the name of the Site. If it is missing, an existing site keeps its name and a new
one gets a default name.
object_id
The ID of the published Site. The deploy command of the CLI writes it after the first
publication, and uses it the next time to update that same site instead of creating a new one.
Keep it with the files of the site if you deploy from several machines.
ignore
A list of glob patterns (same syntax as headers). Matching files are not published. For
example:
"ignore": ["/private", "/private/*", "/secret.txt"]
Files
- All the files of the folder are published, including those whose name starts with a dot, except
ws-resources.jsonand the ignored ones. - A path can be up to about 2 KB long.
- Every file of the site is public, like every blob.