How to build a user feedback loop into your web3 dapp

Build a user feedback form into your web3 dapp.

by Clarissa WatsonAugust 3, 2023
How to build a user feedback loop into your web3 dapp image

Collecting user feedback is one of the most critical steps to achieving product-market-fit and creating a successful application. And it’s even more important in web3, where standards for UX design are still emerging and undefined.

For web3 developers, the most popular method of collecting user feedback about their dapps continues to be centralized solutions offered by companies like Google and Mailchimp. However, on-chain feedback forms are now available. Let’s look at these web3-native feedback forms, why they’re important to your dapp’s success, and how to use them.

In a previous post, we introduced Form-xChange: a new open-source, decentralized web3 form built by Consensys, and showed you how to integrate it into your dapp using the MetaMask SDK.

In this tutorial, we’ll build on these steps by showing you how to deploy a feedback form to your frontend and create a new form for users to share their input about your dapp. But first, a quick reminder on the importance of collecting user feedback for product development and management.

Web3 user feedback forms to help mass adoption

Native, decentralized feedback forms are desperately needed in web3. Why?

  1. They cut costs dramatically: The only (and one-time) cost associated with creating a form is during the deployment of a smart contract. And if deployed on an L2 like Linea, the cost is usually not more than a few dollars.
  2. They have near-infinite customization possibilities: You can design your form to collect any kind of feedback you wish (text, reactions, links, etc.). Additionally, you can customize your frontend as needed as it is completely distinct from the contract.
  3. You pay only for what you use: With decentralized forms, there are no payment tiers based on the number of responses. Theoretically, you can record as many responses as you want. \

If you’re adopting a model where customers pay gas, you won’t incur any cost beyond contract deployment.
If you choose to pay the bill on behalf of your customers, again the cost is a few cents when you’re operating on a cost-efficient network. 4. You can implement token gating: Using decentralized forms, you can gate access to who can respond to your form questions. Therefore, you could theoretically limit access to wallets who own NFTs from your collection, wallets that have a certain non-zero balance of ETH, or an ERC-20 token of your choice.

A tutorial: creating your own decentralized user feedback form

Step 1: Install MetaMask

We will be deploying and interacting with our contracts on Linea. In order to do this, we will require a crypto wallet that is configured with the Linea network and has a small balance of LineaETH.

You first need a web3 wallet. In this tutorial we’ll use MetaMask — a free, easy to use wallet that comes automatically configured with Linea. You can install MetaMask as an extension for your browser here.

Note: For this tutorial, we recommend using a browser other than Brave (for example, Edge, Chrome, Safari, etc.). At the time of writing, Form-xChange has known issues running on the Brave browser.

Once you’ve added the extension, MetaMask will prompt you to complete a series of steps, including giving you your wallet recovery phrase. Store this phrase carefully. If lost, you can’t recover it. If stolen, someone else will have access to your funds.

Once your wallet is set up, navigate to the network drop-down in the top left of the MetaMask extension and toggle show test networks on. From the new drop-down, select the Linea Goerli network. If all goes well, your wallet should look something like this:

Image 2

Step 2: Acquire LineaETH from a faucet

If this is your first time working with Linea, your wallet will (obviously) have a balance of 0 LineaETH.

Let’s change that. Infura has a faucet that gives you access to free 0.5 LineaETH every day. In order to access this faucet, you may be prompted to create a free Infura account.

Image 1

Once the top up is done, you should see a small LineaETH balance:

Image 3

Step 3: Acquire a Linea RPC endpoint

Sign into Infura again using the account you created in the previous step. You will automatically be redirected to the main dashboard.

Here, create a new project by creating a new API key on the top right.

Image 4

For network, choose web3 API. You can name the key anything you want.

Once your key is created, you will be redirected once again to a project dashboard containing a collection of endpoints. From here, take note of the endpoint associated with Linea testnet. We will require this in a later step to deploy our Form-xChange contracts.

Step 4: Install node and npm

The Form-xChange solution runs on a stack of Infura, Next.js, Truffle, and the Dapp API. In order to install and use these technologies, we’ll need node and npm on our local machine.

You can download both for your operating system here.

Once done, check that it has been installed correctly by checking their version numbers on your terminal.

$ node -v
$ npm -v

Step 5: Clone the Form-xChange repository

As mentioned earlier, Form-xChange is an open-source repository whose source code is publicly available on GitHub.

Let’s clone this repository and install all required packages using the following commands:

$ git clone
$ cd Form-XChange
$ npm install

Open the Form-xChange repository in your favorite code editor (e.g. VS Code). This is a turn-key project, so we won’t need to write much code apart from configuring a few environment variables.

Step 6: Deploy the feedback form

