Motivation
Three years ago I wrote an article about how to build a contact form in jekyll. My previous work on this code lasted quite a while. I’m happy with it but It’s become a bit much to manage in its current state.
Reasons to refactor
- The TO field was an environment variable. This necessitated a 1:1 ratio of domains to containers I was running. NOT maintainable…
- The vue component was too dumb. It did not understand how to process generic forms. I needed to link hard coded javascript components for each different form type and have manually coded html forms. This was fragile and lead to typos/extra work. Now I include one file and one properly labeled html element that I define.
Solutions
- yaml for mailgun proxy config
- Form generator for easy scaffolding of embedable forms.
- vue3/axios dependency updates.
The Code
Given a custom domain and a properly configured mailgun account; you can be up and running with this project in minutes. You can check it out over at derek-adair/embedded-contact. The README has more detailed instructions but here is a high level overview;
1) The api.
Currently its pretty “dumb” and takes your mailgun key as an environment variable. The most sophisticated piece of this is how it reads proxy.config.yml;
proxy.config.yml
domains:
# Your mailgun domain
mg.<yourdomain>.com:
to: <your_valid_email>
uris:
- https://<yourdomain>.com
2) The Form Generator
This is VueJS app powered by vite. It will give you a central place to edit / style your contact forms. Leveraging this in your own projects will look something like;
- Create a form definition, something like
CustomContact.vue
. - Initialize in main.js
import CustomContact from "./CustomContact.vue"; createApp(CustomContact).mount("#custom-contact");
- Build w/
docker-compose run --rm form-generator yarn run build
- Include the javascript from ./dist anywhere you have
<div id="custom-contact"></div>
Security
The only real security in place is basic CORS and some validation to ensure I dont accidently cross my clients forms.
Know the risk
This code is vulnerable to CSRF attacks. I do have auth planned, but I am not really that concerned as this would really take someone seeking to maliciously attack a specific target – for those reasons I am not sure when I will get around to this.
What’s Next?
- Releases on pypi / npm
- Auth
- Additional mail providers
- Mailing lists?
- Probably a SQLite DB??
- Official docker images
- You tell me