--- import Layout from '../layouts/Layout.astro'; import ContactForm from '../components/react/ContactForm'; interface ContactLink { kind: string; label: string; value: string; } interface SiteConfig { contact_intro?: string; contact_links?: ContactLink[]; } const API_URL = process.env.PUBLIC_API_URL || 'http://localhost:3000'; let siteConfig: SiteConfig = {}; let error = ''; try { const res = await fetch(`${API_URL}/api/config`); if (res.ok) { siteConfig = await res.json(); } else { error = 'Failed to load contact details.'; } } catch (e) { error = `Could not connect to backend: ${e instanceof Error ? e.message : String(e)}`; console.error(error); } const links: ContactLink[] = siteConfig.contact_links ?? []; const intro = siteConfig.contact_intro ?? ''; const KIND_LABEL: Record = { email: 'Email', mastodon: 'Mastodon', bluesky: 'Bluesky', github: 'GitHub', instagram: 'Instagram', url: 'Link', }; function b64(s: string): string { return Buffer.from(s, 'utf-8').toString('base64'); } function obfuscateEmail(addr: string): { user: string; host: string; display: string; u64: string; h64: string } | null { const at = addr.indexOf('@'); if (at === -1) return null; const user = addr.slice(0, at); const host = addr.slice(at + 1); const display = `${user} [at] ${host.replace(/\./g, ' [dot] ')}`; return { user, host, display, u64: b64(user), h64: b64(host) }; } ---
Correspondence

Get in touch

{intro && (

{intro}

)}
{error && (

{error}

)} {links.length > 0 && ( )}

Or send a note directly