Navigate to the sub-folder containing the Truffle project and the form smart contracts:

$ cd packages/form-XChange

In this folder, you will see a contracts sub-folder that contains two main contracts: a FeedbackForm and a FeedbackFormFactory.

The former implements an individual form that is capable of storing a list of questions and responses made to those questions.

The latter is a factory contract that can be used to deploy customized versions of the former.

You can take a look at the source code and make modifications according to the kind of form that you want to create. For this tutorial, we’ll stick to the default configuration.

In this step, we are going to deploy the FeedbackFormFactory contract. This will allow us, the creator, to create forms from our Next frontend.

In order to do this, create a file named .env and add the following information:


Next, in the truffle-config.js file, replace the generic RPC endpoint with the Infura endpoint you generated in Step 3. The final config file should look something like this:

const mnemonic = process.env["MNEMONIC"];

const HDWalletProvider = require("@truffle/hdwallet-provider");

module.exports = {
  networks: {
    development: {
      host: "", // Localhost
      port: 9545,
      network_id: "5777",
      chain_id: 1337,
    linea: {
      provider: () =>
        new HDWalletProvider(mnemonic, `< INFURA LINEA ENDPOINT >`),
      network_id: 59140,
      chain_id: 59140,
  mocha: {
    timeout: 100000,
  compilers: {
    solc: {
      version: "0.8.13",

We’re all set! Deploy the feedback form factory contract by running the following command:

$ npm run linea

If all goes well you should see output that looks something like this:

> form-xchange@0.0.0 linea
> npm run compile && npm run generate-types && npm run migrate:linea

> form-xchange@0.0.0 compile
> truffle compile

Compiling your contracts...
> Everything is up to date, there is nothing to compile.

> form-xchange@0.0.0 generate-types
> typechain --target=truffle-v5 'build/contracts/*.json'

Successfully generated 5 typings!

> form-xchange@0.0.0 migrate:linea
> truffle migrate --network linea

Compiling your contracts...
> Everything is up to date, there is nothing to compile.

Starting migrations...
> Network name:    'linea'
> Network id:      59140
> Block gas limit: 61000000 (0x3a2c940)


   Replacing 'FeedbackFormFactory'
   > transaction hash:    0x50ba2c362cb463d0b763ba5f092e3f1a8591dd9cd358f2feda035438ce02cee0
   > Blocks: 2            Seconds: 21
   > contract address:    0xBDAb1F857dC80968022784cc1C868820BFD2F7c5
   > block number:        1099121
   > block timestamp:     1688991002
   > account:             0xc361Fc33b99F88612257ac8cC2d852A5CEe0E217
   > balance:             0.62878173171592041
   > gas used:            2636875 (0x283c4b)
   > gas price:           2.500000007 gwei
   > value sent:          0 ETH
   > total cost:          0.006592187518458125 ETH

   > Saving artifacts
   > Total cost:     0.006592187518458125 ETH

> Total deployments:   1
> Final cost:          0.006592187518458125 ETH

Take note of the contract address. We’ll need this in a later step.

Step 7: Deploy the Next frontend factory

With our feedback form factory contract live, let’s shift our attention to the Next frontend. Navigate to the Next app project by running the following command:

$ cd ../../apps/web

We’ll need to connect our app with the contract we deployed in the previous step. We can do so by opening the lib/contract.ts/config.ts file and adding the contract address.


In the apps/web folder, create another .env file and this time, add the Infura key associated with your project from Step 3.


We’re all set! Let’s now deploy the app to localhost:

$ npm run dev

You can now check out the app on localhost:3000. It should look something like this:

Image 5

Let’s go ahead and create a new form!

Connect your MetaMask wallet using the functionality available in the top-right corner of the app. Once this is done, the app automatically recognizes that you were the one who deployed the factory contract and hence, you are the creator of the app too.

This will allow you to create new forms from the UI here.

Image 6

Add a form title, description, and at least one question, and click on Create Form.

This will prompt MetaMask to approve a transaction. Remember that you’re being asked to do this because creation of a form effectively means the creation of a new FeedbackForm contract.

Head back to the home page, and you should see your form there. You can now submit responses on your form!

Image 7

Note that you will be required to pay a small amount of gas in order to record this response (via MetaMask).

Keep building with the web3 stack: Infura, Linea, and MetaMask

And there you have it! Without writing almost any code, we have deployed an entire decentralized form solution for our dapp and gained the ability to not just capture user feedback, but to capture it in a decentralized, web3-native form. Projects like Form-xChange will be a big step towards bringing web2 UX design to web3 applications. Feel free to modify the look and feel of your Next frontend as well as the functionality offered by the smart contracts. You are free (and in fact, encouraged) to make this your own.

Receive our Newsletter