Overview
When using strings that include non-ASCII characters, spaces, or special symbols as part of a URL, they must be converted into a format that browsers can interpret correctly. This process is known as percent-encoding. This article clarifies the differences between the two standard methods, encodeURI and encodeURIComponent, and provides a practical implementation of a social media share widget that safely handles user input.
Specifications (Input/Output)
Comparison of Methods
Both methods accept a string and return an encoded version, but they differ in the range of characters they escape.
| Method | Meaning / Usage | Characters NOT Encoded (Examples) |
encodeURI(str) | Encodes the entire URL. Protocol and path separators are preserved. | A-Z a-z 0-9 ; , / ? : @ & = + $ – _ . ! ~ * ‘ ( ) # |
encodeURIComponent(str) | Encodes a component of a URL (such as a parameter value). Even separators like / and ? are converted. | A-Z a-z 0-9 – _ . ! ~ * ‘ ( ) |
- Input: String
- Output: Escaped String
Basic Usage
1. Handling the Entire URL (encodeURI)
This method converts characters like Kanji but leaves functional URL symbols (:, /, ?) intact.
const url = 'https://example.com/search/article_page.html';
const encoded = encodeURI(url);
console.log(encoded);
// "https://example.com/search/article_page.html"
// Protocol (https://) and separators (/) remain unchanged.
2. Embedding as Parameter Values (encodeURIComponent)
This method converts even functional symbols like & or = into harmless strings. This is mandatory when creating query parameter values.
const keyword = 'JavaScript & HTML';
const encoded = encodeURIComponent(keyword);
console.log(encoded);
// "JavaScript%20%26%20HTML"
// Space becomes %20, and & becomes %26.
// Example of joining to a URL
const searchUrl = `https://example.com/search?q=${encoded}`;
Full Code Examples
This example creates a share widget where users can input comments, attach hashtags, and open a posting screen for “X” (formerly Twitter). Since we are creating a parameter value (text), encodeURIComponent is used.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Media Share Widget</title>
<style>
.share-widget {
font-family: sans-serif;
max-width: 400px;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
}
.input-area {
width: 100%;
height: 80px;
margin-bottom: 10px;
padding: 8px;
box-sizing: border-box;
}
.btn-share {
background-color: #000;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 20px;
cursor: pointer;
font-weight: bold;
}
.btn-share:hover {
background-color: #333;
}
</style>
</head>
<body>
<div class="share-widget">
<h3>Share your thoughts</h3>
<textarea id="user-comment" class="input-area" placeholder="Enter your comment here..."></textarea>
<button id="btn-post" class="btn-share">Post to X</button>
</div>
<script src="share.js"></script>
</body>
</html>
JavaScript
/**
* Event setup for the share button
*/
const setupShareButton = () => {
const button = document.getElementById('btn-post');
const input = document.getElementById('user-comment');
if (!button || !input) return;
button.addEventListener('click', () => {
// 1. Retrieve input value
const comment = input.value;
// 2. Create the post text (attach fixed hashtags)
const textToShare = comment ? `${comment} #TechLearning` : 'I am learning... #TechLearning';
// 3. URI Encoding process
// Use encodeURIComponent because this is a parameter value
const encodedText = encodeURIComponent(textToShare);
// 4. Construct the share URL
// Format: https://twitter.com/intent/tweet?text=...
const shareUrl = `https://twitter.com/intent/tweet?text=${encodedText}`;
// 5. Open in a new window
window.open(shareUrl, '_blank', 'width=550,height=400');
});
};
// Execute after DOM is loaded
document.addEventListener('DOMContentLoaded', setupShareButton);
Customization Points
- Changing Share Destinations: To send via LINE, you can change the URL schema to
https://line.me/R/msg/text/?${encodedText}. - Including the Current Page URL: You can retrieve
window.location.href, pass it throughencodeURIComponent, and append it as a&url=...parameter to share the article link simultaneously. - Adjusting Window Size: The third argument of
window.openallows you to control the size and features of the popup window, such aswidthandheight.
Important Notes
- Misuse Risks: If you use
encodeURIfor parameter values, symbols like&and=will remain unencoded. This breaks the URL structure and causes parameters to be recognized incorrectly. Always prioritizeencodeURIComponentfor specific values. - Double Encoding: Encoding a string that is already encoded will convert the
%symbol into%25, making it impossible to decode correctly (e.g.,%20becomes%2520). - Deprecated Methods: The
escape()function found in older tutorials is now deprecated. It can cause encoding errors with non-ASCII characters and should never be used in modern development.
Advanced Applications
Batch Generating Query Strings from Objects
Manually joining multiple parameters is tedious. The URLSearchParams object automates the encoding process for you.
const params = {
text: 'Hello World',
hashtags: 'JavaScript,Programming',
url: 'https://example.com'
};
// URLSearchParams automatically performs logic equivalent to encodeURIComponent
const query = new URLSearchParams(params).toString();
console.log(query);
// "text=Hello+World&hashtags=JavaScript%2CProgramming&url=https%3A%2F%2Fexample.com"
Summary
URL encoding is a mandatory process for the safe exchange of data over the web. The general rule is to use encodeURI for constructing entire URLs in rare cases and to use encodeURIComponent for all individual parameter values. Following this principle prevents broken links and data corruption caused by special characters or multi-byte languages. For modern applications, utilizing URLSearchParams is highly recommended to simplify the management of complex query strings.
