URL encode

Paste a string and get it percent-encoded for use in a URL. The one decision that matters is offered as a choice rather than guessed at: whether you are encoding a value that goes inside a URL, or a whole URL whose slashes and question marks are structure and must survive. Getting that backwards produces an address that looks right and resolves somewhere else.

A value escapes ? & = / and #. A whole URL keeps them, because there they are structure.

Result

The answer appears here as you type.

  • Where it runs

    Nothing is uploaded, because there is no file — it is worked out in this page.

  • No queue, no account

    It answers as fast as your machine can, and it never asks who you are.

  • As often as you like

    Nothing is counted and nothing is capped — answering again costs us nothing.

How it works

  1. Paste the text into the box.
  2. Say what it is — a value inside a URL, or a whole URL. This is the choice that decides whether ? and & are escaped.
  3. Copy the result. Nothing was uploaded.

The only question this tool asks, and why it asks it

A URL is made of parts, and the characters that separate them — `/`, `?`, `&`, `=`, `#` — are structure when they are doing that job and data when they are not. Encoding a whole address has to leave them alone or the address stops being one. Encoding a single value has to escape them, or the value ends and something else begins.

This is exactly the difference between `encodeURI` and `encodeURIComponent`, and it is the mistake behind most broken redirect parameters on the web: a `?return=https://example.com/a?b=c` where the second question mark was never escaped, so everything after it belongs to the outer URL instead. The result is a link that works in testing, where the target has no query string, and fails in production, where it does.

Percent-encoding carries bytes, not characters

A percent sequence is `%` followed by two hexadecimal digits, and it names one byte. Characters outside ASCII take several: `ü` is `%C3%BC`, not `%FC`, because UTF-8 spells it in two bytes. An emoji takes four sequences.

The old `escape()` function produced `%FC` and is deprecated for precisely that reason — it predates the decision that the web is UTF-8. Its output still appears in older code and in some legacy APIs, where it will decode to the wrong character on anything but a Latin-1 backend. Everything here is UTF-8.

The five characters that catch out request signing

`encodeURIComponent` leaves `!`, `'`, `(`, `)` and `*` unescaped. RFC 3986 lists them as reserved, so a strictly conforming encoder escapes them, and the two therefore disagree on five characters that appear in ordinary text all the time.

Nobody notices until a signature is involved. OAuth 1.0 and AWS Signature Version 4 both compute a hash over the encoded string, so a single unescaped apostrophe changes the hash and the request is rejected — with an error about credentials, which sends you looking in entirely the wrong place. The strict option here escapes all five.

Spaces: %20, or a plus sign

Both appear and they are not the same rule. `%20` is percent-encoding and is correct everywhere in a URL. The plus sign comes from `application/x-www-form-urlencoded`, the format an HTML form posts in, where a space is written as `+` — a convention that predates the modern specification and survives because forms do.

In a path, `+` is a literal plus. In a query string, most servers read it as a space because that is what the form encoding says, which means a genuine plus in a query value has to be written `%2B` or it will vanish. This encoder emits `%20`, which is unambiguous in both places.

Encoding twice, and how to spot it

Percent-encoding an already-encoded string escapes the `%` itself, so `%20` becomes `%2520`. That is not an error to any component involved — it is a perfectly valid encoding of the literal text "%20" — which is why double encoding survives all the way to the point where a user sees `Hello%20world` in a heading.

The tell is a `%25` where a `%` should be. If you see one, something in the chain is encoding a value that was already encoded, usually because a framework does it for you and a template does it again. The fix is to remove one of them rather than to decode twice at the far end.

URL encode: common questions

Should I encode the whole URL or just the value?

Just the value, almost always. Encoding a whole URL is for the rare case where you have an address containing a space or a non-ASCII character and need it made legal without disturbing its structure. If you are building a query string, each value is encoded separately and the & and = between them are not.

Why is a space sometimes %20 and sometimes +?

Because `+` comes from HTML form encoding rather than from URLs themselves. Servers reading a query string usually accept both, but only `%20` is correct in a path, and only `%20` is unambiguous — a literal plus in a query value has to be written as %2B or it will be read as a space.

Does it handle accents, Cyrillic and emoji?

Yes, as UTF-8, which is what the modern web specifies. One character can become several percent sequences: ü is %C3%BC and an emoji is four sequences. The older escape() function produced a single byte instead and gets this wrong for everything outside Latin-1.

What is the strict option for?

Request signing. OAuth 1.0 and AWS SigV4 hash the encoded string, and the ordinary encoder leaves five characters — an exclamation mark, an apostrophe, both brackets and an asterisk — unescaped where RFC 3986 says they should not be. One of them in your data changes the hash and the request is rejected, usually with an unhelpful error about credentials.

Is my text sent to a server?

No. It is encoded in this page and nothing is uploaded, which you can confirm in the network panel. The values people encode are often search terms, identifiers and redirect targets — none of that needs to travel to be escaped.

Other tools