Generates URLs for media files.
Options
All URL-generating functions accept the following options in addition to any adapter-specific options:
:cache_bust—boolean— whentrueand the media item has a stored checksum, appends a?v={checksum[0..7]}query parameter so that CDN edges serve a fresh object whenever the file changes. Defaults tofalse.:signed—boolean— whentrue, generates a signed/expiring URL. For S3 this is an AWS Signature V4 presigned GET URL. For local disk this is an HMAC-signed URL that can be verified byPhxMediaLibrary.Plug.MediaDownload. Requires:expires_in(see below). Defaults tofalse.:expires_in—integer— expiry window in seconds for signed URLs (default:3600). Has no effect unless:signedistrue.:download—boolean— whentrue, generates a URL suitable for file downloads. For S3, this attaches aContent-Disposition: attachmentresponse header to the presigned URL. For local disk, the URL routes throughPhxMediaLibrary.Plug.MediaDownloadwhich sets the header. Implies:signedfor S3 (a presigned URL is required). Defaults tofalse.:filename—String.t()— override the filename used in theContent-Dispositionheader when:downloadistrue. Defaults to the media item'sfile_name.
CDN Cache-Busting
When assets are served through a CDN you typically want far-future
Cache-Control headers and a content-fingerprint in the URL so the CDN
picks up the new asset when you replace a file.
# Regular URL
PhxMediaLibrary.url(media)
#=> "/uploads/images/42/abc/photo.jpg"
# CDN URL with cache-busting checksum
PhxMediaLibrary.cdn_url(media)
#=> "/uploads/images/42/abc/photo.jpg?v=a1b2c3d4"
# Explicit option form
PhxMediaLibrary.url(media, nil, cache_bust: true)
#=> "/uploads/images/42/abc/photo.jpg?v=a1b2c3d4"Signed / Expiring URLs
For S3 (already supported by the adapter):
PhxMediaLibrary.signed_url(media)
#=> "https://bucket.s3.amazonaws.com/...?X-Amz-Signature=..."
PhxMediaLibrary.signed_url(media, nil, expires_in: 300)For local disk storage (requires PhxMediaLibrary.Plug.MediaDownload to be
mounted in the app's router):
# router.ex
forward "/media", PhxMediaLibrary.Plug.MediaDownload, disk: :local
# config.exs
config :phx_media_library,
disks: [
local: [
adapter: PhxMediaLibrary.Storage.Disk,
root: "priv/static/uploads",
base_url: "/uploads",
download_base_url: "/media",
secret_key_base: "long-random-secret"
]
]Download Links
For S3, this generates a presigned URL with response-content-disposition:
PhxMediaLibrary.download_url(media)
#=> "https://bucket.s3.amazonaws.com/...?response-content-disposition=attachment..."For local disk, the URL routes through PhxMediaLibrary.Plug.MediaDownload
which serves the file with Content-Disposition: attachment.
Summary
Functions
Generate a CDN-friendly URL with cache-busting via a content-fingerprint query parameter.
Generate a download URL for a media item.
Generate a signed, time-limited URL for a media item.
Generate a URL for a media item.
Generate a URL for a specific path (used for responsive images / poster frames that are stored at an explicit path rather than a derived one).
Functions
@spec cdn_url(PhxMediaLibrary.Media.t(), atom() | nil) :: String.t()
Generate a CDN-friendly URL with cache-busting via a content-fingerprint query parameter.
Equivalent to url(media, conversion, cache_bust: true).
When the media item has no stored checksum (e.g. legacy records), returns the plain URL without any query parameter.
Examples
iex> PhxMediaLibrary.UrlGenerator.cdn_url(media)
"/uploads/images/1/uuid/photo.jpg?v=a1b2c3d4"
iex> PhxMediaLibrary.UrlGenerator.cdn_url(media, :thumb)
"/uploads/images/1/uuid/photo_thumb.jpg?v=a1b2c3d4"
@spec download_url(PhxMediaLibrary.Media.t(), atom() | nil, keyword()) :: String.t()
Generate a download URL for a media item.
For S3 storage this generates a presigned GET URL that instructs the
browser (and S3) to serve the file with a Content-Disposition: attachment
header so the browser downloads rather than renders the file.
For local disk storage the URL routes through
PhxMediaLibrary.Plug.MediaDownload which sets the Content-Disposition
header when serving the file. The plug must be mounted in the app's router.
Equivalent to url(media, conversion, download: true).
Options
Accepts all options supported by url/3. Additionally:
:filename— override the filename in theContent-Dispositionheader. Defaults tomedia.file_name.:expires_in— expiry for the presigned URL in seconds (S3 only). Defaults to3600.
Examples
iex> PhxMediaLibrary.UrlGenerator.download_url(media)
"https://bucket.s3.../file.zip?...&response-content-disposition=attachment..."
# Local disk (requires Plug.MediaDownload mounted at "/media")
iex> PhxMediaLibrary.UrlGenerator.download_url(media)
"/media/images/1/uuid/photo.jpg"
@spec signed_url(PhxMediaLibrary.Media.t(), atom() | nil, keyword()) :: String.t()
Generate a signed, time-limited URL for a media item.
For S3 storage this is an AWS Signature V4 presigned GET URL valid for
:expires_in seconds (default: 3600).
For local disk storage this generates an HMAC-signed URL that is
verified by PhxMediaLibrary.Plug.MediaDownload. A secret_key_base
must be present in the disk configuration and the plug must be mounted.
Equivalent to url(media, conversion, signed: true).
Options
:expires_in— expiry window in seconds (default:3600).:download— also attach aContent-Disposition: attachmentheader (seedownload_url/3).
Examples
iex> PhxMediaLibrary.UrlGenerator.signed_url(media)
"https://bucket.s3.../file.jpg?X-Amz-Signature=..."
iex> PhxMediaLibrary.UrlGenerator.signed_url(media, nil, expires_in: 300)
@spec url(PhxMediaLibrary.Media.t(), atom() | nil, keyword()) :: String.t()
Generate a URL for a media item.
Arguments
media— thePhxMediaLibrary.Mediastruct.conversion— optional conversion name atom (e.g.:thumb). Passnil(default) for the original file.opts— keyword list of options (see module docs).
@spec url_for_path(PhxMediaLibrary.Media.t(), String.t(), keyword()) :: String.t()
Generate a URL for a specific path (used for responsive images / poster frames that are stored at an explicit path rather than a derived one).
Options
Accepts :cache_bust with an explicit checksum string, or any
adapter-specific options.