ToolsTuna
    Utilities

    URL Encoding Explained: When (and How) to Percent-Encode Your URLs

    May 15, 20265 min read

    Why URLs Need Encoding

    URLs are not allowed to contain arbitrary characters. The spec (RFC 3986) limits them to a small set: letters, digits, and a handful of punctuation marks. Anything outside that set — spaces, accented letters like `é`, CJK characters, emojis, ampersands inside a value, or even a forward slash that's part of data rather than path — has to be **percent-encoded**.

    Percent encoding is simple: take the character's UTF-8 byte representation and write each byte as `%` followed by two hex digits. A space becomes `%20`. A `&` becomes `%26`. The letter `é` (two UTF-8 bytes) becomes `%C3%A9`.

    The Two Functions Everyone Confuses

    JavaScript ships two encoding functions and developers mix them up constantly:

  1. `encodeURI`: assumes you're handing it an entire URL. It encodes unsafe characters but **preserves URL-structure characters**: `/`, `:`, `?`, `#`, `&`, `=`. Use it when you have something like `https://example.com/path with spaces?q=1` and you want the whole URL to remain a valid, navigable URL.
  2. `encodeURIComponent`: assumes you're handing it a single piece of data that will be inserted into a URL — a query value, a path segment, a form field. It escapes **everything** including `/` `?` `&` `=`, because if it didn't, your value could be confused with URL structure.
  3. The rule of thumb: **building a URL from pieces? Use `encodeURIComponent` on each piece. Cleaning up a URL someone gave you? Use `encodeURI`.**

    Our [URL Encoder/Decoder](/url-encoder-decoder) exposes both as "Component" and "Full URL" modes.

    A Concrete Example

    Say you want a URL like:

    ```

    https://api.example.com/search?q=hello & world&lang=en

    ```

    If you naively paste this into a browser, the `&` inside the value `hello & world` will be interpreted as a new query parameter named ` world`. Wrong. The right way is to encode the **value** with `encodeURIComponent`:

    ```

    q = encodeURIComponent("hello & world") // → "hello%20%26%20world"

    url = "https://api.example.com/search?q=" + q + "&lang=en"

    ```

    The final URL is `...?q=hello%20%26%20world&lang=en` — the encoded `&` (`%26`) is now safely part of the value, and the literal `&` between `q` and `lang` correctly separates parameters.

    Decoding: The Mirror Image

    Decoding reverses the process. `%20` becomes a space, `%26` becomes `&`, `%C3%A9` becomes `é`. Two things go wrong most often:

  4. Invalid percent sequences.: A bare `%` not followed by two hex digits, or an incomplete multi-byte UTF-8 character, throws `URIError: URI malformed`. Usually this means the URL was truncated, hand-edited, or already partially decoded.
  5. Double encoding.: A value gets encoded twice somewhere in the pipeline — typically once by client code and again by a framework. The result: `%2520` (which decodes to `%20`, not to a space). Fix is to decode twice.
  6. When Encoding Bites You

    Real-world traps:

  7. Pluses in form data.: Historically, form encoding (`application/x-www-form-urlencoded`) uses `+` for spaces, not `%20`. Most modern code accepts either, but if you see weird `+` characters in decoded output, this is probably why.
  8. Slashes in path segments.: If you have an ID that contains a `/` (rare but it happens — file paths, hierarchical IDs), you **must** `encodeURIComponent` it or it will be parsed as multiple path segments.
  9. Reserved characters in fragments.: The `#` in `example.com#foo` starts the fragment. If you need a literal `#` in your query value, encode it as `%23`.
  10. Plus and space in URLs that go through different parsers.: Some old PHP / Java backends decode `+` to space; modern fetch / Node does not. Test both ends if you're sending data to a system you don't control.
  11. Security Angle

    URLs often carry sensitive data: API keys, OAuth state, signed S3 URLs, session tokens, customer IDs. Online encoder tools that POST your URL to a server can log it, breach it, or leak it through analytics. Look for tools that explicitly process **locally in the browser**.

    Ours does — encoding and decoding both happen via the native `encodeURI` / `decodeURIComponent` APIs in your browser. The URL never leaves your device. You can verify this in your browser's network tab: clicking Encode or Decode triggers exactly one tiny credit deduction request, which contains no URL data.

    A Quick Workflow

    A practical pattern when you're debugging a broken URL:

  12. Paste the URL into the tool, click **Decode** in Component mode. Read what it actually says.
  13. If the decoded version still looks encoded (`%25` appearing in it), click **Swap** and decode again — your value was double-encoded.
  14. Fix the source code that produced the double encoding (usually a misplaced `encodeURIComponent` call inside something that already encodes).
  15. Re-encode the corrected value with the right scope (Component for values, Full URL for whole URLs) and verify.
  16. Conclusion

    URL encoding is one of those topics that looks trivial until it bites you in production with a corrupted query string or a 404 on a path you swore was valid. Once you internalize the distinction between **encoding a value** and **encoding a whole URL**, 90% of the bugs disappear. The other 10% — double encoding, plus-vs-space, fragment edge cases — get easier when you have a fast, local tool to decode and re-encode without round-tripping through a server. Our [URL Encoder/Decoder](/url-encoder-decoder) does exactly that, with both modes one click apart.

    Ready to try it?

    Use our free tool — no signup, no watermarks, no limits.

    Related Articles

    Get in Touch

    Questions, feedback, or partnership ideas? Send us a note.