send.webforms.toRead the docs →

Template marketplaces

Make a ThemeForest template's contact form work

Short answer

Set the template's form action to your WebForms endpoint. If the template submits with jQuery, add dataType: "json" to its $.ajax call and show response.message on success. No PHP, hosting or mail server is needed, and it works on static hosts like GitHub Pages and Netlify.

ThemeForest HTML templates usually ship a contact form wired to a PHP script that only works on a server that runs PHP and can send email. WebForms replaces that script: the form posts to your endpoint, and each submission is spam checked, stored and emailed to you. Most templates need one changed attribute and one changed line of JavaScript.

Get an endpointRead the docs

Setup

  1. Create a form and copy its endpoint

    Sign up, create a form, and copy the endpoint URL. Submissions are emailed to your verified address by default.

  2. Find the contact form

    Open the template's contact page, usually contact.html, and find the <form> tag. Note its action and any id or class a script uses, such as #contact-form, .ajax-form or .form-widget.

  3. Point the action at WebForms

    Replace the action value (for example php/contact.php or mail.php) with your endpoint, and keep method="POST". Keep the field name attributes as they are: WebForms stores whatever fields the form sends.

  4. Fix the template's AJAX script

    If the template submits without reloading the page, open its form script (often js/ajax-mail.js, js/contact.js or js/main.js). Add dataType: "json" to the $.ajax call, and show response.message instead of the raw response. Scripts that hardcode the PHP URL, like contact_me.js, need that URL replaced with your endpoint too.

  5. Delete the PHP files and send a test

    Remove the template's mail scripts, such as contact.php, mail.php or the php/ folder, so nothing posts to them. Send a test from the live site; it appears in your inbox and the dashboard within seconds.

ThemeForest examples

Swap in your own endpoint and these run as-is.

contact.html
<!-- contact.html: only the action changes -->
<form id="contact-form" action="https://send.webforms.to/wft_your_key" method="POST">
  <input type="text" name="name" placeholder="Your name" required>
  <input type="email" name="email" placeholder="Your email" required>
  <input type="text" name="subject" placeholder="Subject">
  <textarea name="message" placeholder="Message" required></textarea>

  <!-- Optional: WebForms reads these -->
  <input type="hidden" name="_subject" value="New enquiry from the website">
  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
         style="position:absolute;left:-9999px" aria-hidden="true">

  <button type="submit">Send message</button>
</form>

The common jQuery handler, with the two changes marked:

js/ajax-mail.js
// js/ajax-mail.js (or contact.js): the usual jQuery handler
$(form).submit(function (e) {
  e.preventDefault();
  $.ajax({
    type: "POST",
    url: $(form).attr("action"),      // now your WebForms endpoint
    data: $(form).serialize(),
    dataType: "json"                  // add this: asks WebForms for JSON
  })
    .done(function (response) {
      $(formMessages).removeClass("error").addClass("success");
      $(formMessages).text(response.message);   // was: .text(response)
      $(form)[0].reset();
    })
    .fail(function () {
      $(formMessages).removeClass("success").addClass("error");
      $(formMessages).text("Sorry, your message could not be sent. Please try again.");
    });
});

If the template's script is hard to change, remove it and use this instead:

contact.html
<!-- Replaces the template's form script entirely -->
<script>
document.querySelector("#contact-form").addEventListener("submit", async (e) => {
  e.preventDefault();
  const form = e.target;
  const out = form.querySelector(".form-message") ?? form.appendChild(document.createElement("p"));
  const body = new FormData(form);
  // So "Reply" on the notification email goes to the visitor.
  if (body.get("email")) body.set("_replyto", body.get("email"));
  const res = await fetch(form.action, {
    method: "POST",
    body,
    headers: { Accept: "application/json" },
  });
  const data = await res.json().catch(() => ({ ok: false }));
  out.textContent = data.ok ? data.message : "Sorry, something went wrong. Please try again.";
  if (data.ok) form.reset();
});
</script>

Why the template's contact form does not send

Most marketplace HTML templates post the form to a PHP file that ships with the template, such as contact.php, mail.php, php/contact-form.php or bat/rd-mailform.php. That script calls PHP's mail function or PHPMailer to send you an email. It only works on a server that runs PHP and is allowed to send mail.

Static hosting runs no PHP at all, so on hosts like GitHub Pages and Netlify the POST fails, often with 405 Not Allowed. Some cloud providers, DigitalOcean among them, block outgoing mail ports by default. Shared hosting that does run PHP can still send these emails to spam, because they come from the web server rather than a real mail domain.

Pointing the form at a WebForms endpoint removes the PHP step. The submission goes to WebForms, which checks it for spam, stores it, and emails it to you, or sends it to Slack, Discord, Telegram or a webhook on Pro.

Which form script does your template use?

ThemeForest has no single standard: each author ships their own handler. These are the patterns that come up most, and what each needs.

What you get instead of contact.php

Every submission is stored in a searchable inbox, so a missed email never means a missed enquiry. Spam is filtered without a CAPTCHA: a honeypot, a time trap and an AI classifier, on every plan including Free.

Free covers 300 submissions a month to one email address. Pro adds Slack, Discord, Telegram, webhooks, file uploads and an autoresponder, so the person who filled in the form gets a reply straight away.

Worth knowing

ThemeForest form FAQ

It posts to a PHP script, such as contact.php or mail.php, that needs a server running PHP with outgoing mail allowed. Static hosts like GitHub Pages, Netlify and Cloudflare Pages run no PHP, so the form fails or returns 405. Point the form at a WebForms endpoint and it works on any host.

Where ThemeForest submissions can go

The guide above gets the submission to your endpoint. From there it can land anywhere: one destination on Free, several on Pro.

Need the form markup too? The template gallery has complete forms for contact, waitlist, job application and more, and the form generator builds one field by field.

Ready to wire up your ThemeForest form?

Free for 300 submissions a month. Endpoint in under a minute, no card required.

Start free