URL Encoding Explained: A Percent-Encoding Reference

Why URLs need percent-encoding, the difference between encoding a component and a whole URL, a reference table for the characters that matter, and the + vs %20 question settled.

Published 2026-10-23

A URL can only contain a small, safe set of characters — but the data you want to put in one (search queries, file names, redirect targets) contains everything else. Percent-encoding is the bridge: every unsafe byte becomes % followed by two hex digits. This is the reference for doing it correctly: which characters must be encoded, when, and in which of the two modes. To encode or decode something right now, use our URL encoder / decoder.

Why encoding exists

A URL is parsed by structure: ? starts the query, & separates parameters, # starts the fragment, / separates path segments. If your data itself contains those characters, the parser can’t tell structure from content. Searching for the string fish & chips? inside ?q=fish & chips? breaks into nonsense. Encoding the data — ?q=fish%20%26%20chips%3F — removes the ambiguity: structural characters appear literally, data characters appear encoded, and the two never collide.

Three classes of character matter:

The reference table

The characters you will actually meet, as data:

CharacterEncodedCharacterEncoded
space%20 (or + in query strings — see below)&%26
%%25=%3D
?%3F#%23
/%2F+%2B
:%3A@%40
"%22< / >%3C / %3E
newline%0Atab%09

Non-ASCII characters are encoded byte-by-byte as UTF-8: é is the two bytes C3 A9, so it becomes %C3%A9; the character 猫 is %E7%8C%AB. If you ever see a single %E9 for é, you’re looking at legacy Latin-1 encoding — one of the classic mojibake recipes.

The two modes: component vs full URL

This is where most bugs live. There are two legitimate things to encode, and they are not interchangeable:

Use the wrong one and you get one of two failures: encoding a whole URL in component mode produces %3A%2F%2F soup that no server recognises; encoding a value in full-URL mode lets a stray & in someone’s search term silently split your parameter in two. Our encoder offers both modes side by side for exactly this reason.

The + vs %20 question

In the query string only, a space may also be written as +. This is a fossil of application/x-www-form-urlencoded — the format HTML forms submit — where spaces become + and a literal plus sign must therefore be encoded as %2B. Rules of thumb:

Decoders that ignore this distinction are why “C++” keeps arriving at servers as “C ”.

Worked example

Build a search URL for the query tomato & basil "fresh", step by step:

  1. Raw value: tomato & basil "fresh"
  2. Component-encode it: tomato%20%26%20basil%20%22fresh%22
  3. Assemble: https://example.com/search?q=tomato%20%26%20basil%20%22fresh%22&page=1

The structure (?, &, =) stayed literal because we encoded the value, then built the URL around it — the order of operations that prevents almost every encoding bug.

Decoding errors to recognise

Related tools