Skip to main content

Modern Job Application Form

A sleek dark-mode job application and career submission form built with Tailwind CSS. Pre-configured for Backforms with built-in resume file attachments, honeypot spam defense, and instant candidate notifications dispatched to your recruitment team.

Direct resume & CV file uploads
Invisible honeypot (_gotcha) spam trap
Full Next.js / React component with FormData
Dark mode styling with gradient button
Instant HR notifications to Email & Slack
Live Form PreviewComponent Sandbox

Job Application

Structured 2-column format with automated file attachments and applicant tracking routing.

Pre-configured for Backforms endpoint with S3 file uploads
Honeypot anti-spam active
Zero backend needed
style="color:#9ece6a;">"use client";

import { useState } from style="color:#9ece6a;">"react";

export default function JobApplicationForm() {
  const [status, setStatus] = useState<style="color:#9ece6a;">"idle" | style="color:#9ece6a;">"loading" | style="color:#9ece6a;">"success" | style="color:#9ece6a;">"error">(style="color:#9ece6a;">"idle");
  const [errorMessage, setErrorMessage] = useState(style="color:#9ece6a;">"");
  const [fileName, setFileName] = useState(style="color:#9ece6a;">"");

  async function handleSubmit(e: React.FormEvent<style="color:#f7768e;font-weight:600;">HTMLFormElement>) {
    e.preventDefault();
    setStatus(style="color:#9ece6a;">"loading");
    setErrorMessage(style="color:#9ece6a;">"");

    const form = e.currentTarget;
    const formData = new FormData(form);

    try {
      style=style="color:#9ece6a;">"color:#565f89;font-style:italic;">// Replace YOUR_FORM_ID with your Backforms endpoint ID from app.backforms.com
      const response = await fetch(style="color:#9ece6a;">"https:style="color:#565f89;font-style:italic;style="color:#9ece6a;">">//backforms.com/f/YOUR_FORM_ID", {
        method: style="color:#9ece6a;">"POST",
        headers: {
          Accept: style="color:#9ece6a;">"application/json",
        },
        body: formData,
      });

      if (response.ok) {
        setStatus(style="color:#9ece6a;">"success");
        form.reset();
        setFileName(style="color:#9ece6a;">"");
      } else {
        const data = await response.json().catch(() => null);
        setErrorMessage(data?.error || style="color:#9ece6a;">"Application submission failed. Please try again.");
        setStatus(style="color:#9ece6a;">"error");
      }
    } catch {
      setErrorMessage(style="color:#9ece6a;">"Network error. Please check your internet connection.");
      setStatus(style="color:#9ece6a;">"error");
    }
  }

  function handleFileChange(e: React.ChangeEvent<style="color:#f7768e;font-weight:600;">HTMLInputElement>) {
    if (e.target.files && e.target.files[0]) {
      setFileName(e.target.files[0].name);
    }
  }

  return (
    <style="color:#f7768e;font-weight:600;">div className=style="color:#9ece6a;">"flex flex-col items-center justify-center min-h-[500px] p-4">
      <style="color:#f7768e;font-weight:600;">div className=style="color:#9ece6a;">"w-full max-w-md bg-gray-800 rounded-lg shadow-md p-6 text-gray-200">
        <style="color:#f7768e;font-weight:600;">h2 className=style="color:#9ece6a;">"text-2xl font-bold text-gray-200 mb-4">Job Application Form</style="color:#f7768e;font-weight:600;">h2>

        {status === style="color:#9ece6a;">"success" ? (
          <style="color:#f7768e;font-weight:600;">div className=style="color:#9ece6a;">"p-4 bg-emerald-950/80 border border-emerald-500/40 text-emerald-300 rounded-lg text-center space-y-2">
            <style="color:#f7768e;font-weight:600;">p className=style="color:#9ece6a;">"font-semibold text-base">Application Submitted!</style="color:#f7768e;font-weight:600;">p>
            <style="color:#f7768e;font-weight:600;">p className=style="color:#9ece6a;">"text-xs text-emerald-400">
              Thank you for applying. Our hiring team will review your application and resume shortly.
            </style="color:#f7768e;font-weight:600;">p>
            <style="color:#f7768e;font-weight:600;">button
              type=style="color:#9ece6a;">"button"
              onClick={() => setStatus(style="color:#9ece6a;">"idle")}
              className=style="color:#9ece6a;">"mt-2 px-4 py-1.5 bg-emerald-600 text-white rounded-md text-xs font-medium hover:bg-emerald-500 transition cursor-pointer"
            >
              Submit Another Application
            </style="color:#f7768e;font-weight:600;">button>
          </style="color:#f7768e;font-weight:600;">div>
        ) : (
          <style="color:#f7768e;font-weight:600;">form onSubmit={handleSubmit} className=style="color:#9ece6a;">"flex flex-col">
            {style=style="color:#9ece6a;">"color:#565f89;font-style:italic;">/* Invisible Honeypot Spam Trap (Catches automated bots silently) */}
            <style="color:#f7768e;font-weight:600;">input
              type=style="color:#9ece6a;">"text"
              name=style="color:#9ece6a;">"_gotcha"
              style={{ display: style="color:#9ece6a;">"none" }}
              tabIndex={-1}
              autoComplete=style="color:#9ece6a;">"off"
            />

            {status === style="color:#9ece6a;">"error" && (
              <style="color:#f7768e;font-weight:600;">div className=style="color:#9ece6a;">"mb-4 p-3 bg-red-900/60 border border-red-500/50 text-red-200 text-xs rounded-md">
                {errorMessage}
              </style="color:#f7768e;font-weight:600;">div>
            )}

            <style="color:#f7768e;font-weight:600;">input
              name=style="color:#9ece6a;">"fullName"
              placeholder=style="color:#9ece6a;">"Full Name"
              required
              className=style="color:#9ece6a;">"bg-gray-700 text-gray-200 border-0 rounded-md p-2 mb-4 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150"
              type=style="color:#9ece6a;">"text"
            />

            <style="color:#f7768e;font-weight:600;">input
              name=style="color:#9ece6a;">"email"
              placeholder=style="color:#9ece6a;">"Email"
              required
              className=style="color:#9ece6a;">"bg-gray-700 text-gray-200 border-0 rounded-md p-2 mb-4 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150"
              type=style="color:#9ece6a;">"email"
            />

            <style="color:#f7768e;font-weight:600;">input
              name=style="color:#9ece6a;">"phone"
              placeholder=style="color:#9ece6a;">"Phone Number"
              className=style="color:#9ece6a;">"bg-gray-700 text-gray-200 border-0 rounded-md p-2 mb-4 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150"
              type=style="color:#9ece6a;">"tel"
            />

            <style="color:#f7768e;font-weight:600;">input
              name=style="color:#9ece6a;">"linkedin"
              placeholder=style="color:#9ece6a;">"LinkedIn Profile URL"
              className=style="color:#9ece6a;">"bg-gray-700 text-gray-200 border-0 rounded-md p-2 mb-4 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150"
              type=style="color:#9ece6a;">"url"
            />

            <style="color:#f7768e;font-weight:600;">textarea
              name=style="color:#9ece6a;">"cover_letter"
              rows={4}
              placeholder=style="color:#9ece6a;">"Cover Letter"
              className=style="color:#9ece6a;">"bg-gray-700 text-gray-200 border-0 rounded-md p-2 mb-4 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150 resize-none"
            />

            <style="color:#f7768e;font-weight:600;">div className=style="color:#9ece6a;">"mb-4">
              <style="color:#f7768e;font-weight:600;">label className=style="color:#9ece6a;">"block text-xs text-gray-400 mb-1">Resume / CV (PDF, DOCX)</style="color:#f7768e;font-weight:600;">label>
              <style="color:#f7768e;font-weight:600;">input
                name=style="color:#9ece6a;">"resume"
                type=style="color:#9ece6a;">"file"
                accept=style="color:#9ece6a;">".pdf,.doc,.docx"
                onChange={handleFileChange}
                className=style="color:#9ece6a;">"w-full bg-gray-700 text-gray-200 border-0 rounded-md p-2 file:mr-3 file:py-1 file:px-2.5 file:rounded file:border-0 file:text-xs file:font-semibold file:bg-gray-600 file:text-gray-200 hover:file:bg-gray-500 focus:bg-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 transition ease-in-out duration-150 cursor-pointer text-xs"
              />
            </style="color:#f7768e;font-weight:600;">div>

            <style="color:#f7768e;font-weight:600;">button
              type=style="color:#9ece6a;">"submit"
              disabled={status === style="color:#9ece6a;">"loading"}
              className=style="color:#9ece6a;">"bg-gradient-to-r from-indigo-500 to-blue-500 text-white font-bold py-2 px-4 rounded-md mt-2 hover:from-indigo-600 hover:to-blue-600 transition ease-in-out duration-150 disabled:opacity-60 disabled:cursor-not-allowed cursor-pointer"
            >
              {status === style="color:#9ece6a;">"loading" ? style="color:#9ece6a;">"Submitting Application..." : style="color:#9ece6a;">"Apply"}
            </style="color:#f7768e;font-weight:600;">button>
          </style="color:#f7768e;font-weight:600;">form>
        )}
      </style="color:#f7768e;font-weight:600;">div>
    </style="color:#f7768e;font-weight:600;">div>
  );
}
Replace YOUR_FORM_ID with your Backforms key

Connect this component to your Backforms endpoint

Create a free form endpoint in under 30 seconds. Zero backend servers or databases required.

Get Free Endpoint Key

Frequently Asked Questions & Technical Integration

How does resume and file upload work with Backforms?

Backforms automatically accepts file attachments whenever your form includes enctype='multipart/form-data' or sends FormData. The files are securely saved in high-performance cloud storage and included as downloadable links in your email alerts and webhook notifications.

What file formats and size limits are supported?

Candidates can attach PDF, DOC, DOCX, PNG, JPG, and other standard formats up to 25MB per upload. You can customize acceptable MIME types and size constraints in your form settings.

Can I route applications directly to our recruitment Slack channel or HR email?

Yes! In your Backforms integrations, connect your team Slack or Discord webhook, and every new job applicant's profile and resume will be dispatched immediately in real-time.