---
title: Next.js ↔️ Stytch Migration Guide
slug: oms/nextjs-stytch-migration-guide
docTags: 
createdAt: 2022-11-03T18:36:58.000Z
---

## Stytch Account Setup

Create your Stytch account following our [Stytch Account Setup](docId\:ssTgzaJO30Gx2Bs9QdOlS) guide.

## Add your public key to the .env

You can find your [public token](https://stytch.com/dashboard/api-keys) in the Stytch dashboard.

```Text
NEXT_PUBLIC_STYTCH_API_KEY={your_token}
```

Also remove the magic key from your .env if you have one.

## Install Stytch and chord-stytch

```shell
npm install @stytch/nextjs @stytch/vanilla-js @chordcommerce/chord-stytch
```

## Add a StytchProvider

Visit the file where you wrap your app in `ChordProvider` and add a `stytchClient`:

```javascript
const stytchClient = new StytchClient({
  apiKey: process.env.NEXT_PUBLIC_STYTCH_API_KEY,
  redirectPath: '/authenticate',
  sessionDurationMinutes: 60
})
```

Then, pass the `stytchClient` to the `auth` prop of the `ChordProvider`:

```javascript
<ChordProvider
  {...otherProps}
  auth={stytchClient}
>
```

Finally, wrap `children` with a `StytchProvider` (import from @stytch/nextjs) and pass `stytchClient.getServiceClient()` to it:

```javascript
<StytchProvider stytch={stytchClient.getServiceClient()}>
  {children}
</StytchProvider>
```

## Add a LoginForm component that uses StytchLogin

Go to the [config docs](https://stytch.com/docs/sdks/javascript-sdk#ui-config) to see what options are available. Please note that you will need to wrap the `<StytchLogin />`  component with another `<StytchProvider />` . This is because the `<StytchLogin />` component depends on Stytch's UI client, which is quite heavy, and that `chord-stytch`  uses the headless client for it's normal operations.&#x20;

::::CodeDrawer{title="StytchLoginForm" isResponseExpanded="false" autoGeneratedAnchorSlug="stytchloginform" legacyHash="_iMk_eD_vmc96E8usoWOA"}
:::CodeblockTabsExamples
```javascript
import React from 'react'
import { StytchLogin, StytchProvider } from '@stytch/nextjs'
import { createStytchUIClient } from '@stytch/nextjs/ui'
import { useMemo } from 'react'
import { useAuth } from '@chordcommerce/react-autonomy'
import { useRouter } from 'next/router'

const StytchLoginForm = () => {
  let baseUrl
  if (typeof window !== 'undefined') baseUrl = window.location.origin

  const router = useRouter()

  const { serviceClient, getToken } = useAuth()

  const stytchProps = useMemo(
    () => ({
      config: {
        products: ['emailMagicLinks', 'oauth'],
        emailMagicLinksOptions: {
          loginRedirectURL: `${baseUrl}/authenticate`,
          loginExpirationMinutes: 30,
          signupRedirectURL: `${baseUrl}/authenticate`,
          signupExpirationMinutes: 30,
          createUserAsPending: false
        },
        // these won't work until you have set them up in Stytch
        oauthOptions: {
          loginRedirectURL: `${baseUrl}/authenticate`,
          signupRedirectURL: `${baseUrl}/authenticate`,
          providers: [{ type: 'google' }]
        }
      },
      styles: {
        hideHeaderText: true,
        width: '100%',
        primaryColor: '#215732'
      },
      callbacks: {
        // this function will automatically navigate to the /account page when a user clicks 
        // the magic link in their email and is authenticated on another tab
        onEvent: async () => {
          const intervalID = setInterval(async () => {
            if (serviceClient?.session.getSync()) {
              await getToken()
              clearInterval(intervalID)
              router.push('/account')
            }
          }, 1000)
        },
        // this function logs the error message in segment
        onError: message => {
          window.analytics.track({
            message,
            meta: {
              storeId: process.env.CHORD_OMS_STORE_ID,
              omsId: process.env.CHORD_OMS_ID,
              tenantId: process.env.CHORD_OMS_TENANT_ID,
              currency: 'USD',
              locale: 'en-US'
            }
          })
        }
      }
    }),
    [baseUrl, getToken, serviceClient, router]
  )

  return (
    <StytchProvider 
      stytch={createStytchUIClient(
        process.env.NEXT_PUBLIC_STYTCH_API_KEY
      )}
    >
      <StytchLogin
        config={stytchProps.config}
        styles={stytchProps.styles}
        callbacks={stytchProps.callbacks}
      />
    </StytchProvider>
  )
}

export default StytchLoginForm
```
:::

:::CodeblockTabsResponses
```javascript
```
:::
::::

## Create an Authenticate component

This component will authenticate the user by calling `handleCallback()` from useAuth, then it will navigate to the /account page.

Add this component to the `pages`  directory.

::::CodeDrawer{title="Authenticate" isResponseExpanded="false" autoGeneratedAnchorSlug="authenticate" legacyHash="Y0Qk9k6xoyaPTrGAjb9l-"}
:::CodeblockTabsExamples
```javascript
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { useAuth } from '@chordcommerce/react-autonomy'

const Authenticate = () => {
  const { handleCallback } = useAuth()
  const router = useRouter()

  useEffect(() => {
    handleCallback().then(() => router.push('/account'))
  }, [handleCallback])

  return <>Loading...</>
}

export default Authenticate
```
:::

:::CodeblockTabsResponses
```javascript
```
:::
::::

## Try it out

Visit your login page and try logging in using a magic link!

Once you've clicked the link in the email from Stytch to sign-up/login, you can visit the [User management](https://stytch.com/dashboard/user-management) page to see your user.

## Enabling OAuth

If your would like to enable OAuth, visit the [SDK Configuration](https://stytch.com/dashboard/sdk-configuration) page, and click the OAuth toggle. Then, expand the OAuth section and toggle Enable PKCE.

Once OAuth is enabled, visit the [OAuth page](https://stytch.com/dashboard/oauth), then select the provider you would like to use and follow the directions.

