Rand Stats

Air::Plugin::MailForm

zef:librasteve

Actions Status

Air::Plugin::MailForm

A plugin for the Raku Air web framework that renders a contact form and sends submissions via SMTP.

Synopsis

#!/usr/bin/env raku

use Air::Functional :BASE;
use Air::Base;
use Air::Plugin::MailForm;

my $site =
site :register[$mail-form, LightDark.new],
    page
        main [
            h3 'Contact Us';
            $mail-form;
        ]
;

$site.serve;

Set environment variables before running:

export SMTP_USER=myuser
export SMTP_PASS=mypass
export MAIL_FROM=webserver@example.com
export MAIL_TO=contact@example.com
raku bin/29-mailform.raku

Description

Air::Plugin::MailForm is a two-class plugin. Air::Plugin::MailForm is the field-free base that provides SMTP sending and form lifecycle (validate → send → finish/retry). Air::Plugin::ContactForm is the built-in subclass that adds name, email, and message fields. The exported $mail-form singleton is a ContactForm instance, so most users need nothing more than use Air::Plugin::MailForm.

SMTP credentials and routing are configured entirely through environment variables so no secrets appear in source code.

Custom Fields

Subclass Air::Plugin::MailForm to define your own fields. Override method mail-body to control the email body text:

use Air::Plugin::MailForm;
use Air::Form;

class EnquiryForm is Air::Plugin::MailForm {
    has Str $.company is required;
    has Str $.phone   is tel;
    has Str $.message is multiline;

    method mail-message(Str $from, Str $to, Str $subject --> Str) {
        qq:to/END/;
        From:    $from
        To:      $to
        Subject: $subject

        Company: { $.company }
        Phone:   { $.phone   }

        { $.message }
        END
    }

    method form-routes {
        self.init;
        self.submit: -> EnquiryForm $form {
            self.submit-form($form)
        }
    }
}

our $enquiry-form = EnquiryForm.empty;
# site :register[$enquiry-form], ...
# page main $enquiry-form;

Environment Variables

VariableDefaultDescription
SMTP_HOSTmail-eu.smtp2go.comSMTP server hostname
SMTP_PORT587SMTP server port
SMTP_USERSMTP username
SMTP_PASSSMTP password
MAIL_FROMEnvelope sender address
MAIL_TORecipient address
MAIL_BCCBCC address (optional)
MAIL_SUBJECTContact Form SubmissionEmail subject line

Docker

Pass the variables at docker run time with -e flags — never bake secrets into the image:

docker run -p 3000:3000 \
  -e SMTP_USER=myuser \
  -e SMTP_PASS=mypass \
  -e MAIL_FROM=webserver@example.com \
  -e MAIL_TO=contact@example.com \
  myimage

For multiple containers or CI pipelines an env file is tidier:

# .env  (add to .gitignore — never commit this)
SMTP_USER=myuser
SMTP_PASS=mypass
MAIL_FROM=webserver@example.com
MAIL_TO=contact@example.com
docker run -p 3000:3000 --env-file .env myimage

Installation

If you already have Air working, then:

Otherwise, follow the Air::Examples Getting Started

Author

librasteve librasteve@furnival.net

Copyright 2026 Stephen Roe.

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.