/** * Encodes values to be used in mailto protocol. * * Note that we cannot simply use URLSeachParams because they, for example, encode a space * as plus (+), which cannot be used in mailto if we want to have consistent behaviour in * all email clients. */ function encodeValuesForMailto(object: T) { return Object.entries(object) .filter(([_, v]) => !!v) .map(([key, value]) => `${key}=${encodeURIComponent(value)}`) .join("&"); } function serializeArray(value?: string | string[] | null) { return Array.isArray(value) ? value.join(",") : value; } type MailtoPayload = { body?: string | null; subject?: string | null; cc?: string | string[] | null; bcc?: string | string[] | null; }; export function mailto(recipient: string | null, payload?: MailtoPayload) { // If the recipient is falsy the user can choose who to send the email to. const to = recipient ?? ""; const serialized = payload ? `?${encodeValuesForMailto({ body: payload.body, subject: payload.subject, cc: serializeArray(payload.cc), bcc: serializeArray(payload.bcc), })}` : ""; return `mailto:${to}${serialized}`; }