Decode Base64 Angular: Encoding and Decoding in Angular Apps
Angular has no Base64 helper of its own; you use the browser APIs. What Angular adds is a sanitizer, and it cares much more about where a decoded file is displayed than about the Base64 itself.
Encoding and decoding
The browser built-ins work as usual, wrapped in a service for reuse. Handle Unicode explicitly, since btoa throws above U+00FF:
@Injectable({ providedIn: 'root' })
export class Base64Service {
encode(value: string): string {
return btoa(String.fromCharCode(...new TextEncoder().encode(value)));
}
decode(value: string): string {
return new TextDecoder().decode(
Uint8Array.from(atob(value), (c) => c.charCodeAt(0))
);
}
}
The sanitizer
Current Angular versions strip only javascript: URLs from [src] and [href] bindings, so <img [src]="'data:image/png;base64,' + b64"> renders without any help. Many tutorials, written for older releases, still wrap image data URIs like this:
constructor(private sanitizer: DomSanitizer) {}
imageUrl(b64: string): SafeUrl {
return this.sanitizer.bypassSecurityTrustUrl(
'data:image/png;base64,' + b64
);
}
Where a bypass is genuinely needed is a resource URL. Binding a decoded PDF to <iframe [src]> or <object [data]> fails with "unsafe value used in a resource URL context" until the value goes through bypassSecurityTrustResourceUrl. Both bypass methods switch off Angular's XSS protection for that value, so never pass user-supplied strings through them: a data:text/html payload in an iframe is executable markup.
Decoding a JWT payload
JWT segments are base64url, so translate the alphabet and restore padding before decoding:
decodeJwtPayload(token: string): unknown {
const part = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
const padded = part.padEnd(part.length + ((4 - (part.length % 4)) % 4), '=');
return JSON.parse(this.decode(padded));
}
This reads the claims; it does not verify the signature. Never make an authorisation decision in the browser based on a decoded token — the server must verify it.
Frequently asked questions
Why is my Base64 image or PDF blank?
For images it is rarely the sanitizer, which lets `data:image/…` URLs through; check that the MIME type matches the file and that the string was not cut off. A PDF in an iframe does need `bypassSecurityTrustResourceUrl`, and only for values your app generated.
Do I need a Base64 npm package?
No. atob and btoa cover it; add a TextEncoder step for Unicode.
Is decoding a JWT in Angular safe?
Reading claims for display is fine. Trusting them for access control is not — only the server can verify the signature.