Table of contents

How to Create a Web3 form with Typeform and Dynamic: A Step-by-Step Guide

https://www.dynamic.xyz/blog/typeform-dynamic-guide
How to Create a Web3 form with Typeform and Dynamic: A Step-by-Step Guide
How to Create a Web3 form with Typeform and Dynamic: A Step-by-Step Guide
Download

Overview

Get ready to take your token-gated or enabled community to the next level. With Dynamic and Typeform, creating a web3 form has never been easier! Let's dive in and explore how to set up everything in just a few minutes.

Step 1: Setting up your Typeform

To start, you can set up a custom form and define any questions you require. It can be as short or as long as you’d like, completely independent of the wallet connection flow. Once it’s set up, head over to the “share” tab of the Typeform

And grab the unique identifier at the end of this link:

https://form.typeform.com/to/UNIQUEFORMCODE

That is our unique form code which we’ll use as our ID below.

Step 2: Create a hidden field

As part of the form, we’ll create a hidden field that will capture the user’s wallet. We do so by going to Create -> Logic -> Personalize with data, and chose Hidden fields:

We’ll add a new hidden field called “walletaddress”:

And publish our form!

Step 3: Setting up your web page

Now that we set  up our Typeform, let’s move on to creating our web page with wallet login. First, we’ll import the relevant libraries needed from Dynamic and Typeform:

<script>import {
 DynamicContextProvider,
 DynamicWidget,
 FilterWallets,
 useDynamicContext
} from "@dynamic-labs/sdk-react";
</script>

Then we’ll define the basic Dynamic component, following our getting started guide: (you can get an environment ID when creating your account)

<script>const App = () => (
 <DynamicContextProvider>;
  settings={{
   environmentId: "environment ID"
  }}
 >
 <DynamicWidget />;
 </DynamicContextProvider>;
);

export default App;</script>

To simplify our UI, we will filter the amount of wallets shown, only showing 4 to start. To do so, we’ll add the following snippet to Dynamic’s settings page.

<script>walletsFilter: FilterWallets([
 "metamask",
 "coinbase",
 "walletconnect",
 "rainbow"
])</script>

At this point, we can create a Typeform component, and wrap it in the user logic to ensure it only shows up after a user logs in. Note that you should replace the ID in the snippet with the form ID from the first step. Note, we are also adding a hidden field:

<script>import { Widget } from "@typeform/embed-react";

const TypeformComponent = () => {
 const { user, primaryWallet } = useDynamicContext();

 return (
  <>
    {user && (
      <Widget
        id="UNIQUEFORMCODE"
        style={{ width: "100%", height: "600px" }}
        className="my-form"
        hidden={{
          walletaddress: primaryWallet.address
        }}
      />
    )}
   </>
 );
};</script>

And lastly, add "TypeformComponent".

Putting it all together, we’ll get the following app:

Note: because the gating happens on the client (the form URL is located within the React component), it should not be used for forms where privacy and security are critical.

Step 4: Email verification (optional)

We can further expand the integration by capturing and verifying email addresses before logging individuals in. 

We will add an extra hidden field named email in Typeform to store the email address. Then, we will navigate to the Dynamic dashboard and under the "Integrations" section, select "Information Capture". In this section, we will choose the "email" field and mark it as "unique and verified". This action will trigger a flow for authentication that requests the user's email and sends them a verification code for confirmation.

Now that the email field is confirmed, we can send it as an additional hidden field in the Typeform:

<script>hidden={{
 walletaddress: primaryWallet.address,
 email: user.email
}}</script>

Step 5: Connecting without authentication (optional)

Depending on your use case, you can either decide to just capture wallet addresses by letting customers connect without needing to authenticate. To do so, we first need to specify connect-only in the settings section:

<script>initialAuthenticationMode: 'connect-only' </script>

We then need to switch the user object, which will be undefined until a user is authenticated. Instead, we will grab primaryWallet from DynamicContext:

<script>const { primaryWallet } = useDynamicContext();</script>

And pull the information from it:

<script>walletaddress: primaryWallet.address </script> 

Next steps

This guide is a simple illustration of how to set up a Typeform with wallet information capture. As a next step, we encourage you to explore the Dynamic docs in detail to learn more about our features.

Share this article

https://www.dynamic.xyz/blog/typeform-dynamic-guide
Itai Turbahn

Itai is the co-founder and CEO of Dynamic Before Dynamic, Itai spent 7 years in product management leadership positions, and was previously a consultant at the Boston Consulting Group. Itai holds an MBA from Harvard Business School and B.Sc degrees in EECS and Economics from MIT.

Related articles

Dynamic takes minutes to set up

(Oh, and we also offer a free multi-chain wallet adapter)

Get started