Appearance
Configuring Privy's appearance in your app
Privy's UIs are highly-customizable to seamlessly match the branding and design system of your app.
Read below to learn how to customize several aspects of Privy, including your app's name, logo, theme, login ordering, displayed wallet options, and more.
Sample UIs available in Figma
Looking for sample UIs in Figma? Use Privy's Figma community file, which contains sample UIs for progressive onboarding, authentication, and embedded wallet transaction flows.
App name
To configure the name of your application, go to the Privy Dashboard and select your desired app from the dropdown in the navigation bar.
Then, navigate to the Customization page for your app and enter your app's name (as you'd like it to be presented to your users) in the App name field.
The App name you enter here will be used to identify your application for your users, throughout Privy's UIs in your app and emails and SMSes sent to users with login codes.
Logo
To configure a logo for your application, go to the Privy Dashboard and select your desired app from the dropdown in the navigation bar.
Then, navigate to the Customization page for your app and enter a URL for your app's logo in the Your logo field. We recommend using an asset with a 2:1 aspect ratio and with a size of 180px x 90px. SVGs are not allowed due to poor compatibility with modern email clients.
The Logo you save here will be used in the upfront login modal shown to users within your app, as well as emails sent to your users with their login codes. If you'd like to use a different logo for the upfront login modal versus the login email, you can override the logo shown in the login modal via the config.appearance.logo
property of the PrivyProvider
component, like so:
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults to the logo you set in the Dashboard
logo: 'https://your.logo.url',
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
You can also opt to show no logo in the login modal by passing an empty string (''
) to appearance.logo
.
Login screen header text
To configure the header text of the Privy login modal's landing screen, set a custom string
as the config.appearance.landingHeader
property of the PrivyProvider
component, like so:
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults to 'Log in or sign up'
landingHeader: 'Your custom header text',
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
We recommend using a string
of length 35 or less. Strings longer than the width of the login modal will be ellipsified.
If you do not set a custom header text, it will default to 'Log in or sign up'.
Login screen message text
To configure the message text of the Privy login modal's login screen, set a custom string
as the config.appearance.loginMessage
property of the PrivyProvider
component, like so:
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults to 'Log in or sign up'
loginMessage: 'Your custom header text',
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
We recommend using a string
of length 100 or less. Strings longer than 100 characters will be truncated.
If you do not set a custom header text, there is no default.
Theme
To configure a theme for your application, set the config.appearance.theme
property of the PrivyProvider
to 'light'
, 'dark'
, or a custom color as a hexadecimal string. The theme
sets the core foreground and background colors for Privy's UIs in your app.
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults to 'light'
theme: 'dark',
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
If you set the theme
to 'light'
or 'dark'
, Privy's UIs will use Privy's standard light and dark themes, respectively. You can also set Privy's theme based on the user's system preferences by following this guide.
If you set the theme
to a custom hexadecimal color, the theme
color will be used as the primary background color for Privy's UIs. All other colors will be automatically generated by modulating the luminance of the theme color you set. This creates a cohesive palette that matches your app's branding.
TIP
If you set a custom hexadecimal color as your theme
, we strongly recommend choosing a color that is either light or dark (>80% or <20% luminance, as defined by HSL). This helps ensure there is sufficient contrast between foreground and background colors in the Privy modal.
If you'd like, you may also override specific colors in Privy's UI to match your brand palette.
Order of login methods
Privy allows you to enable both web2 (email, phone, and socials) and web3 (external wallet) login methods for your app. You can customize Privy to configure how you want these login methods to appear.
TIP
Though Privy provides careful defaults around ordering of login methods, you can also fully customize the ordering of login methods by using the loginMethodsAndOrder
override.
This will allow you to fully customize the ordering of your login methods, with any overflow items (after the first four) going to a secondary page.
For many apps, it is preferable to display wallet (or social) logins upfront and have users click to access the rest of the options. If you'd like to default to either web2 or web3 login methods appearing in your login modal, you can do so by setting the config.appearance.showWalletLoginFirst
property of the PrivyProvider
like so:
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults to true
showWalletLoginFirst: true,
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
External wallet options
To customize the external wallet options for your app, pass in a WalletListEntry
array to the config.appearance.walletList
property. When users login with, connect, or link an external wallet in your app, the possible options (e.g. MetaMask, Rainbow, WalletConnect) will be presented to users in the order you configure them in this array.
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
// Defaults ['detected_wallets', 'metamask', 'coinbase_wallet', 'rainbow', 'wallet_connect']
walletList: ['metamask', 'rainbow', 'wallet_connect'],
...insertTheRestOfYourAppearanceConfig,
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
You can also configure which wallet options to show at runtime, by passing in walletList
to the connectWallet
method:
tsx
import {usePrivy} from '@privy-io/react-auth';
const {connectWallet} = usePrivy();
<button onClick={() => connectWallet({walletList: ['rainbow', 'coinbase_wallet']})}>
Login with email and sms only
</button>;
The possible wallets to include in the array are metamask
, coinbase_wallet
, rainbow
, zerion
, phantom
, wallet_connect
, uniswap
, rabby_wallet
, cryptocom
, okx_wallet
, safe
, and detected_wallets
.
The detected_wallets
option includes all wallets that Privy detects which are not explicitly included elsewhere in the walletList array. As an example, if your user has the Zerion browser extension installed, it will appear under detected_wallets
– unless you include zerion
elsewhere in the walletList
array, in which case it will appear in the placement of zerion
.
INFO
Privy detects wallets via EIP6963 injection, window.ethereum
injection, or a mobile wallet's in-app browser.
Configuring the Coinbase Smart Wallet
The Coinbase Smart Wallet is available to all Privy developers. To get set up, you will simply need to add Coinbase Wallet to your login flow and configure your smart wallet preference in the config.externalWallets.coinbaseWallet.connectionOptions
property.
tsx
<PrivyProvider
appId="your-privy-app-id"
config={{
appearance: {
walletList: ['coinbase_wallet'],
...insertTheRestOfYourAppearanceConfig,
},
externalWallets: {
coinbaseWallet: {
// Valid connection options include 'eoaOnly' (default), 'smartWalletOnly', or 'all'
connectionOptions: 'smartWalletOnly',
},
},
...insertTheRestOfYourPrivyProviderConfig,
}}
>
{children}
</PrivyProvider>
By default, Privy will set config.externalWallets.coinbaseWallet.connectionOptions
to eoaOnly
such that smart wallets are not enabled. This will surface the existing Coinbase Wallet extension for users who have it installed.
The following are valid connectionOptions
property values:
eoaOnly
: (default) The Privy SDK will only surface the Coinbase Wallet extension or Coinbase Wallet mobile app QR code. Users who do not have it installed will be prompted to install it.smartWalletOnly
: The Privy SDK will surface the Coinbase Smart Wallet for all users.all
: The Privy SDK will detect whether the user has the Coinbase wallet extension installed. It will popup the Coinbase wallet if they do and the Smart Wallet otherwise.
TIP
Smart Wallet supports a limited number of chains. If using all
or smartWalletOnly
connection options, be sure that your PrivyProvider default chain and supported chains list is a subset of Coinbase's supported list.
CSS Overrides
Beyond the configuration properties above, Privy also enables you to explicitly override specific colors in the login modal, to further match your product's design system and color palette. You might use these overrides if you are using a default Privy theme
('light' or 'dark') and wish to tweak a certain color, or if you set a custom theme
and want to use your exact brand colors instead of the automatically-generated ones.
To explicitly override colors in your Privy modal, simply add the corresponding CSS variable for the color to the CSS :root
of your app, and set it to your custom color. The possible CSS variables are listed below; we encourage you to use your browser's developer tools to experiment with different color combinations to find the right one for your app!
css
:root {
--privy-border-radius-sm: 'your-custom-value';
--privy-border-radius-md: 'your-custom-value';
--privy-border-radius-lg: 'your-custom-value';
--privy-border-radius-full: 'your-custom-value';
--privy-color-background: 'your-custom-value';
--privy-color-background-2: 'your-custom-value';
--privy-color-foreground: 'your-custom-value';
--privy-color-foreground-2: 'your-custom-value';
--privy-color-foreground-3: 'your-custom-value';
--privy-color-foreground-4: 'your-custom-value';
--privy-color-foreground-accent: 'your-custom-value';
--privy-color-accent: 'your-custom-value';
--privy-color-accent-light: 'your-custom-value';
--privy-color-accent-lightest: 'your-custom-value';
--privy-color-accent-dark: 'your-custom-value';
--privy-color-accent-darkest: 'your-custom-value';
--privy-color-success: 'your-custom-value';
--privy-color-error: 'your-custom-value';
--privy-color-error-light: 'your-custom-value';
}