Quickstart
Select a framework to start:- Next.js - App
- Next.js - Pages
- React
- Vanilla JS
- Android
- iOS
- React Native
Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s domain to your project’s Authorized Domains.
Install the Next.js SDK and configure your API key
- In your Next.js app, run the command to install the SDK:
npm install @stytch/nextjs --save
- Then add your Stytch
public_tokento your project’s.envfile:
NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN=$PUBLIC_TOKEN
Set up a Stytch context provider
- Create a custom
Stytchwrapper component that initializes the Stytch client.
'use client';
import { ReactNode } from 'react';
import { createStytchClient, StytchProvider } from '@stytch/nextjs';
const stytchClient = createStytchClient(
process.env.NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN
);
export default function Stytch({ children }: { children: ReactNode }) {
return <StytchProvider stytch={stytchClient}>{children}</StytchProvider>;
}
- Wrap your application with
<Stytch>to provide context to all child components:
import Stytch from './components/stytch-provider';
export default function RootLayout({
children,
}: {
children: ReactNode
}) {
return (
<html>
<body>
<Stytch>{children}</Stytch>
</body>
</html>
);
}
Add <StytchLogin> UI component
- Create a
<StytchLogin>component. - Set authentication methods and relevant options in the config object.
import { Products, StytchLogin } from '@stytch/nextjs';
const config = {
products: [Products.emailMagicLinks, Products.oauth],
oauthOptions: {
providers: [{ type: 'google' }],
},
sessionOptions: {
sessionDurationMinutes: 60,
},
};
export const LoginOrSignupForm = () => {
return <StytchLogin config={config} />;
};
Add <LoginOrSignupForm> to your login page(s)
- Add
<LoginOrSignupForm>to your/loginpage.
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useStytchSession } from '@stytch/nextjs';
import { LoginOrSignupForm } from "src/components/LoginOrSignupForm";
export default function Login() {
const { session, isInitialized } = useStytchSession();
const router = useRouter();
useEffect(() => {
if (session && isInitialized) {
router.replace("/home");
}
}, [session, isInitialized, router]);
if (!isInitialized || session) {
return <p>Loading...</p>;
}
return <LoginOrSignupForm/>;
}
- If you’re using separate routes, add
<LoginOrSignupForm>to your/authenticateredirect route as well, e.g.app/authenticate/page.jsxorpages/authenticate.jsx.
Handle session and user data
useStytchSession() lets you easily check for an active session.Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s domain to your project’s Authorized Domains.
Install the Next.js SDK and configure your API key
- In your Next.js app, run the command to install the SDK:
npm install @stytch/nextjs --save
- Then add your Stytch
public_tokento your project’s.envfile:
NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN=$PUBLIC_TOKEN
Wrap your application in <StytchProvider>
- Initialize the Stytch client through
createStytchClient(). - Pass the Stytch UI client to the
<StytchProvider>component at the root of your application, making it accessible to all child components.
// For Page Router setups
import { createStytchClient, StytchProvider } from '@stytch/nextjs';
const stytch = createStytchClient(process.env.NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN!);
export default function MyApp({ Component, pageProps }: AppProps) {
return (
<StytchProvider stytch={stytch}>
<Component {...pageProps} />
</StytchProvider>
);
}
Add <StytchLogin> UI component
- Create a
<StytchLogin>component. - Set authentication methods and relevant options in the config object.
import { Products, StytchLogin } from '@stytch/nextjs';
const config = {
products: [Products.emailMagicLinks, Products.oauth],
oauthOptions: {
providers: [{ type: 'google' }],
},
sessionOptions: {
sessionDurationMinutes: 60,
},
};
export const LoginOrSignupForm = () => {
return <StytchLogin config={config} />;
};
Add <LoginOrSignupForm> to your login page(s)
- Add
<LoginOrSignupForm>to your/loginpage.
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useStytchSession } from '@stytch/nextjs';
import { LoginOrSignupForm } from "src/components/LoginOrSignupForm";
export default function Login() {
const { session, isInitialized } = useStytchSession();
const router = useRouter();
useEffect(() => {
if (session && isInitialized) {
router.replace("/home");
}
}, [session, isInitialized, router]);
if (!isInitialized || session) {
return <p>Loading...</p>;
}
return <LoginOrSignupForm/>;
}
- If you’re using separate routes, add
<LoginOrSignupForm>to your/authenticateredirect route as well, e.g.app/authenticate/page.jsxorpages/authenticate.jsx.
Handle session and user data
useStytchSession() lets you easily check for an active session.Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s domain to your project’s Authorized Domains.
Install the React SDK and configure your API key
npm install @stytch/react --save
Wrap your application in <StytchProvider>
- Initialize the Stytch UI client through
createStytchClient(). - Pass the Stytch UI client to the
<StytchProvider>component at the root of your application, making it accessible to all child components.
import { createStytchClient, StytchProvider } from '@stytch/react';
const stytch = createStytchClient($YOUR_PUBLIC_KEY);
// Add the component at the root of your application
export function App() {
return (
<StytchProvider stytch={stytch}>
{/* Your app code */}
</StytchProvider>
);
}
Add <StytchLogin> UI component
- Create a
<StytchLogin>component. - Set authentication methods and relevant options in the config object.
import { Products, StytchLogin } from '@stytch/react';
const config = {
products: [Products.emailMagicLinks, Products.oauth],
oauthOptions: {
providers: [{ type: 'google' }],
},
sessionOptions: {
sessionDurationMinutes: 60,
},
};
const LoginOrSignup = () => {
return <StytchLogin config={config} />;
};
Add <LoginOrSignup> to your login page(s)
- Add
<LoginOrSignup>to your/loginpage:
import { useStytchSession } from "@stytch/react";
import { Navigate } from "react-router";
import { LoginOrSignup } from "./LoginOrSignup";
export const Login = () => {
const { session } = useStytchSession();
if (session) {
return <Navigate to="/home" />;
}
return <LoginOrSignup />;
};
- If you’re using separate routes, add
<LoginOrSignup>to your/authenticateredirect route as well, e.g.Authenticate.jsx.
Handle session and user data
useStytchSession() lets you easily check for an active session.Example app
Web demo
SDK reference
Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s domain to your project’s Authorized Domains.
Install the JS SDK and configure your API key
npm install @stytch/vanilla-js --save
Initialize the Stytch client for your app
- Initialize the Stytch UI client through
createStytchClient(). - Export the initialized client as
stytchso it can be used across your app.
import { createStytchClient } from "@stytch/vanilla-js";
export const stytch = createStytchClient($YOUR_PUBLIC_KEY);
Register the Stytch UI web component and configure it
- Create a
login.jsfile to register and initialize the custom element. - Set authentication methods and relevant options in the config object.
import { Products, StytchUI } from '@stytch/vanilla-js';
import { stytch } from "./stytch-client.js";
// Register the custom element
customElements.define('stytch-ui', StytchUI);
// Pass in the StytchClient and config
const login = document.getElementById('stytch-ui');
login.render({
client: stytch,
config: {
products: [Products.emailMagicLinks, Products.oauth],
oauthOptions: {
providers: [{ type: 'google' }],
},
sessionOptions: {
sessionDurationMinutes: 60,
},
},
});
Add Stytch UI on your login page(s)
- Add
<stytch-ui>on your/loginpage:
<!DOCTYPE html>
<html lang="en">
<head>...</head>
<body>
<stytch-ui id="stytch-ui" />
<script type="module" src="js/login.js"></script>
</body>
</html>
- If you’re using separate routes, add
<stytch-ui>on your/authenticateredirect route as well, e.g.authenticate.html.
Handle session and user data
useStytchSession() lets you retrieve the current session and can be used to determine if a user is already logged in.Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s application ID to your project’s Authorized bundle & application IDs.
- The Stytch Android SDK automatically handles deeplinks in the pre-built UI flow (used below). You must add the following URLs to your project’s Redirect URLs in the Dashboard:
[YOUR_PUBLIC_TOKEN]://b2c-ui[YOUR_PUBLIC_TOKEN]://oauth
Install the Android SDK and configure your API key
- The Stytch Android SDK is published on Maven Central at
com.stytch.sdk:sdk - The latest version can be found here
- Make sure
mavenCentral()is added to the repository configuration in yoursettings.gradle.ktsfile:
dependencyResolutionManagement {
repositories {
mavenCentral()
}
}
- Add the Stytch Android SDK to your application’s
build.gradle.ktsdependencies block:
dependencies {
implementation("com.stytch.sdk:sdk:$STYTCH_SDK_VERSION")
}
- Add your
public_tokenas a string resource. This will enable the SDK to automatically configure itself, including any necessary deeplinks.
As XML
As XML
<resources>
<string name="STYTCH_PUBLIC_TOKEN">public-token-test-...</string>
</resources>
As code
As code
android {
defaultConfig {
resValue("string", "STYTCH_PUBLIC_TOKEN", "\"${System.getenv("STYTCH_PUBLIC_TOKEN")}\"")
}
}
Initialize the Stytch client for your app
StytchClient.configure() method.Note: Be sure to pass an application context to this method to prevent potential memory leaks. The below examples show how to do this from either an Application or Activity class. You will only choose one approach that is appropriate for your situation.From an application class (preferred)
From an application class (preferred)
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
StytchClient.configure(this)
}
}
From an activity class (alternate)
From an activity class (alternate)
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StytchClient.configure(applicationContext)
}
}
Create the StytchUI client
StytchUI instance using the familiar Builder pattern, configured to your needs. Below, we will be enabling Email magic links and Google OAuth:val stytchUIClient = StytchUI.Builder().apply {
activity(this@MainActivity)
productConfig(
StytchProductConfig(
products = listOf(StytchProduct.EMAIL_MAGIC_LINKS, StytchProduct.OAUTH),
oauthOptions = OAuthOptions(
providers = listOf(OAuthProviderConfig(OAuthProvider.GOOGLE))
)
),
)
onAuthenticated(::onAuthenticated)
}.build()
private fun onAuthenticated(result: StytchResult<*>) {
when (result) {
is StytchResult.Success -> println("User successfully authenticated")
is StytchResult.Error -> println(result.error)
}
}
Launch the authentication flow
authenticate() method from your UI. Below, we are launching the authentication flow from a button press in a compose application:Button(onClick = stytchUIClient::authenticate) {
Text("Log in")
}
Handle session and user data
class MainViewModel : ViewModel() {
val uiState =
combine(
StytchClient.isInitialized,
StytchClient.user.onChange,
StytchClient.sessions.onChange,
) { isInitialized, userData, sessionData ->
val userIsAvailable = userData is StytchObjectInfo.Available
val sessionIsAvailable = sessionData is StytchObjectInfo.Available
when {
!isInitialized -> AppUIState.Loading
isInitialized && userIsAvailable && sessionIsAvailable -> AppUIState.LoggedIn(
userData = userData.value,
sessionData = sessionData.value,
)
else -> AppUIState.LoggedOut
}
}
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000),
AppUIState.Loading,
)
}
Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s Bundle ID to your project’s Authorized bundle & application IDs.
- You must add the following URL to your project’s Redirect URLs in the Dashboard:
stytchui-[YOUR_PUBLIC_TOKEN]://deeplink
Install the iOS SDK and configure your API key
- Add a new package package dependency pointing at our GitHub repository
- In your project Build Settings, under
Other Linker Flags, add-ObjC
Configure your application to handle Stytch UI deeplinks
Info.plist<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>stytchui-YOUR_PUBLIC_TOKEN</string>
</array>
</dict>
</array>
</dict>
Configure StytchUIClient
StytchUIClient with your desired options. We recommend doing so in your viewmodel.Below, we will be enabling Email magic links and Google OAuth:class ContentViewModel: ObservableObject {
@Published var stytchUIConfiguration: StytchUIClient.Configuration = .init(
stytchClientConfiguration: StytchClientConfiguration(publicToken: [YOUR_PUBLIC_TOKEN], defaultSessionDuration: 5),
products: [.emailMagicLinks, .oauth],
oauthProviders: [.thirdParty(.google)],
)
init() {
...
StytchUIClient.configure(configuration: stytchUIConfiguration)
...
}
}
Launch the authentication flow
- Add the following published properties to your viewmodel:
class ContentViewModel: ObservableObject {
@Published var isAuthenticated: Bool = false
@Published var isAuthenticationPresented: Bool = false
}
- Define a deeplink helper method (also in the viewmodel):
func handleOpenURL(_ url: URL) {
isAuthenticationPresented = true
let didHandle = StytchUIClient.handle(url: url)
print("StytchUIClient didHandle: \(didHandle) - url: \(url)")
}
- Pass the new
isAuthenticationPresentedproperty to theauthenticationSheet()method in your UI, and intercept links:
var body: some View {
VStack {
if viewModel.isAuthenticated {
// Your Authenticated UI
} else {
// Your Unauthenticated UI
// toggle $viewModel.isAuthenticationPresented to toggle the authentication flow
}
}
.authenticationSheet(configuration: viewModel.stytchUIConfiguration, isPresented: $viewModel.isAuthenticationPresented)
.onOpenURL { url in
viewModel.handleOpenURL(url)
}
}
Handle session and user data
class ContentViewModel: ObservableObject {
private var cancellables = Set<AnyCancellable>()
init() {
...
startObservables()
...
}
func startObservables() {
StytchUIClient.dismissUI
.receive(on: DispatchQueue.main)
.sink { [weak self] in
self?.isAuthenticationPresented = false
}
.store(in: &cancellables)
StytchUIClient.errorPublisher
.receive(on: DispatchQueue.main)
.sink { error in
print("Error from StytchUIClient:")
print(error.errorInfo)
}
.store(in: &cancellables)
StytchUIClient.isInitialized
.receive(on: DispatchQueue.main)
.sink { isInitialized in
print("isInitialized: \(isInitialized)")
}
.store(in: &cancellables)
StytchUIClient.sessions.onSessionChange
.receive(on: DispatchQueue.main)
.sink { [weak self] sessionInfo in
switch sessionInfo {
case let .available(session, lastValidatedAtDate):
print("Session Available: \(sessionInfo.expiresAt) - lastValidatedAtDate: \(lastValidatedAtDate)\n")
print("User: \(String(describing: StytchClient.user.getSync()))")
self?.isAuthenticated = true
case .unavailable:
print("Session Unavailable\n")
self?.isAuthenticated = false
}
}
.store(in: &cancellables)
Before you start
- Have a
public_tokenfrom your Stytch project & environment. - Enable and configure Frontend SDKs in your Dashboard.
- Add your application’s Bundle ID (iOS) and Application ID (Android) to your project’s Authorized bundle & application IDs.
- You must add the following URL to your project’s Redirect URLs in the Dashboard:
stytch-ui-[YOUR_PUBLIC_TOKEN]://deeplink
Install the React Native SDK
@stytch/react-native.npm install @stytch/react-native @stytch/react-native-inappbrowser-reborn --save
Configure your application to handle Stytch UI deeplinks
stytch-ui-[YOUR_PUBLIC_TOKEN]. How you do that will depend on your supported platforms and whether you are using bare React Native or Expo.NOTE: If you are using Expo Router, which is the default for new apps created with create-expo-app, you must add a +native-intent.tsx, file which ignores routing for the incoming Stytch UI deep links. An example of this can be found here.Configure the StytchClient
StytchClient with your public_token, and wrap your app in the StytchProvider component:const publicToken = process.env.EXPO_PUBLIC_STYTCH_PUBLIC_TOKEN ?? '';
const stytch = new StytchClient(publicToken);
export default function RootLayout() {
return (
<StytchProvider stytch={stytch}>
<YourApp>
</StytchProvider>
);
}
Authenticate a user
- Define your desired configuration for the authentication flow. Below, we will be enabling Email magic links and Google OAuth:
const config: StytchUIConfig = {
productConfig: {
products: [Products.emailMagicLinks, Products.oauth],
oauthOptions: { providers: [OAuthProviders.Google] },
},
};
- Display the authentication flow, and listen to the callbacks to determine when a user is fully authenticated:
export default function LoginScreen() {
const stytch = useStytch();
const { user } = useStytchUser();
useEffect(() => {
if (user) {
navigation.navigate('Profile');
}
}, [user, navigation]);
return <StytchUI client={stytch} config={config}></StytchUI>;
}
Handle session and user data
useStytchSession() lets you easily check for an active session.Next steps
- Authentication methods
- Session management