supabase-rb-rb
Storage

Retrieve public URL

Build the public URL for an object in a public bucket.

Construct the public URL for path without making an HTTP request — pure string builder. Only meaningful for buckets created with public: true; for private buckets you want create_signed_url instead.

The method does not check that the object exists, that the bucket is actually public, or that storage-api will accept the URL — it just glues the base URL, render path, bucket id, and (RFC3986-encoded) path segments together.

Signature

supabase.storage.from(bucket_id).get_public_url(path,download: nil,transform: nil)

Parameters

NameTypeRequiredDescription
pathStringRequiredObject path inside the bucket. Each segment is RFC3986-encoded (spaces become %20, "+" becomes %2B) so user-supplied filenames do not break the URL.
downloadBoolean, StringOptionaltrue to append ?download= (empty value — browsers use the original filename). Pass a String to append ?download=<filename> overriding the suggested filename.
transformHashOptionalImage-render options (height, width, resize, format, quality). When provided, the URL is routed through /render/image/public/<bucket>/ instead of /object/public/<bucket>/, with the keys appended as query params.

Returns

Returns
String

The fully-qualified URL. No network request is made. Note that storage-api only honors the URL if the bucket was created with public: true — calling get_public_url on a private bucket returns a string that will 401 when fetched.

Example — vanilla public URL

supabase.storage.from("avatars").get_public_url("people/ada.png")
# => "https://project.supabase.co/storage/v1/object/public/avatars/people/ada.png"

Example — force download with a custom filename

supabase.storage.from("downloads").get_public_url(
  "release-notes/v1.0.0.md",
  download: "release-notes-1.0.0.md"
)
# => ".../object/public/downloads/release-notes/v1.0.0.md?download=release-notes-1.0.0.md"

Example — image transform

supabase.storage.from("avatars").get_public_url(
  "people/ada.png",
  transform: { width: 128, height: 128, resize: "cover" }
)
# => ".../render/image/public/avatars/people/ada.png?width=128&height=128&resize=cover"

Example — filenames with spaces

supabase.storage.from("attachments").get_public_url("Meeting Notes 2026-Q2.pdf")
# => ".../object/public/attachments/Meeting%20Notes%202026-Q2.pdf"

Path encoding uses RFC3986 (unreserved set). URI.encode_www_form_component is deliberately NOT used because it follows application/x-www-form-urlencoded (spaces → +, which storage-api rejects).

On this page