URL-Safe Base64 Encoding Explained
What URL-safe Base64 is, how it differs from standard Base64, and when to use it — with code examples in JavaScript, Node.js, and Python.
Need to encode URL-safe Base64 right now?
Use the free online tool — toggle the URL-Safe switch for instant conversion.
What is URL-safe Base64?
URL-safe Base64 (also called Base64url, defined in RFC 4648 §5) is a variant of Base64 encoding designed to be safe for use in URLs and file names. It uses the same principle as standard Base64 but swaps out the two characters that are problematic in URLs.
Standard Base64 uses a 64-character alphabet that includes + and /. These characters have special meaning in URLs — plus is decoded as a space in form data, and slash is a path separator. URL-safe Base64 replaces them with - and _, which are safe everywhere in a URL.
Standard Base64 vs URL-safe Base64
| Character | Standard Base64 | URL-Safe Base64 |
|---|---|---|
| + | Plus sign | Hyphen – |
| / | Slash | Underscore _ |
| = | Padding (0–2 chars) | Omitted |
Example: the standard Base64 string SGVsbG8sIFdvcmxkIQ== becomes SGVsbG8sIFdvcmxkIQ in URL-safe form (padding removed, no character substitution needed in this example).
When to use URL-safe Base64
JWT Tokens
JSON Web Tokens use URL-safe Base64 (without padding) for all three of their segments — header, payload, and signature. This lets JWTs be safely embedded in URLs and HTTP headers.
OAuth 2.0 / PKCE
The PKCE extension for OAuth uses URL-safe Base64 to encode the code challenge, which is passed in the query string of the authorization URL.
URL and query parameters
Any Base64 data placed in a URL query parameter must use URL-safe encoding — standard Base64's + and / would be mis-parsed or require %2B and %2F escaping.
File names
Encoding binary IDs or hashes for use in file names is safer with URL-safe Base64 since / would create path separators and cause errors.
Cookie values
HTTP cookies have restrictions on special characters. URL-safe Base64 (without = padding) avoids the most problematic characters in cookie values.
URL-safe Base64 in code
URL-safe Base64 in JavaScript (browser)
The browser doesn't have a native URL-safe Base64 function, but you can convert standard Base64 by replacing characters:
// Encode to URL-safe Base64
function toUrlSafeBase64(str) {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, ''); // remove padding
}
// Decode from URL-safe Base64
function fromUrlSafeBase64(str) {
// Re-add padding if needed
const padded = str + '='.repeat((4 - str.length % 4) % 4);
return atob(padded.replace(/-/g, '+').replace(/_/g, '/'));
}
toUrlSafeBase64("Hello, World!"); // → "SGVsbG8sIFdvcmxkIQ"
fromUrlSafeBase64("SGVsbG8sIFdvcmxkIQ"); // → "Hello, World!"URL-safe Base64 in Node.js
Node.js Buffer supports URL-safe Base64 encoding directly via the 'base64url' encoding:
// Encode to URL-safe Base64 (Node.js 16+)
const encoded = Buffer.from("Hello, World!").toString("base64url");
console.log(encoded); // → "SGVsbG8sIFdvcmxkIQ"
// Decode from URL-safe Base64
const decoded = Buffer.from("SGVsbG8sIFdvcmxkIQ", "base64url").toString("utf8");
console.log(decoded); // → "Hello, World!"
// For older Node.js versions (manual conversion)
const base64 = Buffer.from("Hello, World!").toString("base64");
const urlSafe = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');URL-safe Base64 in Python
Python's base64 module has built-in functions for URL-safe Base64:
import base64
text = "Hello, World!"
# Encode to URL-safe Base64 (uses - and _ instead of + and /)
encoded = base64.urlsafe_b64encode(text.encode("utf-8")).decode("utf-8")
print(encoded) # → SGVsbG8sIFdvcmxkIQ==
# Without padding (common in JWTs and OAuth)
no_pad = encoded.rstrip("=")
print(no_pad) # → SGVsbG8sIFdvcmxkIQ
# Decode (re-add padding before decoding)
padded = no_pad + "=" * (4 - len(no_pad) % 4) % 4
decoded = base64.urlsafe_b64decode(padded).decode("utf-8")
print(decoded) # → Hello, World!Decode a JWT payload
JWT tokens are three URL-safe Base64 segments separated by dots. The payload (second segment) can be decoded directly:
// Decode a JWT payload (browser or Node.js)
function decodeJwtPayload(token) {
const [, payload] = token.split('.');
// Re-add padding
const padded = payload + '='.repeat((4 - payload.length % 4) % 4);
const json = atob(padded.replace(/-/g, '+').replace(/_/g, '/'));
return JSON.parse(json);
}
const token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTcwMDAwMDAwMH0.sig";
console.log(decodeJwtPayload(token));
// → { sub: "user_123", exp: 1700000000 }Quick tip: using the online tool
The Base64 tool on this site has a URL-Safe toggle at the top of the tool. Enable it to automatically switch between standard and URL-safe encoding — existing output re-encodes instantly when you flip the toggle.
Related guides
Try URL-safe Base64 encoding now
Free, instant, and 100% private — nothing is ever uploaded to a server.