Simplify user onboarding with “preferred placement”
Overview
For the best onboarding experience, we recommend adding a highly visible ‘Create’ or ‘Create Wallet’ button to your dapp’s homepage (referred to as “preferred placement” - see example images below).

For new users, navigating through “Connect” in order to get started is unintuitive, and requires them to understand that they do not need a Coinbase Wallet yet to create one.
This difficulty can be prevented by streamlining the onboarding experience and adding 'preferred placement' aka 'create wallet' button to a page. This simplifies the choices for a new user and gets them ready to use your dapp in a few seconds. Plus, we're offering additional incentives to dapps who implement this new approach.
We recommend two paths for implementation:
- Match our branded Create Wallet button
- Match your own apps look and feel in the Create button
Example:



Implementation
With wagmi
To implement the Create Wallet button with wagmi, all you need to do to trigger the create is call connect.
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useConnect } from "wagmi";
import { CoinbaseWalletLogo } from "./CoinbaseWalletLogo";
const GRADIENT_BORDER_WIDTH = 2;
const buttonStyles = {
background: "transparent",
border: "1px solid transparent",
boxSizing: "border-box",
};
const contentWrapperStyle = {
position: "relative",
};
function Gradient({ children, style, isAnimationDisabled = false }) {
const [isAnimating, setIsAnimating] = useState(false);
const gradientStyle = useMemo(() => {
const rotate = isAnimating ? "720deg" : "0deg";
return {
transform: `rotate(${rotate})`,
transition: isAnimating
? "transform 2s cubic-bezier(0.27, 0, 0.24, 0.99)"
: "none",
...style,
};
}, [isAnimating, style]);
const handleMouseEnter = useCallback(() => {
if (isAnimationDisabled || isAnimating) return;
setIsAnimating(true);
}, [isAnimationDisabled, isAnimating, setIsAnimating]);
useEffect(() => {
if (!isAnimating) return;
const animationTimeout = setTimeout(() => {
setIsAnimating(false);
}, 2000);
return () => {
clearTimeout(animationTimeout);
};
}, [isAnimating]);
return (
<div style={contentWrapperStyle} onMouseEnter={handleMouseEnter}>
<div className="gradient-background" style={gradientStyle} />
{children}
</div>
);
}
export function BlackCreateWalletButton({ height = 66, width = 200 }) {
const { connectors, connect } = useConnect();
const minButtonHeight = 48;
const minButtonWidth = 200;
const buttonHeight = Math.max(minButtonHeight, height);
const buttonWidth = Math.max(minButtonWidth, width);
const gradientDiameter = Math.max(buttonHeight, buttonWidth);
const styles = useMemo(
() => ({
gradientContainer: {
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "black",
borderRadius: buttonHeight / 2,
height: buttonHeight,
width: buttonWidth,
boxSizing: "border-box",
overflow: "hidden",
},
gradient: {
background:
"conic-gradient(from 180deg, #45E1E5 0deg, #0052FF 86.4deg, #B82EA4 165.6deg, #FF9533 255.6deg, #7FD057 320.4deg, #45E1E5 360deg)",
position: "absolute",
top: -buttonHeight - GRADIENT_BORDER_WIDTH,
left: -GRADIENT_BORDER_WIDTH,
width: gradientDiameter,
height: gradientDiameter,
},
buttonBody: {
display: "flex",
justifyContent: "center",
alignItems: "center",
boxSizing: "border-box",
backgroundColor: "#000000",
height: buttonHeight - GRADIENT_BORDER_WIDTH * 2,
width: buttonWidth - GRADIENT_BORDER_WIDTH * 2,
fontFamily: "Arial, sans-serif",
fontWeight: "bold",
fontSize: 18,
borderRadius: buttonHeight / 2,
position: "relative",
paddingRight: 10,
},
}),
[buttonHeight, buttonWidth, gradientDiameter]
);
const createWallet = useCallback(() => {
const coinbaseWalletConnector = connectors.find(
(connector) => connector.id === "coinbaseWalletSDK"
);
if (coinbaseWalletConnector) {
connect({ connector: coinbaseWalletConnector });
}
}, [connectors, connect]);
return (
<button style={buttonStyles} onClick={createWallet}>
<div style={styles.gradientContainer}>
<Gradient style={styles.gradient}>
<div style={styles.buttonBody}>
<CoinbaseWalletLogo containerStyles={{ paddingRight: 10 }} />
Create Wallet
</div>
</Gradient>
</div>
</button>
);
}Notes
- For more detail, view the
useConnectdocumentation. - Upon successful connection, account information can be accessed via data
returned from
useConnect, or viauseAccount.
With CoinbaseWalletSDK only
To implement the Create Wallet button using only the SDK, all you need to do is send an eth_requestAccounts request.
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { CoinbaseWalletSDK } from "@coinbase/wallet-sdk";
import { CoinbaseWalletLogo } from "./CoinbaseWalletLogo";
const GRADIENT_BORDER_WIDTH = 2;
const buttonStyles = {
background: "transparent",
border: "1px solid transparent",
boxSizing: "border-box",
};
const contentWrapperStyle = {
position: "relative",
};
function Gradient({ children, style, isAnimationDisabled = false }) {
const [isAnimating, setIsAnimating] = useState(false);
const gradientStyle = useMemo(() => {
const rotate = isAnimating ? "720deg" : "0deg";
return {
transform: `rotate(${rotate})`,
transition: isAnimating
? "transform 2s cubic-bezier(0.27, 0, 0.24, 0.99)"
: "none",
...style,
};
}, [isAnimating, style]);
const handleMouseEnter = useCallback(() => {
if (isAnimationDisabled || isAnimating) return;
setIsAnimating(true);
}, [isAnimationDisabled, isAnimating, setIsAnimating]);
useEffect(() => {
if (!isAnimating) return;
const animationTimeout = setTimeout(() => {
setIsAnimating(false);
}, 2000);
return () => {
clearTimeout(animationTimeout);
};
}, [isAnimating]);
return (
<div style={contentWrapperStyle} onMouseEnter={handleMouseEnter}>
<div className="gradient-background" style={gradientStyle} />
{children}
</div>
);
}
const sdk = new CoinbaseWalletSDK({
appName: "My Dapp With Vanilla SDK",
appLogoUrl: "https://example.com/logo.png",
appChainIds: [84532],
});
const provider = sdk.makeWeb3Provider();
export function BlackCreateWalletButton({ height = 66, width = 200 }) {
const minButtonHeight = 48;
const minButtonWidth = 200;
const buttonHeight = Math.max(minButtonHeight, height);
const buttonWidth = Math.max(minButtonWidth, width);
const gradientDiameter = Math.max(buttonHeight, buttonWidth);
const styles = useMemo(
() => ({
gradientContainer: {
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "black",
borderRadius: buttonHeight / 2,
height: buttonHeight,
width: buttonWidth,
boxSizing: "border-box",
overflow: "hidden",
},
gradient: {
background:
"conic-gradient(from 180deg, #45E1E5 0deg, #0052FF 86.4deg, #B82EA4 165.6deg, #FF9533 255.6deg, #7FD057 320.4deg, #45E1E5 360deg)",
position: "absolute",
top: -buttonHeight - GRADIENT_BORDER_WIDTH,
left: -GRADIENT_BORDER_WIDTH,
width: gradientDiameter,
height: gradientDiameter,
},
buttonBody: {
display: "flex",
justifyContent: "center",
alignItems: "center",
boxSizing: "border-box",
backgroundColor: "#000000",
height: buttonHeight - GRADIENT_BORDER_WIDTH * 2,
width: buttonWidth - GRADIENT_BORDER_WIDTH * 2,
fontFamily: "Arial, sans-serif",
fontWeight: "bold",
fontSize: 18,
borderRadius: buttonHeight / 2,
position: "relative",
paddingRight: 10,
},
}),
[buttonHeight, buttonWidth, gradientDiameter]
);
const createWallet = useCallback(async () => {
try {
const [address] = await provider.request({
method: "eth_requestAccounts",
});
handleSuccess(address);
} catch (error) {
handleError(error);
}
}, [handleSuccess, handleError]);
return (
<button style={buttonStyles} onClick={createWallet}>
<div style={styles.gradientContainer}>
<Gradient style={styles.gradient}>
<div style={styles.buttonBody}>
<CoinbaseWalletLogo containerStyles={{ paddingRight: 10 }} />
Create Wallet
</div>
</Gradient>
</div>
</button>
);
}Benefits for you:
By integrating a create wallet button on the front page of your app, you are eligible for:
- Increased volume of gas credits via our Cloud paymaster
- Comarketing and promotional opportunities with Coinbase
- Featured placement in our dapp listings on homebase.coinbase.com
For more information, please fill out the form on coinbase.com/smart-wallet so our team can get in touch with you.