Plug.Static (Plug v1.11.0) View Source
A plug for serving static assets.
It requires two options:
:at
- the request path to reach for static assets. It must be a string.:from
- the file system path to read static assets from. It can be either: a string containing a file system path, an atom representing the application name (where assets will be served frompriv/static
), or a tuple containing the application name and the directory to serve assets from (besidespriv/static
).
The preferred form is to use :from
with an atom or tuple, since
it will make your application independent from the starting directory.
For example, if you pass:
plug Plug.Static, from: "priv/app/path"
Plug.Static will be unable to serve assets if you build releases or if you change the current directory. Instead do:
plug Plug.Static, from: {:app_name, "priv/app/path"}
If a static asset cannot be found, Plug.Static
simply forwards
the connection to the rest of the pipeline.
Cache mechanisms
Plug.Static
uses etags for HTTP caching. This means browsers/clients
should cache assets on the first request and validate the cache on
following requests, not downloading the static asset once again if it
has not changed. The cache-control for etags is specified by the
cache_control_for_etags
option and defaults to "public"
.
However, Plug.Static
also supports direct cache control by using
versioned query strings. If the request query string starts with
"?vsn=", Plug.Static
assumes the application is versioning assets
and does not set the ETag
header, meaning the cache behaviour will
be specified solely by the cache_control_for_vsn_requests
config,
which defaults to "public, max-age=31536000"
.
Options
:gzip
- given a request forFILE
, servesFILE.gz
if it exists in the static directory and if theaccept-encoding
header is set to allow gzipped content (defaults tofalse
).:brotli
- given a request forFILE
, servesFILE.br
if it exists in the static directory and if theaccept-encoding
header is set to allow brotli-compressed content (defaults tofalse
).FILE.br
is checked first and dominatesFILE.gz
due to the better compression ratio.:cache_control_for_etags
- sets the cache header for requests that use etags. Defaults to"public"
.:etag_generation
- specify a{module, function, args}
to be used to generate an etag. Thepath
of the resource will be passed to the function, as well as theargs
. If this option is not supplied, etags will be generated based off of file size and modification time. Note it is recommended for the etag value to be quoted, which Plug won't do automatically.:cache_control_for_vsn_requests
- sets the cache header for requests starting with "?vsn=" in the query string. Defaults to"public, max-age=31536000"
.:only
- filters which requests to serve. This is useful to avoid file system traversals on every request when this plug is mounted at"/"
. For example, ifonly: ["images", "favicon.ico"]
is specified, only files in the "images" directory and the "favicon.ico" file will be served byPlug.Static
. Note thatPlug.Static
matches these filters against request uri and not against the filesystem. When requesting a file with name containing non-ascii or special characters, you should use urlencoded form. For example, you should writeonly: ["file%20name"]
instead ofonly: ["file name"]
. Defaults tonil
(no filtering).:only_matching
- a relaxed version of:only
that will serve any request as long as one of the given values matches the given path. For example,only_matching: ["images", "favicon"]
will match any request that starts at "images" or "favicon", be it "/images/foo.png", "/images-high/foo.png", "/favicon.ico" or "/favicon-high.ico". Such matches are useful when serving digested files at the root. Defaults tonil
(no filtering).:headers
- other headers to be set when serving static assets. Specify either an enum of key-value pairs or a{module, function, args}
to return an enum. Theconn
will be passed to the function, as well as theargs
.:content_types
- custom MIME type mapping. As a map with filename as key and content type as value. For example:content_types: %{"apple-app-site-association" => "application/json"}
.
Examples
This plug can be mounted in a Plug.Builder
pipeline as follows:
defmodule MyPlug do
use Plug.Builder
plug Plug.Static,
at: "/public",
from: :my_app,
only: ~w(images robots.txt)
plug :not_found
def not_found(conn, _) do
send_resp(conn, 404, "not found")
end
end
Link to this section Summary
Link to this section Functions
Callback implementation for Plug.call/2
.
Callback implementation for Plug.init/1
.