Job application form you can copy
Change the positions in the list, or describe the role in the box: “Application for a barista, with weekend availability and a link to a CV”. The HTML tab is selected. React and Vue tabs write the same fields for a careers page built with them.
Fields, no AI
Live preview
Preview only. Nothing is sent from this page.
Apply for this job
Copy the code
Replace fk_your_access_key with your own Formgong access key. The placeholder does not accept submissions. The honeypot field is named botcheck. Leave it empty.
The HTML form posts in the browser. React and Vue show an error on the page if the request fails. These class names need Tailwind on your site. This page does not load Tailwind. Bootstrap 5 class names need Bootstrap on your site. This page does not load Bootstrap.
<style>
#fg-fk_your_access_key{box-sizing:border-box;max-width:520px;width:100%;padding:28px;border:1px solid #dbe2ea;border-radius:8px;background:#fff;color:#0f172a;font:16px/1.5 system-ui,sans-serif;display:grid;gap:16px}#fg-fk_your_access_key *{box-sizing:border-box}#fg-fk_your_access_key h2{font-size:24px;line-height:1.3;margin:0 0 4px;color:#0f172a}#fg-fk_your_access_key label{display:grid;gap:6px;font-weight:500}#fg-fk_your_access_key input,#fg-fk_your_access_key textarea,#fg-fk_your_access_key select{width:100%;font:inherit;min-height:44px;border:1px solid #94a3b8;border-radius:8px;padding:10px 12px;background:#fff;color:#0f172a}#fg-fk_your_access_key textarea{min-height:96px;resize:vertical}#fg-fk_your_access_key .fg-reminder-consent{display:flex;align-items:flex-start;gap:10px;font-weight:400}#fg-fk_your_access_key input[type=checkbox]{width:20px;min-height:20px;flex-shrink:0;margin:2px 0}#fg-fk_your_access_key button{font:inherit;font-weight:600;min-height:48px;padding:12px 20px;border:0;border-radius:8px;background:#4338ca;color:#ffffff;cursor:pointer}#fg-fk_your_access_key :focus-visible{outline:3px solid #4338ca;outline-offset:3px}#fg-fk_your_access_key button:disabled{cursor:wait;opacity:.7}#fg-fk_your_access_key p{margin:0}#fg-fk_your_access_key fieldset{border:0;padding:0;margin:0;display:grid;gap:8px;min-width:0}#fg-fk_your_access_key legend{font-weight:500;padding:0;margin-bottom:6px}#fg-fk_your_access_key .fg-choice{display:flex;align-items:center;gap:10px;font-weight:400}#fg-fk_your_access_key input[type=radio]{width:20px;min-height:20px;flex-shrink:0;margin:0}#fg-fk_your_access_key .fg-trap{position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
</style>
<form id="fg-fk_your_access_key" action="https://formgong.com/submit" method="POST">
<h2>Apply for this job</h2>
<input type="hidden" name="access_key" value="fk_your_access_key">
<input type="hidden" name="_lang" value="en">
<label>Full name * <input type="text" name="full_name" required></label>
<label>Email * <input type="email" name="email" required autocomplete="email"></label>
<label>Phone <input type="tel" name="phone" autocomplete="tel"></label>
<label>Position * <select name="position" required><option value="">—</option><option value="Sales assistant">Sales assistant</option><option value="Warehouse">Warehouse</option><option value="Office">Office</option></select></label>
<label>Earliest start date <input type="date" name="start_date"></label>
<label>Link to your CV or LinkedIn <input type="url" name="cv_link"></label>
<label>Tell us about your experience * <textarea name="experience" required></textarea></label>
<label class="fg-choice"><input type="checkbox" name="agree" value="yes" required> I agree that you keep my application for this hiring round *</label>
<div class="fg-trap" aria-hidden="true"><label>Leave this field empty<input name="botcheck" tabindex="-1" autocomplete="off"></label></div>
<button type="submit">Send application</button>
</form><form class="relative mx-auto grid w-full max-w-lg gap-4 rounded-lg border border-slate-200 bg-white p-6 text-base text-slate-900" action="https://formgong.com/submit" method="POST"> <h2 class="text-2xl font-semibold">Apply for this job</h2> <input type="hidden" name="access_key" value="fk_your_access_key"> <input type="hidden" name="_lang" value="en"> <div class="grid gap-1"><label class="font-medium" for="tw-full_name">Full name *</label><input class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-full_name" type="text" name="full_name" autocomplete="name" required></div> <div class="grid gap-1"><label class="font-medium" for="tw-email">Email *</label><input class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-email" type="email" name="email" autocomplete="email" required></div> <div class="grid gap-1"><label class="font-medium" for="tw-phone">Phone</label><input class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-phone" type="tel" name="phone" autocomplete="tel"></div> <div class="grid gap-1"><label class="font-medium" for="tw-position">Position *</label><select class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-position" name="position" required><option value="">Choose</option><option value="Sales assistant">Sales assistant</option><option value="Warehouse">Warehouse</option><option value="Office">Office</option></select></div> <div class="grid gap-1"><label class="font-medium" for="tw-start_date">Earliest start date</label><input class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-start_date" type="date" name="start_date"></div> <div class="grid gap-1"><label class="font-medium" for="tw-cv_link">Link to your CV or LinkedIn</label><input class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700" id="tw-cv_link" type="url" name="cv_link"></div> <div class="grid gap-1"><label class="font-medium" for="tw-experience">Tell us about your experience *</label><textarea class="w-full rounded-md border border-slate-400 bg-white px-3 py-2 text-base text-slate-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-700 min-h-24" id="tw-experience" name="experience" required></textarea></div> <label class="flex items-center gap-2 font-normal" for="tw-agree"><input class="h-5 w-5" id="tw-agree" type="checkbox" name="agree" value="yes" required> I agree that you keep my application for this hiring round *</label> <div class="absolute start-0 top-0 h-px w-px overflow-hidden" aria-hidden="true"><label>Leave this empty<input name="botcheck" tabindex="-1" autocomplete="off"></label></div> <button class="min-h-12 rounded-md bg-indigo-700 px-4 py-3 font-semibold text-white" type="submit">Send application</button> </form>
<form class="position-relative mx-auto" style="max-width:32rem" action="https://formgong.com/submit" method="POST"> <h2 class="h4 mb-3">Apply for this job</h2> <input type="hidden" name="access_key" value="fk_your_access_key"> <input type="hidden" name="_lang" value="en"> <div class="mb-3"><label class="form-label" for="bs-full_name">Full name *</label><input class="form-control" id="bs-full_name" type="text" name="full_name" autocomplete="name" required></div> <div class="mb-3"><label class="form-label" for="bs-email">Email *</label><input class="form-control" id="bs-email" type="email" name="email" autocomplete="email" required></div> <div class="mb-3"><label class="form-label" for="bs-phone">Phone</label><input class="form-control" id="bs-phone" type="tel" name="phone" autocomplete="tel"></div> <div class="mb-3"><label class="form-label" for="bs-position">Position *</label><select class="form-select" id="bs-position" name="position" required><option value="">Choose</option><option value="Sales assistant">Sales assistant</option><option value="Warehouse">Warehouse</option><option value="Office">Office</option></select></div> <div class="mb-3"><label class="form-label" for="bs-start_date">Earliest start date</label><input class="form-control" id="bs-start_date" type="date" name="start_date"></div> <div class="mb-3"><label class="form-label" for="bs-cv_link">Link to your CV or LinkedIn</label><input class="form-control" id="bs-cv_link" type="url" name="cv_link"></div> <div class="mb-3"><label class="form-label" for="bs-experience">Tell us about your experience *</label><textarea class="form-control" id="bs-experience" name="experience" rows="4" required></textarea></div> <div class="mb-3 form-check"><input class="form-check-input" type="checkbox" id="bs-agree" name="agree" value="yes" required><label class="form-check-label" for="bs-agree">I agree that you keep my application for this hiring round *</label></div> <div class="position-absolute top-0 start-0 overflow-hidden" style="width:1px;height:1px" aria-hidden="true"><label>Leave this empty<input name="botcheck" tabindex="-1" autocomplete="off"></label></div> <button class="btn btn-primary" type="submit">Send application</button> </form>
import { useEffect, useRef, useState } from "react";
// Visitor language for Formgong messages, thank-you text and autoreply.
const LANG = "en";
export default function ContactForm() {
const captcha = useRef(null);
const feedback = useRef(null);
const [failed, setFailed] = useState(false);
const [busy, setBusy] = useState(false);
const [status, setStatus] = useState("");
useEffect(() => mountCaptcha(captcha.current, null), []);
useEffect(() => { if (failed && status) feedback.current?.focus(); }, [failed, status]);
async function onSubmit(event) {
event.preventDefault();
if (busy) return;
const form = event.currentTarget;
const body = new FormData(form);
body.set("access_key", "fk_your_access_key");
body.set("_lang", LANG);
setBusy(true);
setFailed(false);
setStatus("Sending…");
try {
const response = await fetch("https://formgong.com/submit", {
method: "POST", headers: { Accept: "application/json" }, body,
});
const result = await response.json();
setFailed(!result.success);
setStatus(result.success ? (result.message || "Sent. Thank you!") : (result.message || "Could not send. Please try again."));
} catch { setFailed(true); setStatus("Connection failed. Please try again."); }
finally { setBusy(false); resetCaptcha(form); }
}
return <form id="fg-fk_your_access_key" onSubmit={onSubmit} aria-busy={busy}>
<style>{"#fg-fk_your_access_key{box-sizing:border-box;max-width:520px;width:100%;padding:28px;border:1px solid #dbe2ea;border-radius:8px;background:#fff;color:#0f172a;font:16px/1.5 system-ui,sans-serif;display:grid;gap:16px}#fg-fk_your_access_key *{box-sizing:border-box}#fg-fk_your_access_key h2{font-size:24px;line-height:1.3;margin:0 0 4px;color:#0f172a}#fg-fk_your_access_key label{display:grid;gap:6px;font-weight:500}#fg-fk_your_access_key input,#fg-fk_your_access_key textarea,#fg-fk_your_access_key select{width:100%;font:inherit;min-height:44px;border:1px solid #94a3b8;border-radius:8px;padding:10px 12px;background:#fff;color:#0f172a}#fg-fk_your_access_key textarea{min-height:96px;resize:vertical}#fg-fk_your_access_key .fg-reminder-consent{display:flex;align-items:flex-start;gap:10px;font-weight:400}#fg-fk_your_access_key input[type=checkbox]{width:20px;min-height:20px;flex-shrink:0;margin:2px 0}#fg-fk_your_access_key button{font:inherit;font-weight:600;min-height:48px;padding:12px 20px;border:0;border-radius:8px;background:#4338ca;color:#ffffff;cursor:pointer}#fg-fk_your_access_key :focus-visible{outline:3px solid #4338ca;outline-offset:3px}#fg-fk_your_access_key button:disabled{cursor:wait;opacity:.7}#fg-fk_your_access_key p{margin:0}#fg-fk_your_access_key fieldset{border:0;padding:0;margin:0;display:grid;gap:8px;min-width:0}#fg-fk_your_access_key legend{font-weight:500;padding:0;margin-bottom:6px}#fg-fk_your_access_key .fg-choice{display:flex;align-items:center;gap:10px;font-weight:400}#fg-fk_your_access_key input[type=radio]{width:20px;min-height:20px;flex-shrink:0;margin:0}#fg-fk_your_access_key .fg-trap{position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}"}</style>
<h2>{"Apply for this job"}</h2>
<label>{"Full name"} * <input type="text" name="full_name" required /></label>
<label>{"Email"} * <input type="email" name="email" required autoComplete="email" /></label>
<label>{"Phone"} <input type="tel" name="phone" autoComplete="tel" /></label>
<label>{"Position"} * <select name="position" required><option value="">—</option><option value={"Sales assistant"}>{"Sales assistant"}</option><option value={"Warehouse"}>{"Warehouse"}</option><option value={"Office"}>{"Office"}</option></select></label>
<label>{"Earliest start date"} <input type="date" name="start_date" /></label>
<label>{"Link to your CV or LinkedIn"} <input type="url" name="cv_link" /></label>
<label>{"Tell us about your experience"} * <textarea name="experience" required /></label>
<label className="fg-choice"><input type="checkbox" name="agree" value={"yes"} required /> {"I agree that you keep my application for this hiring round"} *</label>
<div aria-hidden="true" style={{position:"absolute",insetInlineStart:0,top:0,width:1,height:1,overflow:"hidden",clipPath:"inset(50%)"}}><input name="botcheck" tabIndex={-1} autoComplete="off" /></div>
<button type="submit" disabled={busy}>{busy ? "Sending…" : "Send application"}</button>
<p ref={feedback} role="status" tabIndex={-1}>{status}</p>
</form>;
}
function mountCaptcha(node, siteKey) {
if (!node || !siteKey) return () => {};
let disposed = false;
let widget;
function render() {
if (disposed || !window.turnstile) return;
window.turnstile.ready(() => {
if (disposed) return;
widget = window.turnstile.render(node, { sitekey: siteKey, language: node.dataset.language || document.documentElement.lang || "auto" });
node.dataset.widgetId = widget;
});
}
if (window.turnstile) render();
else {
let script = document.querySelector('script[src^="https://challenges.cloudflare.com/turnstile/v0/api.js"]');
if (!script) {
script = document.createElement("script");
script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
script.async = true;
document.head.appendChild(script);
}
script.addEventListener("load", render, { once: true });
}
return () => { disposed = true; if (widget !== undefined) window.turnstile?.remove(widget); };
}
function resetCaptcha(form) {
const widget = form.querySelector("[data-turnstile]")?.dataset.widgetId;
if (widget !== undefined) window.turnstile?.reset(widget);
}<script setup>
import { ref } from "vue";
const status = ref("");
const busy = ref(false);
async function onSubmit(event) {
const form = event.currentTarget;
if (busy.value || !form.reportValidity()) return;
const body = new FormData(form);
body.set("access_key", "fk_your_access_key");
body.set("_lang", "en");
busy.value = true;
status.value = "Sending…";
try {
const response = await fetch("https://formgong.com/submit", {
method: "POST",
headers: { Accept: "application/json" },
body,
});
const result = await response.json();
status.value = result.success ? (result.message || "Sent. Thank you!") : (result.message || "Could not send. Please try again.");
} catch {
status.value = "Connection failed. Please try again.";
} finally {
busy.value = false;
}
}
</script>
<template>
<form style="position:relative;display:grid;gap:16px;max-width:32rem" @submit.prevent="onSubmit" :aria-busy="busy">
<h2>Apply for this job</h2>
<label>Full name * <input type="text" name="full_name" required></label>
<label>Email * <input type="email" name="email" required autocomplete="email"></label>
<label>Phone <input type="tel" name="phone" autocomplete="tel"></label>
<label>Position * <select name="position" required><option value="">—</option><option value="Sales assistant">Sales assistant</option><option value="Warehouse">Warehouse</option><option value="Office">Office</option></select></label>
<label>Earliest start date <input type="date" name="start_date"></label>
<label>Link to your CV or LinkedIn <input type="url" name="cv_link"></label>
<label>Tell us about your experience * <textarea name="experience" required></textarea></label>
<label class="fg-choice"><input type="checkbox" name="agree" value="yes" required> I agree that you keep my application for this hiring round *</label>
<div aria-hidden="true" style="position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)"><input name="botcheck" tabindex="-1" autocomplete="off"></div>
<button type="submit" :disabled="busy">Send application</button>
<p role="status" tabindex="-1">{{ status }}</p>
</form>
</template>Create a free form, then open Connect on that form in this browser. If it still has the default name, email and message fields, they are replaced with this form.
| Field | Type | Required |
|---|---|---|
| Full name, email | Text, email | Yes |
| Phone, earliest start date | Tel, date | No |
| Position | Select with three roles | Yes |
| CV or LinkedIn link | URL | No |
| Experience, consent | Textarea, checkbox | Yes |
What to ask, and what to leave out
Ask what you need to decide who to interview: how to reach them, which role, when they can start and why they fit. The sample has a url field for a CV or LinkedIn link, because this generator does not write a file upload. A link also keeps large attachments out of your inbox.
Leave out questions about age, date of birth, marital status, children, religion, health or a photo. In the US, the EEOC treats questions like these as evidence of discrimination when the answer is not needed for the job, and EU countries have similar rules. If the law requires a question for the role, such as the right to work, ask it in the words your local guidance uses.
Keeping applications private
An application holds personal data. The sample ends with a required checkbox: the person agrees that you keep the application for this hiring round. Say on the page how long you keep applications, and delete them when the round is over.
Formgong stores submissions in the EU. To track candidates as a team, send each application to Notion, where it becomes a row in a database you can move through stages. Or keep it simple and reply from your mail app: the notification uses the candidate’s email as the reply address.
Other kinds of application
A program, a grant or a volunteer role uses the same form with other questions. The registration form generator has a shorter application example next to a workshop signup. For one-off hiring, this page is enough. For dozens of open roles, an applicant tracking system will save you time.
Free limits, email and storage
The application form code is free to copy. Applications are delivered only after you replace the placeholder key.
Copying the code needs no account. AI generations are limited to 5 an hour and 10 a day for each network, plus 100 a day for the whole site. When a limit is hit, use “Build it yourself, without AI”. That path does not call the model.
On the free plan, Telegram is instant and email is sent for every submission. The free plan is 1,000 submissions a month. Auto-reply is not on the free plan. Submission data is stored in the EU. Support is Formgong at support@formgong.com.
Your description is sent to the model so it can choose fields. It is not stored. Do not paste passwords, card numbers or other secrets.
Questions
What is a job application form generator?
A tool that writes the application form for your careers page. This one gives HTML, Tailwind, Bootstrap 5, React and Vue versions of the same fields.
How do I create a job application form in HTML?
Use text, email and tel inputs for contact details, a select for the position, a textarea for experience and a required consent checkbox. Copy the HTML tab on this page for a working version.
Can candidates upload a CV?
Not with this generator, which has no file field. The sample asks for a link to the CV or a LinkedIn profile instead.
What should a job application form not ask?
Age, date of birth, marital status, children, religion, health or a photo, unless the law requires it for the role. These questions can be treated as evidence of discrimination.
Where do the applications go?
To your Formgong inbox, and to you by email or Telegram, after you add a real key. You can also send each one to Notion.
Sources
Checked on 16.10.2026 against these public pages: EEOC: Prohibited employment policies and practices, MDN: input type=url, Formgong HTML guide.