Expanding a URI template with variables
A URI template is a URL pattern with placeholders in curly braces, such as https://api.example.com/repos/{owner}/{repo}. Expanding it means replacing each placeholder with a value and percent-encoding that value so the result is a valid URL. The syntax is standardised in RFC 6570, and APIs such as GitHub's return templates like this in their responses.
This tool takes the template in the first box and a JSON object of variables in the second, for example {"owner": "octo cat", "repo": "hello/world"}, and prints the expanded URL. It implements the whole of RFC 6570 up to Level 4.
Example
Variables:
{"owner": "octo cat", "repo": "hello/world", "path": "/docs/read me.md", "section": "intro 2",
"x": 1024, "y": 768, "page": 2, "list": ["red", "green"], "keys": {"semi": ";", "dot": "."}}
| Template | Expanded |
|---|---|
https://api.example.com/repos/{owner}/{repo} |
https://api.example.com/repos/octo%20cat/hello%2Fworld |
https://example.com{+path} |
https://example.com/docs/read%20me.md |
https://example.com/page{#section} |
https://example.com/page#intro%202 |
/map{?x,y} |
/map?x=1024&y=768 |
/map{?x}{&page} |
/map?x=1024&page=2 |
/a{/owner} |
/a/octo%20cat |
/a/{owner:3} |
/a/oct |
/c{/list*} |
/c/red/green |
/m{;x,y} |
/m;x=1024;y=768 |
file{.list*} |
file.red.green |
/k{?keys*} |
/k?semi=%3B&dot=. |
The difference between the first two rows is the point of having several operators. In {repo} the slash is data, so it's encoded as %2F and the URL keeps the right number of path segments. In {+path} the slashes are meant to be structure, so reserved expansion leaves them alone and only encodes the space. {#section} works like {+...} but adds a leading #, and only when the variable has a value.
Operators and modifiers
| Expression | Prefix | Separator | Notes |
|---|---|---|---|
{var} |
none | , |
Simple expansion, everything but unreserved characters encoded |
{+var} |
none | , |
Reserved characters such as / and ? kept |
{#var} |
# |
, |
Fragment, reserved characters kept |
{.var} |
. |
. |
Label expansion, e.g. file extensions |
{/var} |
/ |
/ |
Path segments |
{;var} |
; |
; |
Path parameters written as name=value |
{?var} |
? |
& |
Query string, name=value pairs |
{&var} |
& |
& |
Query continuation after a literal ? |
Two modifiers work with any operator. :n keeps only the first n characters of a string value ({owner:3} gives oct). * explodes a list or object: {/list*} writes one path segment per item, and {?keys*} writes one key=value pair per entry. Without *, a list is joined with commas (red,green) and an object becomes key,value,key,value.
Numbers and booleans are expanded as text (1024, true). A list or object that itself contains an object or array can't be expressed in a URI template, so the tool reports an error for it.
Encoding
Simple expansion encodes every character except letters, digits and - . _ ~, as the RFC requires. That includes characters JavaScript's encodeURIComponent leaves alone: RFC 6570's own example expands {hello} with "Hello World!" to Hello%20World%21, and so does this tool. Non-ASCII text is encoded as UTF-8, so café becomes caf%C3%A9. Literal text outside the braces is copied as written, except characters that can't appear in a URL at all (such as spaces), which are percent-encoded.
Steps
- Paste the template into the first box.
- Enter the variables as a JSON object in the second box, or leave it empty.
- Click Convert and copy the expanded URL.
- If you see "Enter valid JSON for the variables", the second box isn't valid JSON; keys need double quotes, so
{id:1}fails and{"id": 1}works. The JSON validator will show where. - If you see an error about the template itself, it names the expression at fault, for example an unclosed
{or a name containing a space.
Related tools
To encode or decode a single value outside a template, use the URL encoder and the URL decoder. The URL standard behind all of this is RFC 3986, which defines which characters are reserved and which must be percent-encoded.
Last updated