URL Encode: Text to Percent-Encoding

h
104
h
e
101
e
l
108
l
l
108
l
o
111
o
32
%20
w
119
w
o
111
o
r
114
r
l
108
l
d
100
d

percent-encoding

Swap to percent-encoding to text

Read a percent-encoded string back as text

How do you URL encode a string?

URL encoding replaces the characters a URL cannot carry as data. A percent-encoded octet is a triplet: a percent sign followed by the two hexadecimal digits of that byte's value.

In short

A space becomes %20. Percent-encoding replaces every character outside the unreserved set - letters, digits, hyphen, period, underscore and tilde - with a percent sign and that byte's two hex digits.

  1. Write the text as UTF-8 octets first. That order is what makes a character outside US-ASCII into more than one triplet.
  2. Leave every unreserved character as it is: A-Z a-z 0-9 - . _ ~.
  3. Replace every other octet with a percent sign and that octet's 2 hexadecimal digits.
  4. Check the reserved characters. Each is safe where it delimits and needs a triplet where it is data.
  5. Read the result back to confirm it. hello world becomes hello%20world.

Text to Percent-Encoding Conversion Table

The reserved characters are the general delimiters : / ? # [ ] @ and the sub-delimiters ! $ & ' ( ) * + , ; = . Each one is safe where it acts as a delimiter and must be percent-encoded where it is data. The unreserved set is the ASCII letters, the digits, hyphen (-), period (.), underscore (_) and tilde (~). These characters never need percent-encoding, and a normaliser decodes them if it finds them encoded. Read the row for the character you have: the Triplet column is what a URL carries in its place. ASCII codes 32–126 are printable characters; 0–31 and 127 are control characters (for example 10 = line feed, 13 = carriage return, 32 = space). That row is the one everybody meets first.

Text to Percent-Encoding Conversion Table
CharacterNameRoleTriplet
A-Z a-z 0-9 - . _ ~unreservednot encoded
:the colongeneral delimiter%3A
/the slashgeneral delimiter%2F
?the question markgeneral delimiter%3F
#the number signgeneral delimiter%23
[the left bracketgeneral delimiter%5B
]the right bracketgeneral delimiter%5D
@the at signgeneral delimiter%40
!the exclamation marksub-delimiter%21
$the dollar signsub-delimiter%24
&the ampersandsub-delimiter%26
'the apostrophesub-delimiter%27
(the left parenthesissub-delimiter%28
)the right parenthesissub-delimiter%29
*the asterisksub-delimiter%2A
+the plus signsub-delimiter%2B
,the commasub-delimiter%2C
;the semicolonsub-delimiter%3B
=the equals signsub-delimiter%3D
(space)the spacenot allowed in a URI%20
%the percent signstarts a triplet%25

The same value in each encoding

These rows are shared with the other encoders, so a value written here is the value every page in the family writes.

The same value in each encoding
ValueWritten as
hello worldtext 'hello world' = percent 'hello%20world' = base64 'aGVsbG8gd29ybGQ='
spacecharacter ' ' = percent '%20' = base64 'IA==' = HTML no character reference needed
ampersandcharacter '&' = percent '%26' = base64 'Jg==' = HTML &
écharacter 'é' = percent '%C3%A9' = base64 'w6k=' = HTML é or é

Every value below is the one the specification fixes, so a result that disagrees with a row here is a result to check. ASCII defines 128 characters, codes 0–127, using 7 bits; in practice each code is stored in one 8-bit byte with a leading 0.

Percent-Encoding at a glance
AttributeValue
triplet form%HH
hex digits per octet2
unreserved setA-Z a-z 0-9 - . _ ~
gen delims: / ? # [ ] @
sub delims! $ & ' ( ) * + , ; =
text charset before encodingUTF-8
defining specRFC 3986
percent form of space%20
percent form of percent%25
percent form of ampersand%26
percent form of number sign%23
percent form of apostrophe%27
percent form of slash%2F
percent form of colon%3A
percent form of question mark%3F
percent form of equals sign%3D
percent form of plus sign%2B
percent form of left bracket%5B
percent form of right bracket%5D
percent form of at sign%40
unreserved hyphen-
unreserved period.
unreserved underscore_
unreserved tilde~

Worked Example: "hello world" to Percent-Encoding

One character at a time, with the working written out. This is the same grid the converter shows when you turn on "show steps".

h
104
h
e
101
e
l
108
l
l
108
l
o
111
o
32
%20
w
119
w
o
111
o
r
114
r
l
108
l
d
100
d

percent-encoding

Result: hello world = hello%20world

For characters outside US-ASCII, RFC 3986 says to write the text as UTF-8 octets first and then percent-encode every octet that is not in the unreserved set, which is why é becomes %C3%A9.

Read the grid a row at a time: h is 68 and is written h; e is 65 and is written e; l is 6C and is written l. A character that is already unreserved keeps itself, so most of a readable string passes through untouched and only the characters a URL would misread change at all.

é is U+00E9 and encodes as C3 A9 (2 bytes); € is U+20AC and encodes as E2 82 AC (3 bytes); 😀 is U+1F600 and encodes as F0 9F 98 80 (4 bytes). UTF-8 encodes each character in 1 to 4 bytes. Characters 0–127 use one byte identical to ASCII, so ASCII text is valid UTF-8. Those byte counts are what decide how many triplets a character takes, which is why one character can arrive as two triplets and still be one character when it is read back.

