Cryonel

URL Encoding and Percent-Encoding Reference

Percent-encoding represents bytes that cannot appear literally in a particular URL component. Build URLs by component, encode once at the boundary, and decode only at the layer that owns that component.

URL components have different rules

https://user@example.com:443/api/users/42?view=full&tag=a#details
└scheme  └authority         └path       └query          └fragment

A character that is structural in one component can be data in another. Slash separates path segments, ampersand commonly separates query fields, and hash begins a fragment. Do not encode a complete URL as if it were one query value. Use a URL builder and set pathname segments, query parameters, and fragment through their appropriate interfaces.

Percent-encoding basics

Percent-encoding writes a byte as % followed by two hexadecimal digits. Non-ASCII text is normally converted to UTF-8 bytes before those bytes are encoded where required. For example, a space is often %20. Hexadecimal letter case may vary, but applications should avoid treating differently cased encodings as different resources.

Path segments

Encode user data as one path segment so embedded slash, question mark, or hash cannot change URL structure. Do not encode path separators that belong to the route itself. Be careful with dot segments, encoded slashes, repeated decoding, and proxy normalization: different layers can interpret them differently and create routing or authorization bypasses. Reject ambiguous encodings at a trusted boundary.

Query parameters

Use a query-parameter API that encodes names and values individually and preserves repeated keys when the contract permits them. Do not concatenate untrusted strings with & and =. Decide how arrays and empty values are represented—repeated keys, comma-separated text, brackets, or another documented convention—and keep clients and servers consistent.

Plus signs and form encoding

application/x-www-form-urlencoded commonly represents a space as plus and a literal plus as %2B. That rule does not mean plus is universally a space in every URL component. A generic percent decoder and a form decoder can therefore produce different results. Use the decoder that matches the producer's documented format.

Avoid double encoding and early decoding

Double encoding changes an existing percent sign into %25, so %2F becomes %252F. Track whether a value is raw data or an encoded component rather than guessing from the presence of percent signs. Decode once at the component boundary. Repeated decoding can turn harmless-looking text into a separator after an authorization decision.

Security and canonicalization

Validate host, scheme, port, and path after parsing with one trusted URL implementation. For redirects and outbound requests, use explicit allowed schemes and destinations. Do not compare raw URL strings for security when equivalent encodings or normalization can differ. Log a safely normalized form without credentials, tokens, or sensitive query values.

Practical examples

Raw dataEncoded component
hello worldhello%20world
a+ba%2Bb
name/emailname%2Femail when it is one segment
cafécaf%C3%A9 in UTF-8 percent-encoding

Encode and inspect components locally with the URL Encoder/Decoder.

Frequently Asked Questions

Should an entire URL be component-encoded?

No. Build it structurally and encode individual values.

Does plus always mean space?

No. That behavior belongs to form-style parsing.

What is double encoding?

Encoding already encoded text, turning percent into %25.

Related Tools and Guides