Gather User Feedback On Any Website with Hermes WC

Nothing’s more important for indie developers than gathering user feedback, especially for early-stage projects that are likely to undergo massive changes regularly. At the same time, many developers don’t need the kind of enterprise-level feature set that many of the most well-known customer platforms offer.

For the last few months, I’ve been creating Component Odyssey, a course designed to help developers build and publish components that work everywhere. As I’m gearing up to open my platform to beta testers I need a free, quick, and easy mechanism to gather user feedback.

I want an unintrusive widget that I could drop into my page which students could use to send feedback at any point during the course to flag bugs and unclear course content. Given that the Component Odyssey platform is built on top of SvelteKit, it would be easy for me to create a Svelte component that fires data to an endpoint.

But I wanted to practice what I teach, and a form widget feels like a great candidate for a web component as the browser already has great support for building forms. On top of that, a form widget isn’t a novel piece of functionality and certainly shouldn’t rely on a specific framework to work. The idea of writing a simple, but very useful component, that I can’t then use in my React and VanillaJS projects feels like a waste of energy.

That’s what led me to build Hermes WC. With Hermes WC, you can easily add an interactive form that dispatches the form data to a location of your choice.

Here’s a demo of Hermes WC in action, sending feedback to Discord, Slack, and an HTTP endpoint.

So let’s see how you can add Hermes WC to your own projects

Step 1: Installing Hermes WC

Begin by installing Hermes WC:

npm install hermes-wc

Step 2: Adding the Hermes WC markup

Once you’ve done that, you can update your webpage with the following markup:

	<form class="hermes-stack" data-hermes="form">
		<sl-input name="feedback" label="Feedback" placeholder="e.g., Not clear enough"></sl-input>
			start-helper-text="Low Score"
			end-helper-text="High score"
		<div class="hermes-row">
			<sl-button data-hermes="close">Close</sl-button>
			<sl-button variant="primary" type="submit">Submit</sl-button>
		<p data-hermes="helper-text" />

There’s heaps of stuff going on here, so let’s break it down, element by element.

Hermes Wrapper

This is the component that’s responsible for handling the layout of the Hermes form. It mainly handles the form’s open and close states, while also placing a button on the right hand side of the page.


This is the form element that’s in charge of listening and reacting to the submit event. A form element with the attribute data-hermes="form" is required.

SL Input

Because Hermes WC uses a standard HTML form element, we can use any old HTML form controls as children and their values will be captured in the submit event. As a result, I’m using the Shoelace library to render some pre-styled and accessible components.

A Shoelace input component

Hermes Score Input

This is an additional web component that Hermes WC provides. It renders a horizontal radio button group with some attributes for helper text.

The Hermes WC Score Input component

SL Button

This is a button provided to us by Shoelace. The button on the left has a data-hermes="close" attribute, which is used to close the feedback widget.

The button on the right has an attribute type="submit" and is used to submit the form when it’s clicked.

Two Shoelace button components

Whatever else you want…

Like I mentioned earlier, because Hermes WC works with HTML forms, you can use any HTML form control to build your form.

Step 3: Import the styles into your page

To apply the default styles to Hermes WC, go ahead and import the styles into your project:

<link rel="stylesheet" href="path/to/node_modules/hermes-wc/src/style.css" />

Step 4: Initializing the Hermes WC form

With the markup written, you’ll need to add a small splash of JavaScript to initialize the form.

import { DiscordSubmissionAdapter } from 'hermes-wc/src/submission-adapters/discord.js'
import { initializeHermesForm } from 'hermes-wc/src/index.js'

  submissionAdapters: [new DiscordSubmissionAdapter({
    webhookUrl: 'your webhook url'
  submissionCompleteCallback: (response) => { // handle the response }

Running initializeHermesForm will do a few things under-the-hood, like set up event listeners and register the web components.

You can then provide one or more submission adapters which send your data to a destination of your choice. As of now, Hermes WC supports sending feedback to Slack, Discord, or an HTTP GET endpoint. You can even create your own adapters.

You can also pass a function through to the submissionCompleteCallback option, which gets fired when all of the submission requests are settled. You’ll be given the response of all the promises, which you can use to display a success or error message to your users.

Wrapping Up

I hope you find a tool like Hermes WC useful. I plan to open source a bunch of the tools I create for Component Odyssey. Other tools include Sandpack Lit.

If you enjoyed this article, and would love to learn more about Component Odyssey or other cool web development tips, then consider subscribing to the newsletter.