Check it in reverse

Decoding reverses the triplets one byte at a time and then reads the resulting bytes as UTF-8, so two triplets can produce a single character. Read the triplets in the order they appear and the original text comes back whole, because an unreserved character was never changed and a triplet always spells exactly one byte. To verify the result by hand, decode the percent-encoded output back to text and compare it with what you started from.

Worked examples: text to percent-encoding

Each example gives the value first, then the working. Click a value to load it in the converter.

What is a space URL encoded?

Text a space in percent-encoding is %20.

Method: write the character as UTF-8 (20) and give each octet a percent sign and two digits.

Load this value in the converter

What is an ampersand URL encoded?

Text an ampersand in percent-encoding is %26.

Method: write the character as UTF-8 (26) and give each octet a percent sign and two digits.

Load this value in the converter

What is a slash URL encoded?

Text a slash in percent-encoding is %2F.

Method: write the character as UTF-8 (2F) and give each octet a percent sign and two digits.

Load this value in the converter

What is e-acute URL encoded?

Text e-acute in percent-encoding is %C3%A9.

Method: write the character as UTF-8 (C3 A9) and give each octet a percent sign and two digits.

Load this value in the converter

What is a number sign in percent-encoding?

Text a number sign in percent-encoding is %23.

Method: write the character as UTF-8 (23) and give each octet a percent sign and two digits.

Load this value in the converter

What is a question mark in percent-encoding?

Text a question mark in percent-encoding is %3F.

Method: write the character as UTF-8 (3F) and give each octet a percent sign and two digits.

Load this value in the converter

What is an equals sign in percent-encoding?

Text an equals sign in percent-encoding is %3D.

Method: write the character as UTF-8 (3D) and give each octet a percent sign and two digits.

Load this value in the converter

What is a plus sign in percent-encoding?

Text a plus sign in percent-encoding is %2B.

Method: write the character as UTF-8 (2B) and give each octet a percent sign and two digits.

Load this value in the converter

What is a colon in percent-encoding?

Text a colon in percent-encoding is %3A.

Method: write the character as UTF-8 (3A) and give each octet a percent sign and two digits.

Load this value in the converter

What is an at sign in percent-encoding?

Text an at sign in percent-encoding is %40.

Method: write the character as UTF-8 (40) and give each octet a percent sign and two digits.

Load this value in the converter

What is an apostrophe in percent-encoding?

Text an apostrophe in percent-encoding is %27.

Method: write the character as UTF-8 (27) and give each octet a percent sign and two digits.

Load this value in the converter

What is "hello world" in percent-encoding?

Text "hello world" in percent-encoding is hello%20world.

Method: write the text as UTF-8 octets and give every octet outside the unreserved set a percent sign and two digits.

Load this value in the converter

Every example above reverses exactly - read the same triplets back as characters.

What Decides Which Characters Get Encoded?

Is the character data or a delimiter?

That is the whole decision, and only you know it. A slash between path segments is a delimiter and stays; a slash inside a value is data and becomes %2F.

What if the value is already Base64?

Then it may not need a triplet at all. The URL-safe alphabet of RFC 4648 section 5 keeps the first 62 characters and swaps plus for minus (-) and slash for underscore (_), so the result passes through a URL or a file name unchanged.

Has the value been through the encoder twice?

A percent sign is itself percent-encoded as %25, so a string that has been through the encoder twice shows %2520 where one space should be.

What case are the hexadecimal digits?

0b marks binary, 0o octal, 0x hexadecimal; a leading # marks a hex colour. Hexadecimal is not case-sensitive (FF = ff); iToolHub writes hex digits in uppercase.

Is this the encoding you need at all?

The three schemes protect different things and are not interchangeable. these encodings are not interchangeable - when percent-encoding is the right choice sets out which does what.

Text to Percent-Encoding in Code

Both standard libraries carry this conversion, so the one-liner below is the whole job. Check the result against the table above before you trust it in a pipeline.

Python: urllib.parse.quote('hello world', safe='')
JavaScript: encodeURIComponent('hello world')

Common Mistakes

Frequently Asked Questions

What is URL encoding?

It is the rule that decides which characters a URL can carry as data. A percent-encoded octet is a triplet: a percent sign followed by the two hexadecimal digits of that byte's value.

Is %20 URL encoding?

Yes. %20 is the percent-encoded form of a space and it is the form this page writes.

Which characters are unreserved in percent-encoding?

The unreserved set — A-Z a-z 0-9 - . _ ~ — and nothing else. Every other character needs a triplet wherever it is data rather than a delimiter.

Should a space become %20 or a plus sign?

Write %20 unless whatever reads the value expects a form's plus convention instead. The two are not interchangeable, so the safe move is to match what the receiving end already does.

How do you URL encode in JavaScript?

encodeURIComponent('hello world') returns hello%20world. Use it for one value; encodeURI leaves the delimiters alone and is for a whole address.

"Can I go back the other way?" Yes. The same value converts straight back in the percent-encoding to text direction.

The rest of the family sits on the full set of text encoding tools.