Blog
Send form submissions to Slack (no code required)
· 4 min read
A contact form submission that lands in a shared inbox gets read whenever someone happens to check it - which, for a small team, can mean hours later, or not until someone else forwards it. A submission posted into Slack gets read in the next thirty seconds, because Slack is where the team already is. Same lead, same message, very different response time.
Email still has a place - it's the paper trail. But as the first notification channel, Slack usually wins: it's the tool your team is already staring at, it doesn't require anyone to remember to check a mailbox, and a new message in a channel gets seen by everyone on it, not just whoever's inbox it landed in.
The DIY route
Slack doesn't accept a raw HTML form POST directly, so getting a submission there yourself means writing a small receiver in between. Typically that's a serverless function (Cloudflare Worker, Vercel function, AWS Lambda) that:
- Accepts the form's POST and validates it actually looks like a submission and not spam.
- Reformats the field names and values into Slack's message format - either a simple
textstring or ablocksarray if you want it to look native. - Escapes user input so a message containing
&,<, or>doesn't break Slack'smrkdwnrendering. - POSTs the result to a Slack Incoming Webhook URL, and handles the case where that POST fails or times out - Slack webhooks aren't infinitely reliable, so a naive implementation quietly drops submissions when they hiccup.
None of this is exotic - it's an afternoon of real engineering, and it's one more service to deploy, monitor, and eventually maintain when a field name changes or Slack tweaks its formatting rules. Reasonable if you already have the infrastructure and enjoy owning it; overhead if all you wanted was "tell the team when someone fills out the form."
The zero-code way
Formhook skips the receiver entirely. In your form's settings, add a webhook and paste in your Slack Incoming Webhook URL (the one you get from Slack's own "Incoming Webhooks" app - https://hooks.slack.com/services/...). Formhook recognizes that host and path automatically and formats every submission as a native Slack message from then on - no code, no field mapping, no escaping to get wrong.
Every submission arrives as a message with a header naming the form, and one or more sections listing each field's name and value, formatted the way a human posted it there themselves. If a submission has more fields than fit cleanly in one section, it's split across several - you don't have to think about it.
{
"text": "New submission to Contact form",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "New submission: Contact form" }
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*name*\nJane Doe" },
{ "type": "mrkdwn", "text": "*email*\njane@example.com" },
{ "type": "mrkdwn", "text": "*message*\nCan you send a quote for..." }
]
}
]
}Same trick for Discord and Microsoft Teams
The URL-detection works the same way for the other two chat tools teams commonly ask for. Paste a Discord webhook URL and submissions arrive as a formatted Discord embed; paste a Microsoft Teams webhook URL and they arrive as a native Teams card. In every case it's the same one field in the dashboard - Formhook looks at the URL's host and path to decide how to format the payload, so switching your team's chat tool later is a matter of pasting a different URL, not rebuilding anything.
Anything that isn't one of those three still works: paste any other URL and Formhook falls back to a generic JSON POST, HMAC-signed so you can verify it actually came from Formhook.
What this doesn't do
Worth being precise about scope: this posts a formatted message into a channel when a submission arrives. It doesn't create threads, add interactive buttons, or add a slash command - it's notification, not a Slack app. For most teams that's exactly the point: one clean message, immediately, with nothing further to configure.
Getting started
If you already have a form pointed at Formhook, this is a two-minute addition: create an Incoming Webhook in Slack, paste the URL into your form's webhook settings, and the next submission shows up in the channel. If you're starting from scratch, the docs cover setting up the form itself, and pricing has the free tier's limits (250 submissions/month, no card required) if you just want to try it.
Ship a working form in one line
EU-hosted, submissions kept forever, push notifications on every tier.
Start freeNo credit card · read the docs
Keep reading
- Push notifications for forms: why email alerts aren't enoughEmail alerts for form submissions get buried. Web push notifications reach your phone and desktop instantly - here's how they work and how to set them up.
- AJAX form submission: send a form without a page reloadThe default HTML form submit reloads the page. Here's how to submit a form with fetch() instead - inline success/error states, progressive enhancement, and accessible status updates.
- What is a form backend? (And when you need one)A form backend receives, stores, and forwards your website's form submissions so you don't run a server. Here's how they work and when you need one.