Base64 Encoding JSON: When and Why You'd Actually Need It

Tutorial5 min read

Base64-encoding JSON comes up more often than you'd expect — but it has a sharp edge that catches almost everyone the first time: plain btoa() breaks the moment your data has an emoji in it.

1. Common Reasons to Base64-Encode JSON

Three cases come up constantly: passing structured data through a URL query parameter (raw JSON's braces and quotes aren't URL-safe), the payload section of a JWT, and squeezing structured data into a field or system that only accepts plain text.

2. Why Plain btoa() Breaks on Unicode

JavaScript's btoa() only handles single-byte (Latin1) characters. The moment your JSON contains an emoji, accented letters, or CJK text, it throws InvalidCharacterError. The fix is to UTF-8 encode the string first, then Base64-encode the resulting bytes — not the raw string.

3. The UTF-8-Safe Encode/Decode Pattern

The reliable version is: btoa(unescape(encodeURIComponent(str))) to encode, and decodeURIComponent(escape(atob(str))) to decode. It's an odd-looking pair of function calls, but it correctly round-trips any Unicode content, not just ASCII.

4. Base64 Is Encoding, Not Encryption

Anyone can decode a Base64 string in one line — it provides zero confidentiality. If the JSON contains anything sensitive, encrypt it before encoding; don't rely on Base64 to hide the contents.

5. Handle Decode Failures Gracefully

Input from users or URLs can be malformed — not valid Base64, or valid Base64 that doesn't decode to valid JSON. Wrap the decode-then-parse step in a try/catch and fail with a clear error message rather than letting an uncaught exception take down the page.