Skip to main content
The fastest way to integrate MoonKey is with the built-in login modal, which your application can integrate in just a few lines of code.
Configure your login methods in the MoonKey Dashboard before using the login modal.

Opening the login modal

The useMoonKey hook exposes a start method that opens the login modal:
import { useMoonKey } from '@moon-key/react-auth';

export default function LoginButton() {
  const { start } = useMoonKey();

  return (
    <button onClick={() => start()}>
      Sign in
    </button>
  );
}
Once the user logs in, the user object will be populated with the authenticated user’s data, and the isAuthenticated state will be true.

Showing the login modal automatically

By default, the login modal will not appear automatically. If you want it to appear automatically on page load (e.g., for unauthenticated users), you can call start() in a useEffect:
import { useMoonKey } from '@moon-key/react-auth';
import { useEffect } from 'react';

export default function AutoLogin() {
  const { start, isAuthenticated } = useMoonKey();

  useEffect(() => {
    // Only show login if user is not authenticated
    if (!isAuthenticated) {
      start();
    }
  }, [isAuthenticated, start]);

  return <div>Welcome!</div>;
}
Be careful when automatically opening the login modal. It may interrupt the user experience if triggered too frequently. Consider using user intent signals (e.g., clicking a button, navigating to a protected route) instead.

Customizing the login modal

You can customize the appearance of the login modal by configuring the appearance prop in your MoonKeyProvider:
import { MoonKeyProvider } from '@moon-key/react-auth';

export default function App() {
  return (
    <MoonKeyProvider
      publishableKey="your_publishable_key"
      config={{
        loginMethods: ['email', 'google', 'apple', 'wallet'],
        appearance: {
          logo: 'https://your-app.com/logo.png',
          loginHeaderTitle: 'Welcome to MyApp',
          loginHeaderDescription: 'Sign in to access your account',
          hideClose: false
        }
      }}
    >
      {/* Your app */}
    </MoonKeyProvider>
  );
}

Available customization options

URL to your company logo. Displayed at the top of the login modal.Example: 'https://myapp.com/logo.png'
loginHeaderTitle
string
Custom title text displayed in the login modal header.Default: 'Sign in'Example: 'Welcome Back'
loginHeaderDescription
string
Custom description text displayed below the title in the login modal.Default: 'Connect your wallet or sign in with email'Example: 'Sign in to access your account'
hideClose
boolean
Whether to hide the close button on the login modal.Default: falseExample: true (useful for required authentication flows)

Example: Complete customization

<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['email', 'google', 'apple'],
    appearance: {
      logo: 'https://myapp.com/brand-logo.svg',
      loginHeaderTitle: 'Welcome to MyApp',
      loginHeaderDescription: 'Create an account or sign in to continue',
      hideClose: false
    }
  }}
>
  {children}
</MoonKeyProvider>

Login methods

The login modal displays authentication options based on the loginMethods configured in your MoonKeyProvider. You can enable multiple methods to give users flexibility in how they authenticate:

Email authentication

Enable email-based passwordless authentication:
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['email']
  }}
>
  {children}
</MoonKeyProvider>
When users select email login, they’ll be prompted to enter their email address. MoonKey will send a one-time passcode (OTP) to verify their identity. Learn more about email authentication.

OAuth providers

Enable social login with Google and Apple:
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['google', 'apple']
  }}
>
  {children}
</MoonKeyProvider>
You must configure OAuth credentials in the MoonKey Dashboard before using OAuth login methods.
Supported OAuth providers:
  • 'google' - Google OAuth
  • 'apple' - Apple Sign In
Additional OAuth providers (Microsoft, Discord, GitHub, etc) are coming soon.
Learn more about OAuth authentication.

Wallet authentication

Enable Web3 wallet login with Sign-In with Ethereum (SIWE) or Sign-In with Solana (SIWS):
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['wallet']
  }}
>
  {children}
</MoonKeyProvider>
This allows users to authenticate by connecting their external wallets (MetaMask, Phantom, etc.) and signing a message.

Multiple login methods

You can enable multiple login methods to give users options:
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['email', 'google', 'apple', 'wallet']
  }}
>
  {children}
</MoonKeyProvider>
The login modal will display all enabled authentication methods, allowing users to choose their preferred option.

Handling authentication states

After the user completes authentication, you can access their information using the useMoonKey hook:
import { useMoonKey } from '@moon-key/react-auth';

export default function UserProfile() {
  const { user, isAuthenticated, ready } = useMoonKey();

  if (!ready) {
    return <div>Loading...</div>;
  }

  if (!isAuthenticated) {
    return <div>Please sign in</div>;
  }

  return (
    <div>
      <h2>Welcome!</h2>
      <p>User ID: {user?.id}</p>
      <p>Email: {user?.email?.address}</p>
      {user?.wallet && (
        <p>Wallet: {user.wallet.address}</p>
      )}
    </div>
  );
}
Learn more about authentication state.

