Add to Existing Project
Configure Your Authentication & Styling
Create two configuration files that will customize your authentication methods and UI styles.
Create your configuration files
- In your project root, create a
config.ts
file - In your project root, create a
tailwind.config.ts
file
You can customize these by visiting our demo app - use the interactive sandbox to explore different authentication methods and styling options. When ready, click ‘Code preview’ to export your customized configuration files.
Basic configuration example
Here’s a basic configuration to get you started:
tailwind.config.ts
Important: If your tailwind.config.ts
already contains any existing
config information, be sure to wrap it with withAccountKitUi
as shown above.
Don’t replace your existing config - just wrap it!
Update your global.css
to include the config:
Note: If still using Tailwind v3, skip this step as the
tailwind.config.ts
file is used by default.
config.ts
import { const createConfig: (props: CreateConfigProps, ui?: AlchemyAccountsUIConfig) => AlchemyAccountsConfigWithUIWraps the createConfig
that is exported from @aa-sdk/core
to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).
createConfig, const cookieStorage: (config?: {
sessionLength?: number;
domain?: string;
}) => StorageFunction to create cookie based Storage
cookieStorage } from "@account-kit/react";
import { class QueryClientQueryClient } from "@tanstack/react-query";
import { const arbitrumSepolia: ChainarbitrumSepolia, function alchemy(config: AlchemyTransportConfig): AlchemyTransportCreates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.
alchemy } from "@account-kit/infra";
export const const config: AlchemyAccountsConfigWithUIconfig = function createConfig(props: CreateConfigProps, ui?: AlchemyAccountsUIConfig): AlchemyAccountsConfigWithUIWraps the createConfig
that is exported from @aa-sdk/core
to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).
createConfig(
{
transport: AlchemyTransporttransport: function alchemy(config: AlchemyTransportConfig): AlchemyTransportCreates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.
alchemy({
// Replace with your API key
apiKey: stringapiKey: "YOUR_API_KEY",
}),
chain: Chainchain: const arbitrumSepolia: ChainarbitrumSepolia,
ssr?: boolean | undefinedEnable this parameter if you are using the config in an SSR setting (eg. NextJS) Turing this setting on will disable automatic hydration of the client store
ssr: true,
storage?: CreateStorageFn | undefinedstorage: const cookieStorage: (config?: {
sessionLength?: number;
domain?: string;
}) => StorageFunction to create cookie based Storage
cookieStorage,
enablePopupOauth?: boolean | undefinedIf set, calls preparePopupOauth
immediately upon initializing the signer. If you intend to use popup-based OAuth login, you must either set this option to true or manually ensure that you call signer.preparePopupOauth()
at some point before the user interaction that triggers the OAuth authentication flow.
enablePopupOauth: true,
// For gas sponsorship (optional)
// Learn more here: https://www.alchemy.com/docs/wallets/transactions/sponsor-gas/sponsor-gas-evm
policyId?: string | string[] | undefinedpolicyId: "YOUR_POLICY_ID",
},
{
auth?: {
addPasskeyOnSignup?: boolean;
header?: React.ReactNode;
hideError?: boolean;
onAuthSuccess?: () => void;
sections: AuthType[][];
hideSignInText?: boolean;
} | undefinedauth: {
sections: AuthType[][]Each section can contain multiple auth types which will be grouped together and separated by an OR divider
sections: [
[{ type: "email"type: "email" }],
[
{ type: "passkey"type: "passkey" },
{ type: "social"type: "social", authProviderId: KnownAuthProviderauthProviderId: "google", mode: "popup"mode: "popup" },
],
],
addPasskeyOnSignup?: boolean | undefinedIf this is true, then auth components will prompt users to add a passkey after signing in for the first time
addPasskeyOnSignup: true,
},
},
);
export const const queryClient: QueryClientqueryClient = new new QueryClient(config?: QueryClientConfig): QueryClientQueryClient();
Remember to replace "YOUR_API_KEY"
with your app’s API Key.
Important: The chain you import (like arbitrumSepolia
) must come from
the @account-kit/infra
package, not from viem
. Additionally, make sure
this chain is enabled in both your Alchemy app and Smart Wallets config policy
in the dashboard.
Note:
You can add an "external_wallets"
auth method to your config to allow connecting existing external EOAs (such as MetaMask) using our built-in connectors and WalletConnect. Learn more here
[
{
type: stringtype: "external_wallets",
walletConnect: {
projectId: string;
}walletConnect: { projectId: stringprojectId: "your-project-id" },
},
];
Initializing Alchemy Provider
Wrap your application with the Alchemy Provider to enable embedded wallet functionality.
1. Create a file: providers.tsx
2. Update your layout.tsx
3. Add authentication to your app
Now you can use the Alchemy React components to add wallet authentication anywhere in your app.
Example page with login functionality
Now that you have basic authentication working, you can explore additional features:
Learn how to perform transactions by sending user operations with your smart wallet.
Customize and style the UI components to match your application’s design.
Enable gasless transactions by setting up gas sponsorship for your users.
Enhance security by implementing multi-factor authentication for your users.