How to URL encode — step by step
- Pick a mode — Encode or Decode.
- Pick a variant that matches your target: query value (
encodeURIComponent), full URL (encodeURI), RFC 3986 strict, or form data (application/x-www-form-urlencoded). - Paste your text into the input box. The result appears automatically after 150 ms.
- Click Copy to copy the output to your clipboard.
- Use Swap to flip the output back into the input and reverse the mode — handy for round-trip checks to confirm the original string is recovered.
URL encoder — copy and paste examples
Paste any of the inputs below into the encoder and select the matching variant to see the output. These cover the most common real-world encoding scenarios.
| Input | Variant | Encoded output |
|---|---|---|
hello world | encodeURIComponent | hello%20world |
name=Ada&role=admin | encodeURIComponent | name%3DAda%26role%3Dadmin |
https://example.com/path?q=hello world | encodeURI | https://example.com/path?q=hello%20world |
café au lait | encodeURIComponent | caf%C3%A9%20au%20lait |
search term | form-urlencoded | search+term |
C++ | encodeURIComponent | C%2B%2B |
price: $20 & tax | encodeURIComponent | price%3A%20%2420%20%26%20tax |
To decode, paste the percent-encoded string (e.g. hello%20world), switch to Decode mode, and the original text appears.
Which variant should I use?
Picking the wrong variant causes half the "mystery" URL bugs in production. Here's the decision guide:
encodeURIComponent (default) — for a single value
Use this when you're encoding a value that will be placed inside a URL — a query-string value,
a path segment, or a header. It encodes every character that has special meaning in URLs (/ : ? # & = +),
which is exactly what you want for a value. This is the right default almost always.
const params = new URLSearchParams();
params.set('q', userInput);
fetch('/search?' + params); // URLSearchParams does encodeURIComponent for you
encodeURI — for an entire URL
Use this when you have a full URL and want to escape only the truly illegal characters
(spaces, non-ASCII) while leaving the URL structure (/, ?, #,
&, =) intact. Rare — most of the time you're building URLs from parts, not
escaping whole URLs. If you're tempted to use this to encode a query value, you're almost certainly wrong.
RFC 3986 strict
Stricter than encodeURIComponent. Also encodes !, *,
', (, ) — characters RFC 3986 marks as "sub-delims" that
some parsers treat as special. Use this when you need maximum compatibility with strict URI parsers
(some older OAuth flows, some XML-based APIs).
application/x-www-form-urlencoded
Used in HTML <form> submissions with method="POST" and the default
enctype. The one meaningful difference from encodeURIComponent: spaces become
+ instead of %20. If you're building form bodies manually (no
URLSearchParams), use this. In decoder mode, this option treats + as space.
What does percent-encoding actually do?
Every character becomes %XX where XX is the hex value of its UTF-8 byte(s).
ASCII characters below 128 take one byte (e.g., space = %20). Non-ASCII characters take
2–4 bytes (e.g., é = %C3%A9, the UTF-8 bytes of U+00E9).
The set of characters that get encoded depends on the variant — that's all the variants do differently. The encoding math is identical; the "character allowlist" is what changes.
RFC 3986 defines 66 "unreserved" characters that are never encoded: A–Z, a–z,
0–9, -, _, ., and ~. Everything else
is fair game depending on context. For the full specification, see the
percent-encoding RFC 3986 explainer.
When to use URL encoding
URL encoding is required any time user-controlled text crosses a URL boundary:
- Search queries: Encode the search term before appending it to
?q=. Without encoding, a query likerock & rollbreaks the parameter structure. - User-generated slugs: File names, usernames, or titles with spaces or special characters must be encoded in path segments.
- OAuth and API authentication: Many OAuth 1.0a signature base strings require RFC 3986 strict encoding of the entire request URL.
- Redirect targets: When a URL is passed as a parameter to a redirect endpoint (e.g.,
?next=/dashboard), the value must be encoded so its slashes aren't parsed as the outer URL's path. - Form submissions: HTML forms use
application/x-www-form-urlencodedby default — the browser handles it, but when building form bodies in code you need to encode manually. - International and emoji content: Any non-ASCII text in URLs — language content, emoji in UTM parameters, CJK characters in file paths — must be percent-encoded as UTF-8 bytes.
- Webhook payloads and callback URLs: When passing a callback URL as a query parameter, always
encodeURIComponentthe full callback URL string.
Common URL encoding bugs
Double-encoding
The most common bug. Something encodes once, then a middleware or framework encodes the output again.
Result: %20 becomes %2520, and the %20 decoded once says "20"
instead of a space. If you see %25 pairs mysteriously appearing, you're double-encoding.
See the full post: double URL encoding — causes and fixes.
Using encodeURI for a query value
encodeURI("a&b=c") returns a&b=c unchanged — because &
and = are "valid" in a URL. Your server then parses two query params (a and
b) instead of one. Use encodeURIComponent for values, always.
Plus becomes space (or doesn't)
In the query string of a URL, + is a literal plus sign. But in an
application/x-www-form-urlencoded body, + is a space. Servers treat them
differently depending on whether they're parsing the URL or the body. This is why you see PHP's
urldecode (form style) vs rawurldecode (URL style).
Forgetting to encode the fragment
Everything after # in a URL is the fragment. Browsers encode fragments differently from
query strings — ? and & are allowed unescaped, but #
itself must be encoded. Get this wrong and deep-linked SPAs with # in state break.
For a complete field guide to all seven common URL encoding bugs, see URL encoding bugs that break your API.
URL encoding by language
The encoder above handles ad-hoc encoding, but here are the idiomatic approaches in code:
- JavaScript: Use
encodeURIComponent(value)for values;new URLSearchParams(obj)for query strings. See URL encoding in JavaScript. - Python: Use
urllib.parse.quote(value)for path segments;urllib.parse.urlencode(dict)for query strings. See URL encoding in Python. - curl: Pass
--data-urlencode 'key=value'for POST; use-G --data-urlencodefor GET query params. See URL encoding in curl.
Frequently asked questions
Why are some characters never encoded?
RFC 3986 defines "unreserved" characters that always stay literal: A-Z, a-z,
0-9, -, _, ., and ~. These are safe in
every URL context, so no encoder touches them. Everything else depends on context and the variant.
Is %20 the same as + for a space?
Only in specific contexts. In query strings, %20 = space and + = literal plus. In form-encoded bodies,
+ = space and %2B = literal plus. Match your encoder to your consumer — never assume.
Does this tool handle non-ASCII and emoji correctly?
Yes. The tool uses JavaScript's native encodeURIComponent / decodeURIComponent,
which always operate on UTF-8 bytes. You can paste CJK characters, Arabic, emoji, or any Unicode and the encoded output is valid percent-encoded UTF-8.
Why did my decode fail with "URI malformed"?
You have an invalid escape sequence. Usual cause: an unescaped % that isn't followed by two hex digits (e.g., a literal % sign in a URL). Fix it by encoding the bare % as %25 before passing it to a decoder.
What is the difference between URL encoding and Base64?
URL encoding (%XX) makes individual characters safe for use inside a URL. Base64 encoding converts arbitrary binary data into a printable ASCII string — it's used for embedding data in HTML, JSON, or email headers, not for URL safety. They solve different problems; sometimes both are used together (Base64-encode binary, then URL-encode the result for a query param).
Related tools
- JSON Formatter — Format, validate, and beautify JSON online. 100% client-side — your data never leaves your browser.
- Base64 Encoder / Decoder — Encode and decode Base64 strings and files. Client-side, safe for sensitive data.
- JWT Decoder — Decode and inspect JSON Web Tokens. Local-only — tokens never leave your browser.
- Hash Generator — Generate MD5, SHA-1, SHA-256, and SHA-512 hashes client-side.
- Hash Generator — MD5, SHA-1, SHA-256 and more
- Email & URL Extractor — pull URLs out of any text block
Related articles
- 4 min readDouble URL Encoding — What It Is, Why It Happens, and How to Prevent ItDouble URL encoding happens when an already-encoded URL is encoded again, turning %20 into %2520. Learn how to detect it, prevent it in APIs and proxies, and why attackers...
- 4 min readURL Canonicalization — Normalize URLs for APIs, Caching, and SEOURL canonicalization normalizes URLs to a consistent form, removing redundant parameters, encoding differences, and trailing slash inconsistencies. Learn how to canonicalize...
- 4 min readURL Encoding in curl — --data-urlencode, -G, and Query String Tipscurl handles URL encoding in multiple ways depending on the request type. Learn how to use --data-urlencode for POST forms, -G for GET query parameters, encode URLs in shell...
- 5 min readURL Encode Decode — Encode and Decode URLs OnlineURL encoding converts special characters to percent-encoded sequences (%20 for space, %2F for slash). Here's when to encode, what gets encoded, and the difference between...
- 4 min readURL Encoding in Python — urllib.parse, requests, and FastAPIPython's urllib.parse module provides quote, quote_plus, and urlencode for URL encoding. Here's how to encode URLs and query strings correctly in Python, requests library, and...
- 4 min readURL Encoding in JavaScript — encodeURIComponent vs encodeURIJavaScript has two URL encoding functions: encodeURI for full URLs and encodeURIComponent for individual components. Learn the difference, when to use each, how to encode query...
Part of the Encoding & Crypto pillar
This tool is part of the Encoding & Crypto collection — Base64, URL, JWT, hashes, UUID, QR codes, and password generation, all running client-side with no data sent to a server.
Written and maintained by Mian Ali Khalid. Last updated 2026-05-12.