A file URL on macOS looks like file:///Users/alex/Documents/report.pdf — three slashes, not two. Spaces become %20. Use it when an API expects a URL type, not a plain path. Pathly's "Copy as URL" produces the correct RFC-compliant format in one right-click.
What Is a file:// URL? (RFC 8089)
The file:// URL scheme is defined by RFC 8089, which superseded the older RFC 1738 definition in 2017. The scheme provides a uniform way to reference files on the local file system using the familiar URL format — the same format used for https:// and ftp:// URLs.
The general structure is:
file://[host]/path/to/file
On a local machine, the [host] component is either empty or localhost. Since an empty host still requires the // separator, and the absolute path on macOS starts with /, you end up with three consecutive slashes:
file:///Users/alex/Documents/report.pdf
^^^
||+-- start of the absolute path
|+--- (empty host)
+---- scheme separator
This is correct. A file:// URL with only two slashes (file://Users/alex/...) would be interpreted as having Users as the hostname — which is wrong for local file access.
URL Encoding: How Spaces and Special Characters Work
POSIX paths allow spaces and many special characters. URLs do not — they require percent-encoding for anything outside a narrow set of safe characters. On macOS, the most common encoding issue is spaces, which become %20:
| POSIX path | Correct file:// URL |
|---|---|
/Users/alex/Documents/report.pdf |
file:///Users/alex/Documents/report.pdf |
/Users/alex/My Documents/report.pdf |
file:///Users/alex/My%20Documents/report.pdf |
/Users/alex/project (v2)/main.swift |
file:///Users/alex/project%20(v2)/main.swift |
/Users/alex/résumé.pdf |
file:///Users/alex/r%C3%A9sum%C3%A9.pdf |
Characters that must be encoded include: spaces (%20), parentheses (%28, %29), hash (%23), question mark (%3F), ampersand (%26), and non-ASCII characters (encoded as UTF-8 byte sequences). Forward slashes in the path are not encoded — they remain as literal /.
Constructing a file URL by simple string concatenation — "file://" + path — produces an invalid URL if the path contains spaces or special characters. Always use a proper encoding function.
When to Use a file:// URL vs a POSIX Path
This is the question that actually matters for day-to-day development. The answer depends on what API or system you're working with.
Use a file:// URL when:
- Electron apps —
shell.openPath(),BrowserWindow.loadURL(), andwebContents.loadFile()all accept file URLs. TheloadURLmethod in particular expects a URL string, not a POSIX path. - Browser-based file loading — opening a local HTML file in a WebView or browser context with
file:///prefix. - macOS APIs that work with NSURL — Swift and Objective-C APIs that accept
URLtypes (notStringtypes) expect file URLs. Example:URL(fileURLWithPath: "/path/to/file")produces a file URL. - AppleScript — some AppleScript commands that accept
POSIX filecoercions work with file URL strings. - Safari Developer Tools — the browser address bar and some internal APIs use file:// URLs to reference local resources.
Use a POSIX path when:
- Shell commands and Terminal —
cd,open,cat,cp, every shell command takes plain paths. - Most config files —
.envfiles, JSON config, YAML, Makefile — plain paths are the norm unless the tool specifically says otherwise. - Python / Ruby file I/O —
open("/path/to/file")takes a POSIX path string, not a file URL. - Most CI/CD tools — GitHub Actions, CircleCI, etc. use plain paths in their YAML configs.
Code Examples: Constructing and Using file:// URLs
JavaScript (Node.js)
// Converting a POSIX path to a file URL
const { pathToFileURL } = require('url');
const fileUrl = pathToFileURL('/Users/alex/Documents/report.pdf');
console.log(fileUrl.href);
// → file:///Users/alex/Documents/report.pdf
// Handles spaces correctly:
const fileUrl2 = pathToFileURL('/Users/alex/My Documents/report.pdf');
console.log(fileUrl2.href);
// → file:///Users/alex/My%20Documents/report.pdf
JavaScript (Browser / Electron renderer)
// Loading a local file in Electron's BrowserWindow
// In main process:
mainWindow.loadURL(`file://${__dirname}/index.html`);
// Or using loadFile (path only, no file:// prefix needed):
mainWindow.loadFile('index.html');
Electron — shell.openPath
const { shell } = require('electron');
// shell.openPath takes a POSIX path, NOT a file:// URL
await shell.openPath('/Users/alex/Documents/report.pdf');
// shell.openExternal DOES take a file:// URL
await shell.openExternal('file:///Users/alex/Documents/report.pdf');
Note the distinction: shell.openPath() takes a POSIX path. shell.openExternal() takes a URL string including the scheme. Getting this wrong is a common source of bugs in Electron apps on macOS.
Swift / macOS
// Creating a file URL from a path string
let posixPath = "/Users/alex/Documents/report.pdf"
let fileURL = URL(fileURLWithPath: posixPath)
print(fileURL)
// → file:///Users/alex/Documents/report.pdf
// Opening a file with the default application
NSWorkspace.shared.open(fileURL)
Python
import pathlib
path = pathlib.Path("/Users/alex/My Documents/report.pdf")
file_url = path.as_uri()
print(file_url)
# → file:///Users/alex/My%20Documents/report.pdf
Terminal: convert any path to a file URL
python3 -c "import pathlib, sys; print(pathlib.Path(sys.argv[1]).as_uri())" \
"/Users/alex/My Documents/report.pdf"
# → file:///Users/alex/My%20Documents/report.pdf
How Pathly Produces the Correct file:// URL
Pathly's "Copy as URL" action takes the file's POSIX path, constructs a correctly-encoded file:// URL — with three slashes and proper percent-encoding of all special characters — and puts it on your clipboard. No Terminal, no Python script, no manual encoding.
This is the format you get for /Users/alex/My Documents/report.pdf:
file:///Users/alex/My%20Documents/report.pdf
The encoding is done using the same APIs that macOS uses internally (URL(fileURLWithPath:) in Swift), so the output is guaranteed to be correctly formed and accepted by any macOS API that consumes file URLs.
The file:// URL scheme is one of those things that looks simple until you try to construct one manually. The three-slash rule is easy to miss; URL encoding is tedious to get right for all edge cases (try filenames with parentheses, accented characters, or hash symbols). The correct approach is always to use a dedicated API — whether that's pathToFileURL() in Node, URL(fileURLWithPath:) in Swift, or pathlib.Path.as_uri() in Python. Pathly does exactly this under the hood, so you can just right-click and paste.
Summary
- A file URL on macOS always has three slashes:
file:/// - Spaces and special characters must be percent-encoded
- Use file URLs for Electron, macOS NSURL APIs, and browser contexts
- Use POSIX paths for Terminal, shell scripts, and most config files
- Always construct file URLs with a proper API — not string concatenation
- Pathly's "Copy as URL" gives you a ready-to-use, correctly-encoded file URL in one right-click
For the related question of when to use absolute vs relative paths, see Absolute vs Relative Paths on Mac Explained.