A PHP contact form for Hugo

I feel that’s the main thing I miss from WordPress: the ease of creating contact forms. Of course, there are commercial services providing endpoints and SMPT servers, but it’s additional privacy concerns and costs.

So I did a PHP micro-framework to easily provide an end-point for a pure HTML form:

Main features:

  • easy to configure (config.php) and to extend (/templates),
  • send email through SMTPS with PHPMailer (enabling proper SPF and DKIM authentication),
  • plain text or HTML email body,
  • contact form displayed by embedding the provided <iframe> or using Hugo shortcode (provided),
  • GeoIP and user-agent detection embedded,
  • spam & bots basic blocking features (see README),
  • email templating support:
    • plain text and HTML templates provided,
    • write your own custom PHP email templates (full examples provided),
    • chose template from contact form input,
    • each template gets its own list of receipients (use different templates to send emails to different persons and/or in different languages),
    • template can fetch values from any custom input form field or custom config key.

Needs PHP 8.1 minimum, Composer, cURL and Phar.


1 Like

Is that really worth it compared to, for example, Formspree?

Formspree is a third-party, commercial service, based in the USA, with a free teer stopping at 50 emails/month. I’m sure they have lots of templating options through the typical JS-driven page builders, on top of their non-GDPR-compliant tracking cookies.

My solution is a self-hosted opensource framework that works on any old-school LAMP server with PHP > 8.1 and uses your own mailbox and DKIM key to send emails, that can be adapted to many use cases through minor code changes in config and template files, without having to explore sub-sub-submenus through right-click pain.

That’s like comparing oranges to apples.

If you like to click everywhere, figure out UI design quirks, re-figure it out in 1 year when they will have changed everything, and spend 120$/year now, but probably 150$/year in 2025, go for Formspee.

Personnally, I’m done with third-party & proprietary “no-coding” stuff when I can achieve the same thing in 500 lines of code and 3 days of work, producing re-usable and maintainable code with no hidden fees or subscription prices that will increase without notice in the years to come.

Coming from the WordPress world, I have seen premium plugins prices be multiplied by 5 to 10 between 2016 and 2023, while user support is just as mediocre as before, stability is a wild dream, and feature creeping is each year more exhausting. That’s not my definition of progress.


I’d far rather just provide contact details in the site footer. Low cost, easy to maintain, easy for users, no legal considerations; it just works.

Personally, I can’t remember the last time I built a site with a contact form, or even a contact page. For Hugo sites I’m not deploying them to a LAMP server; so there is no PHP.

Even the Craft sites I build, where I am deploying to a LAMP server, I wouldn’t want that server to be sending email; I want it 100% dedicated to serving web requests.


What I understand @aurelienpierre is suggesting is to deploy your Hugo site normally and use a separate LAMP server to control the back-end part. That’d be a machine you can have at home, so you have control over it.


How do you protect your email from spamming bots ?

For this I’m succesfully using GitHub - martignoni/hugo-cloak-email: A Hugo theme component to cloak email adresses

1 Like

I have not tested this solution, so I may be wrong. But based on the description, this might have a negative impact on accessibility (e.g. blind users).

If I am right and this shortcode is used in an imprint, this could cause legal problems (depending on which country you live in).

Hey, I personnaly use Tally.io for form. The free tier is not limited in terms amount of message sent and you simply choose to send the message from the site to your inbox.

See more about their terms and GDPR: GPDR

1 Like

You can call aws and get on the phone with them and use a lambda serverless function that sends from your website. They helped me do it

There’s an errata here. It’s actually https://tally.so/


I’m fully with you here!

Just wonder how did you solve “search” which is, besides “forms” another piece of puzzle to be solved by not using WP or cashing 3rd party services enormous amount of money for their “service”?


With Fuse : https://www.fusejs.io/

There is a ready-to-use Hugo theme module but I used the manual way.

1 Like


very well said but there are also the no server solutions such as GitHub actions you can basically use GitHub to deliver form via email api or AWS SES. Any thoughts on that? instead of php which is not that secure as requires maintenance and security, cheers!

PHP is not more or less secure than any programming language used to script server-side features. Perhaps it got a bad rap from being customarily associated with SQL databases and allowing SQL injections from HTML forms. Sending emails doesn’t deal with SQL.

The only reliable way to send emails that will (most of the time) pass spam detection is through SMTP servers : it’s the only way to have them stamped with DKIM and checked by SPF. You can possibly pile up DMARC. All these require an email server, and the MX, DKIM, SPF and DMARC properties need to be set on the DNS records.

Sending emails truly serverless means the emails will have no authentication whatsoever, and is typically the fingerprint of spam and phishing. See an example of email scripted sending in Python, you can usurp any FROM email address you want without having to authentify anywhere. Emails fields are purely declarative. I personnaly have scripts on my mail server that send emails to the spam box straight away, when they have missing or invalid DKIM headers. It gets rid of 98-99 % of spams without having to use keyword-based bayesian filtering.

Now, whatever serverless way of connecting to your email server through SMTP will share the same threat model : you need to have the ID/Password of the SMTP account stored somewhere safe, and to tunnel an encrypted route (SSL and such).

AWS SES apparently handles the SMTP part for you, but it seems to be only a “write only” emailing system. Plus, you still needs to map HTML forms to emailing fields through some HTTP interface able to collect POST requests (probably using AWS lambda functions). AWS Lambda works with Docker containers stored on AWS S3 buckets. When you are done figuring out AWS Lambda, Docker images configuration (I personally gave up) and piling up the hidden fees of SES, Lambda and S3, a bit of PHP on top of PHPMailer doesn’t look that bad, especially if you already have your email server.


All of this is quite true, but if my form action is just sending a notification to me I really don’t care. But as you point out, that is entirely different if your form also triggers an email to the person who submitted the form (e.g., “Thank you for filling out my form…”).


Wonderful! Thank you very much!