Skip to content

Add nextjs migration logic#42

Merged
mhamann merged 8 commits into
rownd:mainfrom
bcbogdan:feat/supertokens-migrate
May 28, 2026
Merged

Add nextjs migration logic#42
mhamann merged 8 commits into
rownd:mainfrom
bcbogdan:feat/supertokens-migrate

Conversation

@bcbogdan
Copy link
Copy Markdown
Contributor

@bcbogdan bcbogdan commented May 28, 2026

Summary by Sourcery

Add SuperTokens migration support triggered from Rownd sign-in flows and provide example apps demonstrating Rownd-to-SuperTokens lazy user migration for React and Next.js.

New Features:

  • Trigger SuperTokens user migration calls from React and Next.js Rownd providers when a new Rownd user completes sign-in.
  • Allow configuring SuperTokens application info via the Rownd provider to enable migration integration.

Enhancements:

  • Add utility helpers to normalize SuperTokens app configuration and invoke the Rownd-to-SuperTokens migration endpoint on the backend.

Documentation:

  • Document how to run the Next.js SuperTokens migration example and validate that migration requests are sent.

Chores:

  • Add React, Node, and Next.js example projects showcasing SuperTokens migration integration with Rownd.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 28, 2026

Reviewer's Guide

Implements SuperTokens migration support for React and Next.js Rownd providers by normalizing SuperTokens app info, wiring a sign-in completed event listener to call a migration endpoint for new users, extending provider props to accept SuperTokens config, and adding full-stack example apps (React and Next.js) demonstrating the migration flow with a SuperTokens + Express backend.

Sequence diagram for Rownd-to-SuperTokens migration on new user sign-in

sequenceDiagram
  actor User
  participant Frontend as React_or_Next_client
  participant RowndHub as Rownd_hub_events
  participant STBackend as SuperTokens_backend

  User->>Frontend: requestSignIn()
  Frontend->>RowndHub: requestSignIn()
  RowndHub-->>Frontend: events.sign_in_completed(detail.user_type)

  alt [detail.user_type == 'new_user']
    Frontend->>Frontend: handleSignInCompleted(event)
    Frontend->>Frontend: syncUserToSuperTokens(accessToken, appInfo)
    Frontend->>STBackend: POST /auth/plugin/rownd/migrate
    STBackend-->>Frontend: 2xx/4xx response
  else [detail.user_type != 'new_user']
    Frontend->>Frontend: (no migration call)
  end
Loading

File-Level Changes

Change Details Files
Wire SuperTokens migration call into React and Next.js Rownd providers on new-user sign-in completion.
  • Import SuperTokens normalization and sync helpers into the core React provider and Next.js client provider.
  • Store the latest access token and SuperTokens appInfo in React refs to avoid stale closures inside event handlers.
  • Register a sign_in_completed event listener that checks for new_user events and calls the SuperTokens migration endpoint with the current access token and appInfo, with cleanup on unmount.
src/context/ReactRowndProvider.tsx
src/next/client/index.tsx
Extend Rownd provider API to accept SuperTokens configuration and encapsulate migration logic in a utility module.
  • Add an optional supertokens.appInfo prop to RowndProviderProps with appName, apiDomain, and apiBasePath.
  • Implement normalizeSuperTokensAppInfo to sanitize apiDomain and apiBasePath formats.
  • Implement syncUserToSuperTokens to POST to the SuperTokens Rownd migration plugin endpoint using the Rownd access token, with non-fatal logging on failures.
src/context/RowndContext.tsx
src/utils/supertokens-sync.ts
Add example applications demonstrating Rownd-to-SuperTokens migration flows for both React and Next.js.
  • Create an Express + SuperTokens backend configured with the Rownd SuperTokens plugin, passwordless auth, session, metadata, and account linking, including CORS and logging.
  • Add a React SPA example wired to @rownd/react that surfaces access tokens and drives sign-in for the migration case.
  • Add a Next.js App Router frontend example wired to @rownd/next, including layout, page content, styling, Next config, and TS config, plus a dedicated backend mirroring the migration setup for the Next environment.
  • Introduce package.json, TypeScript configs, Vite/Next config, and minimal project scaffolding for the new examples.
