/** * Email addresses kept out of the served HTML. * * Address harvesters read raw HTML and do not run scripts. The server writes * the address reversed and base64-encoded; components/EmailLink.tsx decodes * it in the browser, so visitors and screen readers get a normal, clickable * address. The plain address appears neither in the HTML nor in the RSC * payload, because only the encoded form is ever passed to the client. * * This is not encryption: anyone running a browser gets the address. It only * has to defeat bulk harvesting. Client-safe, no Node APIs. */ function toBase64(text: string): string { let binary = ''; for (const byte of new TextEncoder().encode(text)) binary += String.fromCharCode(byte); return btoa(binary); } function fromBase64(encoded: string): string { const binary = atob(encoded); return new TextDecoder().decode(Uint8Array.from(binary, (c) => c.charCodeAt(0))); } export function encodeEmail(email: string): string { return toBase64([...email].reverse().join('')); } export function decodeEmail(encoded: string): string { try { return [...fromBase64(encoded)].reverse().join(''); } catch { return ''; } } /** * The no-script fallback, "name [at] example [dot] com". Weaker than the * encoded form, but it keeps the address reachable for a visitor without * JavaScript, which ยง 5 DDG asks of the Impressum. */ export function spelledOutEmail(email: string): string { return email.replace('@', ' [at] ').replace(/\./g, ' [dot] '); }