fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano
, '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

fix(nextjs): prevent infinite handshake redirect loop on Netlify - #7857

Merged
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop
Feb 18, 2026
Merged

fix(nextjs): prevent infinite handshake redirect loop on Netlify#7857
mauricioabreu merged 2 commits into
mainfrom
mauricio-antunes/fix-infite-handshake-redirect-netlify-loop

Conversation

@mauricioabreu

@mauricioabreumauricioabreu commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

Description

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed infinite handshake redirect loop when deploying Next.js apps with Clerk development instances to Netlify
    • Improved redirect handling with fallback mechanism for Netlify deployments in development environments

@changeset-bot

changeset-botBot commented Feb 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be3ca3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
NameType
@clerk/nextjsPatch

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercelBot commented Feb 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreview, CommentFeb 18, 2026 5:50am

Request Review

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is looking good. Just a minor change! Thankss

publishableKey: requestState.publishableKey,
});

const res = NextResponse.redirect(requestState.headers.get(constants.Headers.Location) || locationHeader);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just use locationHeader here 👀

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I don't think so? this code looks a bit different from the other frameworks

I read the other framework's implementation, and the response is built with Response(null, { status: 307, headers: requestState.headers })

In Next.js, we use NextResponse.redirect(url) and explicitly skip copying the Location header.

I mean, if we reused the locationHeader value captured before the mutation, the param added by handleNetlifyCacheInDevInstance is lost

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy. Looks like I have to revisit the helper. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thanks for correcting me here! I just checked and saw we're updating the Location header so your implementation is perfect!

@mauricioabreumauricioabreu self-assigned this Feb 17, 2026
@mauricioabreu
mauricioabreu marked this pull request as ready for review February 17, 2026 01:56
@coderabbitai

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

This pull request introduces a fix for an infinite handshake redirect loop that occurs when deploying Next.js applications with Clerk development instances to Netlify. The changes add Netlify cache handling in development mode by importing and invoking handleNetlifyCacheInDevInstance during redirect processing. A fallback mechanism is implemented for the Location header, using either the current Location header value or a previously captured locationHeader if the header is missing. The changes are documented in a new changeset file and do not introduce public API modifications.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and specifically summarizes the main change: preventing an infinite handshake redirect loop on Netlify for the Next.js integration, which is directly supported by the code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection✅ Passed✅ No merge conflicts detected when merging into main

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


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

@wobsorianowobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! Let's also cherry-pick the changes here to "release/core-2" branch 🫡

@pkg-pr-new

Copy link
Copy Markdown

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7857

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7857

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7857

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7857

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7857

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7857

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7857

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7857

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7857

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7857

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@7857

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7857

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7857

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7857

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7857

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7857

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7857

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7857

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7857

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7857

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7857

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7857

commit: be3ca3a

@mauricioabreu
mauricioabreu merged commit 061c6c4 into mainFeb 18, 2026
39 checks passed
@mauricioabreu
mauricioabreu deleted the mauricio-antunes/fix-infite-handshake-redirect-netlify-loop branch February 18, 2026 11:06
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
mauricioabreu added a commit that referenced this pull request Feb 18, 2026
…) (#7876)
Co-authored-by: Robert Soriano <sorianorobertc@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mauricioabreu@wobsoriano