examples/supertokens-migration/backend/src/index.ts
examples/supertokens-migration/backend/package.json
examples/supertokens-migration/backend/tsconfig.json
examples/supertokens-migration/backend/.env.example
examples/supertokens-migration/backend/.npmrc
examples/supertokens-migration/frontend/src/App.tsx
examples/supertokens-migration/frontend/index.html
examples/supertokens-migration/frontend/vite.config.ts
examples/supertokens-migration/frontend/package.json
examples/supertokens-migration/frontend/tsconfig.json
examples/supertokens-migration/frontend/tsconfig.node.json
examples/supertokens-migration-nextjs/backend/src/index.ts
examples/supertokens-migration-nextjs/backend/package.json
examples/supertokens-migration-nextjs/backend/tsconfig.json
examples/supertokens-migration-nextjs/backend/.env.example
examples/supertokens-migration-nextjs/backend/.gitignore
examples/supertokens-migration-nextjs/backend/package-lock.json
examples/supertokens-migration-nextjs/frontend/src/app/layout.tsx
examples/supertokens-migration-nextjs/frontend/src/app/page.tsx
examples/supertokens-migration-nextjs/frontend/src/app/globals.css
examples/supertokens-migration-nextjs/frontend/next.config.ts
examples/supertokens-migration-nextjs/frontend/package.json
examples/supertokens-migration-nextjs/frontend/tsconfig.json
examples/supertokens-migration-nextjs/frontend/.eslintrc.json
examples/supertokens-migration-nextjs/frontend/.gitignore
examples/supertokens-migration-nextjs/frontend/package-lock.json
examples/supertokens-migration-nextjs/README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The sign_in_completed event handling logic (including accessTokenRef/supertokensAppInfoRef usage and syncUserToSuperTokens invocation) is duplicated between ReactRowndProvider and the Next.js client; consider extracting a shared helper/hook to avoid divergence over time.
  • In the sign_in_completed handlers you cast to CustomEvent<{ user_type?: string }> without a runtime guard; if these events can be triggered externally, consider checking event instanceof CustomEvent (and that detail is an object) before accessing detail.user_type to avoid potential runtime issues.
  • syncUserToSuperTokens already catches and logs its own errors, so chaining .catch(() => {}) at the call sites in React effects is redundant and can be removed for clarity.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `sign_in_completed` event handling logic (including `accessTokenRef`/`supertokensAppInfoRef` usage and `syncUserToSuperTokens` invocation) is duplicated between `ReactRowndProvider` and the Next.js client; consider extracting a shared helper/hook to avoid divergence over time.
- In the `sign_in_completed` handlers you cast to `CustomEvent<{ user_type?: string }>` without a runtime guard; if these events can be triggered externally, consider checking `event instanceof CustomEvent` (and that `detail` is an object) before accessing `detail.user_type` to avoid potential runtime issues.
- `syncUserToSuperTokens` already catches and logs its own errors, so chaining `.catch(() => {})` at the call sites in React effects is redundant and can be removed for clarity.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@bcbogdan bcbogdan force-pushed the feat/supertokens-migrate branch from 0274a67 to db15799 Compare May 28, 2026 14:01
Copy link
Copy Markdown
Contributor

@mhamann mhamann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactor — the inline SuperTokens-migration block in ReactRowndProvider is now a useSuperTokensMigration hook, reused by both the React provider and the Next.js client. The defensive event-type checks (instanceof CustomEvent, typeof detail === 'object') are a real improvement over the previous inline version. Tests cover the new wiring in both providers.

Correctness

  • Minor regression — lost rejection swallow on syncUserToSuperTokens. The old code wrote syncUserToSuperTokens(...).catch(() => {}); the new code does void syncUserToSuperTokens(...). syncUserToSuperTokens constructs new URL() outside its try block, so a malformed apiDomain (e.g. missing protocol) throws synchronously and bubbles as an unhandled promise rejection. See line comment on useSuperTokensMigration.ts:60.

Design / Nits

Three small suggestions
  • useEffect(..., [supertokens]) re-runs whenever a parent passes a new object literal — and the example in layout.tsx does exactly that. See line comment on useSuperTokensMigration.ts:46.
  • useRef is still imported in src/context/ReactRowndProvider.tsx (line 1) but no longer referenced after the extraction. (Couldn't anchor — unchanged line — flagging here.)
  • The Next.js example's layout.tsx hard-codes appKey="<APP_KEY>" and the README doesn't call out the substitution. See line comment on layout.tsx:19.

Test coverage

Good positive/negative cases for user_type and event-shape. Not covered: early returns when accessToken is null or supertokens is undefined, and the cleanup (removeEventListener on unmount). Optional, low priority.

Landing recommendation: Safe to merge after the rejection-swallow regression on line 60 is addressed (one-line fix).

Comment thread src/hooks/useSuperTokensMigration.ts
Comment thread src/hooks/useSuperTokensMigration.ts Outdated
Comment thread examples/supertokens-migration-nextjs/frontend/src/app/layout.tsx Outdated
@mhamann mhamann merged commit 049e28e into rownd:main May 28, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants