Validate a typed name and a consent checkbox, then render the name as SVG text in a script-style font. The image is for display. The typed name, the consent wording, and a timestamp are the record.
function typedSignature(form) {
const name = form.elements.signerName.value.trim();
if (!name) throw new Error("Type your full name to sign.");
if (!form.elements.consent.checked) throw new Error("Check the consent box to sign.");
const esc = name
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
const svg =
'<svg xmlns="http://www.w3.org/2000/svg" width="320" height="80">' +
'<text x="10" y="55" font-family="cursive" font-size="40">' + esc + "</text></svg>";
return {
typedName: name,
svg,
consentText: form.elements.consent.dataset.text,
signedAt: new Date().toISOString(),
};
}The function refuses to run without a name and an explicit consent checkbox. It escapes the name so characters like & and < cannot break the SVG, and it returns the exact consent wording the signer saw next to the typed name and image. Put that wording in a data-text attribute on the checkbox so the stored text always matches what was on screen.
Caveats
Set the timestamp on the server. The client clock is controlled by the user, so treat signedAt as a convenience and overwrite it when the request arrives. Store the typed name and consent text with it, because the image alone does not show what the signer agreed to.
The cursive generic font family resolves to different fonts on different devices, so the same name can look different on a phone and a laptop. If the signature must look identical when stamped onto a PDF, render it once on the server with a font you control and store that result.
Whether a typed name is an acceptable signature for a given document depends on the document type and jurisdiction, so check the requirements for your case before relying on it.
Back to All Questions