> ## Documentation Index
> Fetch the complete documentation index at: https://pond.dflow.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Turnkey

> How to add Turnkey to a Next.js + React app

Use Turnkey Embedded Wallet Kit to add authentication and embedded wallets to a
Next.js + React app.

## Prerequisites

Create a [Turnkey organization](https://docs.turnkey.com/getting-started/quickstart) in the [Turnkey dashboard](https://app.turnkey.com),
enable **Auth Proxy**, **email OTP**, and **passkeys**.

Copy your **Organization ID** and **Auth Proxy Config ID**.

## Step-by-step (Next.js + React)

<Steps>
  <Step title="Install the React Wallet Kit">
    Install the Turnkey React Wallet Kit in your Next.js app.

    <AccordionGroup>
      <Accordion title="Install dependencies">
        ```bash theme={null}
        npm install @turnkey/react-wallet-kit
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Add environment variables">
    Store your IDs in `.env.local` so your app can initialize Turnkey.

    <AccordionGroup>
      <Accordion title="Create .env.local">
        ```bash theme={null}
        NEXT_PUBLIC_ORGANIZATION_ID="your-org-id"
        NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID="your-auth-proxy-config-id"
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Wrap your app with TurnkeyProvider">
    Initialize Turnkey at the app root and include the wallet kit styles.

    <Tabs>
      <Tab title="App Router">
        Create a client-side provider component, then wrap it in `app/layout.tsx`.

        <AccordionGroup>
          <Accordion title="app/providers.tsx">
            ```tsx theme={null}
            // app/providers.tsx
            "use client";

            import {
              TurnkeyProvider,
              TurnkeyProviderConfig,
            } from "@turnkey/react-wallet-kit";

            const turnkeyConfig: TurnkeyProviderConfig = {
              organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
              authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
            };

            export function Providers({ children }: { children: React.ReactNode }) {
              return (
                <TurnkeyProvider
                  config={turnkeyConfig}
                  callbacks={{
                    onError: (error) => console.error("Turnkey error:", error),
                  }}
                >
                  {children}
                </TurnkeyProvider>
              );
            }
            ```
          </Accordion>

          <Accordion title="app/layout.tsx">
            ```tsx theme={null}
            // app/layout.tsx
            import "@turnkey/react-wallet-kit/styles.css";
            import { Providers } from "./providers";

            export default function RootLayout({
              children,
            }: {
              children: React.ReactNode;
            }) {
              return (
                <html lang="en">
                  <body>
                    <Providers>{children}</Providers>
                  </body>
                </html>
              );
            }
            ```
          </Accordion>
        </AccordionGroup>
      </Tab>

      <Tab title="Pages Router">
        Wrap your app in `pages/_app.tsx`.

        <AccordionGroup>
          <Accordion title="pages/_app.tsx">
            ```tsx theme={null}
            // pages/_app.tsx
            import type { AppProps } from "next/app";
            import "@turnkey/react-wallet-kit/styles.css";
            import {
              TurnkeyProvider,
              TurnkeyProviderConfig,
            } from "@turnkey/react-wallet-kit";

            const turnkeyConfig: TurnkeyProviderConfig = {
              organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!,
              authProxyConfigId: process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID!,
            };

            export default function App({ Component, pageProps }: AppProps) {
              return (
                <TurnkeyProvider
                  config={turnkeyConfig}
                  callbacks={{
                    onError: (error) => console.error("Turnkey error:", error),
                  }}
                >
                  <Component {...pageProps} />
                </TurnkeyProvider>
              );
            }
            ```
          </Accordion>
        </AccordionGroup>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Connect a user">
    Use Turnkey’s modal and show a connected state when login completes.

    <AccordionGroup>
      <Accordion title="Connect button">
        ```tsx theme={null}
        "use client";

        import {
          AuthState,
          ClientState,
          useTurnkey,
        } from "@turnkey/react-wallet-kit";

        export default function ConnectButton() {
          const { handleLogin, authState, clientState } = useTurnkey();

          if (clientState === undefined || clientState === ClientState.Loading) {
            return <p>Loading...</p>;
          }
          if (clientState === ClientState.Error) {
            return <p>Turnkey failed to initialize.</p>;
          }
          if (authState === AuthState.Authenticated) {
            return <p>Connected</p>;
          }

          return <button onClick={handleLogin}>Connect Wallet</button>;
        }
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Theme the Turnkey UI">
    Use [theming](https://docs.turnkey.com/sdks/react/ui-customization) to customize
    the Turnkey UI.
  </Step>
</Steps>

<Info>
  See [authentication](https://docs.turnkey.com/sdks/react/auth) for custom login
  flows.
</Info>
