Plug v1.6.0 Plug.Static 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.: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 exact “favicon.ico” file will be served byPlug.Static
. 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.: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
.