supertokens / supertokens-auth-react

ReactJS authentication module for SuperTokens
https://supertokens.com
Other
260 stars 81 forks source link

Doesn't work on React Router 6.4 (v6.22.3) #817

Open ikx94 opened 2 months ago

ikx94 commented 2 months ago

React Router 6.22 uses different routing than the previous 6.* versions.

The tutorial doesn't work, and I've spent 2 hours changing things and trying but I can't get it to work.

I would highly appreciate some help. An user on Discord reported the same problem (https://discord.com/channels/603466164219281420/1175886717245472798) but no solution was given.

I would consider upgrading from React Router 6.4 to Remix but there's also no example of how to use this on Remix SPA mode (which is what I would use, because my backend is a Express server).

The main problem is that the components are tied to other things, I don't know why that's the case when it could just be etc.

This is my main.tsx code:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider } from 'react-router-dom'
import { Toaster } from '@/components/ui/toaster'
import { ThemeProvider } from '@/components/theme-provider'
import { ResponsiveHelper } from '@/components/custom/responsive-helper'
import router from '@/router'
import '@/index.css'
import SuperTokens, { SuperTokensWrapper } from 'supertokens-auth-react'
import ThirdPartyEmailPassword, {
  Github,
  Google,
  Facebook,
  Apple,
} from 'supertokens-auth-react/recipe/thirdpartyemailpassword'
import Session from 'supertokens-auth-react/recipe/session'

SuperTokens.init({
  appInfo: {
    // learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo
    appName: 'Blueprint',
    apiDomain: 'http://localhost:8080',
    websiteDomain: 'http://localhost:3000',
    apiBasePath: '/auth',
    websiteBasePath: '/auth',
  },
  recipeList: [
    ThirdPartyEmailPassword.init({
      signInAndUpFeature: {
        providers: [
          Github.init(),
          Google.init(),
          Facebook.init(),
          Apple.init(),
        ],
      },
    }),
    Session.init(),
  ],
})

ReactDOM.createRoot(document.getElementById('root')!).render(
  <SuperTokensWrapper>
    <ThemeProvider defaultTheme='dark' storageKey='vite-ui-theme'>
      <RouterProvider router={router} />
      <Toaster />
      <ResponsiveHelper />
    </ThemeProvider>
  </SuperTokensWrapper>
)

You'll notice there's no

So there's no place to insert this code:

{/*This renders the login UI on the /auth route*/}
{getSuperTokensRoutesForReactRouterDom(reactRouterDom, [ThirdPartyEmailPasswordPreBuiltUI])}
{/*Your app routes*/}

Sample router.tsx file:

import GeneralError from './pages/errors/general-error'
import NotFoundError from './pages/errors/not-found-error'
import MaintenanceError from './pages/errors/maintenance-error'
import AuthRoutes from './components/AuthRoutes'

const router = createBrowserRouter([
  // Auth routes

  {
    path: '/auth/*',
    element: <AuthRoutes />,
  },
  {
    path: '/login',
    lazy: async () => ({
      Component: (await import('./pages/auth/login')).default,
    }),
  },
  {
    path: '/login-2',
    lazy: async () => ({
      Component: (await import('./pages/auth/login-2')).default,
    }),
  },
  {
    path: '/sign-up',
    lazy: async () => ({
      Component: (await import('./pages/auth/sign-up')).default,
    }),
  },
  {
    path: '/forgot-password',
    lazy: async () => ({
      Component: (await import('./pages/auth/forgot-password')).default,
    }),
  },
  {
    path: '/otp',
    lazy: async () => ({
      Component: (await import('./pages/auth/otp')).default,
    }),
  },

  // Main routes
  {
    path: '/',
    lazy: async () => {
      const AppShell = await import('./components/app-shell')
      return { Component: AppShell.default }
    },
    errorElement: <GeneralError />,
    children: [
      {
        index: true,
        lazy: async () => ({
          Component: (await import('./pages/dashboard')).default,
        }),
      },
      {
        path: 'tasks',
        lazy: async () => ({
          Component: (await import('@/pages/tasks')).default,
        }),
      },
    ],
  },

  // Error routes
  { path: '/500', Component: GeneralError },
  { path: '/404', Component: NotFoundError },
  { path: '/503', Component: MaintenanceError },

  // Fallback 404 route
  { path: '*', Component: NotFoundError },
])

export default router
rishabhpoddar commented 2 months ago

See a solution here: https://github.com/supertokens/supertokens-auth-react/issues/581

Keeping this issue opened until we add it in our docs.