DocsStandard library
URLs.
Parse a URI reference, resolve it against a base, and encode components deliberately.
A URL reference can be absolute or relative. The Url module lets you work with its components directly, so you don’t have to assemble query strings by concatenating text.
API reference: Url
Parsing and printing.
import Url
main() =
case Url.parse "https://example.com/items" of
Nothing -> print "invalid URL"
Just url -> print (Url.toString (Url.withQuery [("q", "hello world")] url))
This prints https://example.com/items?q=hello%20world. parse returns a Maybe Url, and it rejects malformed escapes, invalid characters in a component, and invalid ports.
The scheme and a registered host name are lowercased. Non-ASCII text in a component has to be percent-encoded first, and there’s no conversion for internationalized host names.
The Url type.
The record keeps the optional scheme, user information, host, port, query, and fragment apart from the path. The path, query and fragment stay percent-encoded and don’t include their leading separators. A missing query is different from a query that’s present but empty.
requestTarget produces the origin-form path and query that an HTTP client sends. It never includes the fragment.
Resolution.
A relative reference only gets its meaning from a base URL. For example, a link from a page under /guide/ can point to a sibling directory:
import Url
main() =
case (Url.parse "https://example.com/guide/start", Url.parse "../api?q=1#details") of
(Just base, Just reference) ->
resolved = Url.resolve base reference
print (Url.toString resolved)
print (Url.requestTarget resolved)
_ -> print "invalid URL"
https://example.com/api?q=1#details
/api?q=1
resolve merges a relative path with the base’s directory and removes dot segments. A reference that has its own scheme or authority replaces the matching parts of the base. Resolve a reference before sending it, because the fragment belongs to the client and is left out of the HTTP request target.
Encoding and queries.
Encode components before you join them. A slash inside a path segment should stay part of that segment instead of starting a new directory:
import Url
main() =
print (Url.percentEncode Url.PathSegment "a/b")
print (Url.percentDecode "hello%20world")
print (Url.percentDecode "%FF")
a%2Fb
Just "hello world"
Nothing
The component you choose matters, since PathSegment and QueryPart keep different punctuation. percentDecode rejects malformed escapes and invalid UTF-8 instead of replacing them.
queryParams keeps the order of the pairs and reads + as a space. withQuery appends encoded pairs, and appendPath appends encoded segments. When you’re building a URL from application values that aren’t encoded yet, prefer these helpers.