Closing the login modal

Users can close the login modal by:
  • Clicking the close button (X) in the top-right corner (unless hideClose is true)
  • Pressing the Escape key
  • Clicking outside the modal (on the backdrop)
You can also programmatically close the modal after certain actions or events in your application logic.

Creating embedded wallets

By default, MoonKey will not automatically create an embedded wallet when a user logs in. You can configure automatic wallet creation with the embeddedWallets.createOnLogin option:
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['email', 'google'],
    embeddedWallets: {
      createOnLogin: 'always' // Create wallet for every user on login
    }
  }}
>
  {children}
</MoonKeyProvider>
Options:
  • 'always' - Automatically create an embedded wallet for every user on login
  • 'none' - Don’t create wallets automatically (default). You can create them manually later using useCreateWallet
Learn more about automatic wallet creation.

Email OTP configuration

When using email authentication, you can customize the OTP verification experience:
<MoonKeyProvider
  publishableKey="your_publishable_key"
  config={{
    loginMethods: ['email'],
    emailOtp: {
      skipVerifiedSuccess: false,
      expiresIn: 600, // 10 minutes
      verifiedDisplayTime: 3000, // 3 seconds
      verifyEmailTitle: 'Verify your email',
      verifyEmailResendTitle: 'Resend code',
      resendCodeTime: 30, // 30 seconds before allowing resend
      verifiedNewUserMessage: 'Email verified! Setting up your account...',
      verifiedExistingUserMessage: 'Welcome back! Signing you in...',
      verifiedSuccessMessage: 'Success! You are now signed in.'
    }
  }}
>
  {children}
</MoonKeyProvider>

Email OTP configuration options

skipVerifiedSuccess
boolean
default:false
Skip showing the success screen after email verification and immediately proceed to the application.
expiresIn
number
default:600
Time in seconds before the OTP expires (default: 600 = 10 minutes).
verifiedDisplayTime
number
default:3000
Time in milliseconds to display the success message before closing the modal (default: 3000 = 3 seconds).
verifyEmailTitle
string
default:"Verify your email"
Title text for the email verification screen.
verifyEmailResendTitle
string
default:"Didn't receive a code?"
Title text for the resend code prompt.
resendCodeTime
number
default:30
Time in seconds before users can request a new OTP code (default: 30 seconds).
verifiedNewUserMessage
string
default:"Email verified!"
Success message shown to new users after verification.
verifiedExistingUserMessage
string
default:"Welcome back!"
Success message shown to existing users after verification.
verifiedSuccessMessage
string
default:"Success!"
Generic success message shown after verification.
Learn more about email authentication.

Prefilling user information

You can prefill the login form with user information (e.g., email address) to streamline the authentication flow:
import { useMoonKey } from '@moon-key/react-auth';

export default function PrefillLoginButton() {
  const { start } = useMoonKey();

  const handleLogin = () => {
    start({
      prefill: {
        type: 'email',
        value: '[email protected]'
      }
    });
  };

  return <button onClick={handleLogin}>Sign in with [email protected]</button>;
}
This is useful when you already know the user’s email (e.g., from a marketing campaign, invitation link, or previous session).

Prefill configuration

prefill
object
Prefill configuration for the login form.

Complete example

Here’s a complete example showing login modal integration with all customization options:
'use client';
import { MoonKeyProvider, useMoonKey } from '@moon-key/react-auth';

function App() {
  return (
    <MoonKeyProvider
      publishableKey="your_publishable_key"
      config={{
        loginMethods: ['email', 'google', 'apple', 'wallet'],
        embeddedWallets: {
          createOnLogin: 'always'
        },
        appearance: {
          logo: 'https://myapp.com/logo.png',
          loginHeaderTitle: 'Welcome to MyApp',
          loginHeaderDescription: 'Sign in to access your account',
          hideClose: false
        },
        emailOtp: {
          skipVerifiedSuccess: false,
          verifiedDisplayTime: 2000,
          verifyEmailTitle: 'Check your email',
          verifiedNewUserMessage: 'Account created successfully!',
          verifiedExistingUserMessage: 'Welcome back!'
        }
      }}
    >
      <Dashboard />
    </MoonKeyProvider>
  );
}

function Dashboard() {
  const { user, isAuthenticated, ready, start } = useMoonKey();

  if (!ready) {
    return <div>Loading...</div>;
  }

  if (!isAuthenticated) {
    return (
      <div>
        <h1>Welcome to MyApp</h1>
        <button onClick={() => start()}>Sign in</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Dashboard</h1>
      <p>Welcome, {user?.email?.address}!</p>
      {user?.wallet && (
        <p>Your wallet: {user.wallet.address}</p>
      )}
    </div>
  );
}

export default App;

Next steps