Define the response contract, collect text fields safely, and narrow success and failure results before updating the page.
Type contract
Record<string, string>
Only named text values are added to the request data.
POST
success: true
Use returned data
success: false
Show the message
Typed implementation
SmartFormify returns JSON with a success flag, message, and response data. Model that payload as a discriminated union before using success-only fields.
Typed fetch request
typescript
This example narrows the JSON returned by SmartFormify and exposes typed data only after the endpoint accepts the submission.
type EndpointSuccess = {
success: true;
message: string;
data: {
submission_id: string;
redirect_url: string | null;
thank_you_content: string;
};
};
type EndpointFailure = {
success: false;
message: string;
data: Record<string, never>;
};
type EndpointResult = EndpointSuccess | EndpointFailure;
const ENDPOINT_URL = "https://api.smartformify.com/fe/YOUR_ENDPOINT_KEY";
function getTextFields(form: HTMLFormElement): Record<string, string> {
const fields: Record<string, string> = {};
new FormData(form).forEach((value, key) => {
if (typeof value === "string") fields[key] = value;
});
return fields;
}
async function submitForm(form: HTMLFormElement) {
const response = await fetch(ENDPOINT_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data: getTextFields(form) })
});
const result = (await response.json()) as EndpointResult;
if (!response.ok || !result.success) {
throw new Error(result.message || "Submission failed.");
}
return result.data;
}Convert supported FormData values to a record of text fields.
Model success and failure with a shared success discriminator.
Throw before reading success-only response properties.
Before launch
Types describe expected data at build time. The page must still handle failed requests and unexpected network conditions.