Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path - #597

Draft
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction
Draft

Bug: startNewFlow uses absolute path "/self-service/...", breaks integrations mounted under a sub-path#597
hersentino wants to merge 1 commit into
ory:mainfrom
hersentino:fix-startNewFlow-fonction

Conversation

@hersentino

@hersentinohersentino commented Apr 28, 2026

Copy link
Copy Markdown

Preflight checklist

Ory Network Project

Self-hosted Ory Kratos (proxied through @ory/nextjs middleware).

Describe the bug

startNewFlow() in @ory/nextjs/app builds the redirect URL with a leading slash:

newURL("/self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

Because the first argument starts with /, the URL constructor treats it as an
absolute path and discards any path prefix carried by baseUrl.

baseUrl here comes from guessPotentiallyProxiedOrySdkUrl({ knownProxiedUrl: await getPublicUrl() }),
which returns the public origin of the Next.js app (the URL the browser sees).
For any deployment where the Next.js app is mounted under a sub-path
e.g. behind an ingress / reverse proxy that routes https://example.com/app/*
to the app, or when using Next.js basePath — the redirect drops the prefix
and points to https://example.com/self-service/... instead of
https://example.com/app/self-service/.... The middleware never sees the
request, the Kratos proxy never runs, and the user lands on a 404 (or worse,
an unrelated route on the parent domain).

This affects every flow that goes through getFlowFactorystartNewFlow:
login, registration, recovery, verification, settings.

The fix is to drop the leading / so the path is resolved relative to
baseUrl
, which is the documented contract of new URL(input, base):

newURL("self-service/"+flowType+"/browser?"+urlQueryToSearchParams(params).toString(),baseUrl,)

When baseUrl has no sub-path (the common case), the resulting URL is
identical, so this change is backwards-compatible for vanilla deployments
and fixes sub-path deployments.

Reproducing the bug

  1. Deploy a Next.js app using @ory/nextjs behind a reverse proxy that mounts
    it under a sub-path, e.g. https://example.com/app/. Make sure the proxy
    forwards Host / X-Forwarded-* headers so getPublicUrl() returns
    https://example.com/app/.
  2. Visit https://example.com/app/login without an existing flow ID.
  3. Observe the 30x redirect: Location: https://example.com/self-service/login/browser?...
    instead of https://example.com/app/self-service/login/browser?....
  4. The @ory/nextjs middleware (matched on /app/self-service/*) never runs,
    so the request never reaches Kratos and the browser hits a 404 / unrelated route.

The same problem occurs with Next.js basePath: "/app" configured in next.config.ts.

Relevant log output

GET /login 307
Location: https://example.com/self-service/login/browser?...
GET /self-service/login/browser 404

Relevant configuration

// src/lib/ory.tsexportconstoryConfig: OryClientConfiguration={project: {login_ui_url: '/login',registration_ui_url: '/registration',// ...},};
// src/middleware.tsimport{createOryMiddleware}from'@ory/nextjs/middleware';exportconstmiddleware=createOryMiddleware(oryConfig);

Version

@ory/nextjs@1.0.0-rc.1

On which operating system are you observing this issue?

Linux (containerised, behind ingress)

In which environment are you deploying?

Kubernetes (Helm), with an ingress mounting the app under a sub-path.

Additional Context

Source location:
src/app/flow.tsstartNewFlow.

Spec reference for the URL constructor behavior:
https://url.spec.whatwg.org/#concept-url-parser — an input starting with /
is parsed as a path-absolute URL and replaces base.pathname.

I'm opening a PR with the one-character fix.

Summary by CodeRabbit

  • Chores
    • Adjusted internal URL routing path construction for improved consistency.

@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b258e73

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercelBot commented Apr 28, 2026

Copy link
Copy Markdown

@hersentino is attempting to deploy a commit to the ory Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Apr 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitaiBot commented Apr 28, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The startNewFlow function's redirect URL path is modified by removing the leading forward slash from the self-service route segment. The remainder of the URL construction logic remains unchanged.

Changes

Cohort / File(s)Summary
URL Path Modification
packages/nextjs/src/app/utils.ts
Removed leading / from the self-service route segment in the startNewFlow function's redirect target URL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the bug being fixed: the absolute path issue in startNewFlow that breaks sub-path deployments.
Description check✅ PassedThe description comprehensively covers the bug, root cause, fix, backwards compatibility, reproduction steps, and relevant configuration, exceeding the template requirements.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/nextjs/src/app/utils.ts (1)

65-69: ⚠️ Potential issue | 🟠 Major

Relative path breaks when baseUrl has no trailing slash—baseUrl is normalized to strip trailing slashes in production

Line 65 assumes baseUrl has a trailing slash, but orySdkUrl() and getProjectApiKey() explicitly remove them. With new URL("self-service/...", "https://example.com/app"), the app segment is dropped instead of appending the flow path.

The codebase already has joinUrlPaths() utility (in packages/nextjs/src/utils/utils.ts) with tests covering this exact scenario. Either use that utility or implement the path-aware fix suggested below.

Suggested fix
 export function startNewFlow(
params: QueryParams,
flowType: FlowType,
baseUrl: string,
) {
// Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default
// return to automatically if they're logged in already.
- return redirect(- new URL(- "self-service/" +- flowType.toString() +- "/browser?" +- urlQueryToSearchParams(params).toString(),- baseUrl,- ).toString(),- RedirectType.replace,- )+ const flowUrl = new URL(baseUrl)+ const basePath = flowUrl.pathname.endsWith("/")+ ? flowUrl.pathname+ : `${flowUrl.pathname}/`+ const query = urlQueryToSearchParams(params).toString()++ flowUrl.pathname = `${basePath}self-service/${flowType.toString()}/browser`+ flowUrl.search = `?${query}`++ return redirect(flowUrl.toString(), RedirectType.replace)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/nextjs/src/app/utils.ts` around lines 65 - 69, The URL construction
currently concatenates "self-service/" + flowType + "/browser?" +
urlQueryToSearchParams(params).toString() with baseUrl which fails when baseUrl
has no trailing slash; update the code that builds the return URL in
packages/nextjs/src/app/utils.ts (the function using flowType,
urlQueryToSearchParams and baseUrl) to use the existing joinUrlPaths(...)
utility from packages/nextjs/src/utils/utils.ts (or implement equivalent
path-aware joining) to combine baseUrl and the relative path before appending
the query string so that base path segments are preserved even when baseUrl has
no trailing slash.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/nextjs/src/app/utils.ts`:
- Around line 65-69: The URL construction currently concatenates "self-service/"
+ flowType + "/browser?" + urlQueryToSearchParams(params).toString() with
baseUrl which fails when baseUrl has no trailing slash; update the code that
builds the return URL in packages/nextjs/src/app/utils.ts (the function using
flowType, urlQueryToSearchParams and baseUrl) to use the existing
joinUrlPaths(...) utility from packages/nextjs/src/utils/utils.ts (or implement
equivalent path-aware joining) to combine baseUrl and the relative path before
appending the query string so that base path segments are preserved even when
baseUrl has no trailing slash.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 82bdff4f-7602-4bbb-8a0d-0e24028979b3

📥 Commits

Reviewing files that changed from the base of the PR and between a6bbdbc and b258e73.

📒 Files selected for processing (1)
  • packages/nextjs/src/app/utils.ts

@codecov

codecovBot commented Apr 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.79%. Comparing base (f3fad4d) to head (b258e73).
⚠️ Report is 358 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #597 +/- ##
===========================================
+ Coverage 42.43% 59.79% +17.36% 
===========================================
Files 136 182 +46 Lines 2008 3557 +1549 Branches 288 563 +275 ===========================================
+ Hits 852 2127 +1275 - Misses 1149 1306 +157 - Partials 7 124 +117 
ComponentsCoverage Δ
@ory/elements-react59.63% <ø> (+22.84%)⬆️
@ory/nextjs60.70% <ø> (-5.28%)⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hersentino
hersentino marked this pull request as draft April 29, 2026 07:38
Sign up for freeto 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

@hersentino@CLAassistant