Javascript is required
PitfallsPublished 2026-07-28Updated 2026-08-085 min read

encodeURI vs encodeURIComponent: When to Use Each

JavaScript provides two built-in URL encoding functions: encodeURI and encodeURIComponent. Confusing them leads to truncated query parameters, broken route parsing, or HTTP 400 Bad Request errors. This article breaks down RFC 3986 reserved characters and proper usage scenarios.

By: Tiny
URL EncodeencodeURIencodeURIComponentJavaScript

1. Problem: reserved character encoding differences

RFC 3986 defines reserved characters (e.g., :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ;, =). encodeURI encodes full URIs while preserving structural delimiters (https://, ?); encodeURIComponent encodes individual query keys or values, percent-encoding reserved delimiters (%XX).

2. Minimal reproduction: misusing encodeURI on query parameter values

When a parameter value contains & or = (such as a redirect target URL), using encodeURI leaves & unescaped, causing server parsers to misinterpret it as multiple query parameters.

const redirectTarget = "https://site.com/login?ref=123&lang=cn";

/* Wrong: using encodeURI on a query parameter value leaves & unescaped */
const wrongUrl = "https://api.example.com/redirect?target=" + encodeURI(redirectTarget);
// Result retains raw &: https://api.example.com/redirect?target=https://site.com/login?ref=123&lang=cn

/* Correct: using encodeURIComponent on the parameter value */
const correctUrl = "https://api.example.com/redirect?target=" + encodeURIComponent(redirectTarget);
// Result percent-encodes reserved characters: https://api.example.com/redirect?target=https%3A%2F%2Fsite.com%2Flogin%3Fref%3D123%26lang%3Dcn

3. Root cause: URI structural parsing and character sets

URIs consist of Scheme, Authority, Path, Query, and Fragment. encodeURI assumes full URI inputs and preserves URI syntax delimiters. encodeURIComponent assumes component fragment inputs, percent-encoding any character that could disrupt URI syntax.

4. Recommendation: layer-by-layer encoding architecture

1. Full URL structure: use encodeURI or native new URL(). 2. Query parameter key/value: use encodeURIComponent or URLSearchParams. 3. Dynamic path segments: encode segments individually with encodeURIComponent before joining with /.

5. Complete code: layered safe URL builder function

This TypeScript function applies proper encoding strategies to full URL frameworks, path segments, and query parameters separately.

function safeBuildUrl(baseUrl: string, pathSegment: string, queryParams: Record<string, string>): string {
  const encodedPath = pathSegment.split("/").map(encodeURIComponent).join("/");

  const queryParts: string[] = [];
  for (const [key, val] of Object.entries(queryParams)) {
    const safeKey = encodeURIComponent(key);
    const safeVal = encodeURIComponent(val);
    queryParts.push(safeKey + "=" + safeVal);
  }

  const queryString = queryParts.join("&");
  const cleanBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
  const fullRawUrl = cleanBase + "/" + encodedPath + "?" + queryString;
  return encodeURI(fullRawUrl);
}

console.log(safeBuildUrl("https://api.example.com", "v1/user info", { search: "a&b=c", redirect: "https://site.com?id=1" }));
// Space in path becomes %20, & and = in query are safely percent-encoded

6. Incorrect approaches

Calling encodeURIComponent directly on a full URL string containing ?key=value (destroying https:// and ?). Using encodeURI on query parameter values (leaking delimiters).

7. Boundaries: single quotes, tildes, and Unicode characters

Neither encodeURI nor encodeURIComponent encodes ', !, (, ), *, or ~. Replace single quotes and parentheses manually if servers strictly validate RFC 3986.

8. Verification

Assert that new URL(url).searchParams.get(key) restores the original value. Cover &, =, ?, /, #, %, spaces, and Unicode, then verify a real client/server round trip uses the same encoding rules.

9. FAQ

Which has better performance, encodeURI or encodeURIComponent? Performance is identical; the difference lies in character set definitions.

Why prefer URLSearchParams over manual encodeURIComponent? URLSearchParams handles key/value encoding and space/+ rules automatically.

When should escape() be used? Never; escape() is a deprecated API that fails on Unicode characters.

10. Summary

Follow clear boundaries: use encodeURI or new URL() for full URL frameworks, and encodeURIComponent or URLSearchParams for individual query components.

Sources and further reading

Specifications and references for checking the article’s technical details.

Related articles

Keep exploring

Use the related browser tool to test the workflow with your own sample data.

Open related tool