The Shack Developer Tips URL Encoding Explained

URL Encoding Explained: Why Your URLs Break and How to Fix Them

Back to All Posts

You've built a search feature, passed a query string in a URL, and watched it silently break because someone typed an ampersand or a space. Or you've hit an API endpoint and gotten a 400 error because a parameter value had a slash in it. URL encoding — or the lack of it — is the culprit almost every time.

The URL Encoder/Decoder at DevToolShack encodes and decodes any string instantly, right in your browser. But understanding why encoding is needed will save you hours of debugging.

Why URLs Need Encoding

URLs are restricted to a specific set of ASCII characters. Characters outside this safe set — spaces, accented letters, emoji, most punctuation — must be converted into a format the URL can safely carry. Without encoding, these characters either get stripped, misinterpreted, or cause the URL to be parsed incorrectly.

The mechanism is called percent-encoding: each unsafe character is replaced by a % followed by its two-digit hexadecimal ASCII code.

space  →  %20
&      →  %26
=      →  %3D
+      →  %2B
/      →  %2F
?      →  %3F
#      →  %23
@      →  %40

Safe vs Unsafe Characters

CategoryCharactersEncoding needed?
Unreserved (always safe)A-Z a-z 0-9 - _ . ~Never
Reserved (structural): / ? # [ ] @ ! $ & ' ( ) * + , ; =When used as data, not structure
Everything elseSpaces, accents, emoji, symbolsAlways

The reserved characters are the tricky ones. A / in a URL path is structural — it separates path segments. But if your data contains a slash (a file path, a date like 2025/10/13), you must encode it as %2F or it will be treated as a path separator.

The Two Functions You Need in JavaScript

JavaScript has two pairs of encoding functions and it matters which you use:

// encodeURI — encodes a full URL, leaves structural characters alone
encodeURI("https://example.com/search?q=hello world&lang=en");
// "https://example.com/search?q=hello%20world&lang=en"
// Note: & and = are NOT encoded — they're part of the URL structure

// encodeURIComponent — encodes a value, including structural characters
encodeURIComponent("hello world & more");
// "hello%20world%20%26%20more"
// Note: & IS encoded — this is for encoding parameter VALUES
The #1 mistake: Using encodeURI on a query parameter value. Because it doesn't encode & and =, any value containing those characters will corrupt your query string. Always use encodeURIComponent for parameter values.

Building Query Strings Safely

The safest way to build query strings in JavaScript is with URLSearchParams — it handles encoding automatically:

const params = new URLSearchParams({
  q: "hello world & more",
  category: "dev/tools",
  page: 1
});

const url = `https://example.com/search?${params}`;
// "https://example.com/search?q=hello+world+%26+more&category=dev%2Ftools&page=1"

Note that URLSearchParams encodes spaces as + (application/x-www-form-urlencoded format) rather than %20. Most servers accept both, but if your API requires %20, use encodeURIComponent manually.

Decoding URLs

To decode, use the matching decode functions:

decodeURI("https://example.com/search?q=hello%20world");
// "https://example.com/search?q=hello world"

decodeURIComponent("hello%20world%20%26%20more");
// "hello world & more"

When debugging a broken URL — especially one you've received from a third party or pulled from a log file — paste it into the URL Encoder/Decoder to instantly see the decoded form. Much faster than reading percent-codes manually.

Common Encoding Issues

SymptomLikely CauseFix
Query parameter value gets truncatedUnencoded & in value starts a new parameterencodeURIComponent(value)
Space in URL becomes + or breaksSpaces are not URL-safeEncode as %20 or +
Path segment treated as directoryUnencoded / in dataEncode as %2F
Fragment ignoredUnencoded # in parameter valueEncode as %23
Non-ASCII characters cause 400 errorsAccented letters, emoji not encodedencodeURIComponent() handles all of these

URL Encoding in Other Languages

# Python
from urllib.parse import quote, quote_plus, urlencode

quote("hello world & more")          # 'hello%20world%20%26%20more'
quote_plus("hello world & more")     # 'hello+world+%26+more'

# Building a full query string
urlencode({"q": "hello world", "page": 1})
# 'q=hello+world&page=1'
# PHP
urlencode("hello world & more");     // 'hello+world+%26+more'
rawurlencode("hello world & more");  // 'hello%20world%20%26%20more'

# Building query strings
http_build_query(["q" => "hello world", "page" => 1]);
// 'q=hello+world&page=1'
Quick decode workflow: Got a long encoded URL from a redirect, an API log, or an email link? Paste it into the URL Encoder/Decoder and hit Decode. You'll see the human-readable form instantly — great for debugging OAuth flows, webhook payloads, and tracking parameters.