-
-
Notifications
You must be signed in to change notification settings - Fork 7
Fix: func sseError not found (Extension Conflict) #496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…tension conflicts
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdded a safety bootstrap script to the document head that initializes fallback HTMX event handler functions. For a predefined set of HTMX events, global functions are created if not already defined, each logging a console warning when invoked to prevent runtime errors from undefined handlers. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||
ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inline global fallback is a pragmatic mitigation, but it’s currently overly broad and always-on via dangerouslySetInnerHTML, which increases the chance of unintended side effects in a root layout. Consider using next/script with an early loading strategy plus explicit browser guards. Additionally, the current console.warn may spam logs during SSE activity; dedupe or restrict warnings (e.g., dev-only) to keep production noise down.
Additional notes (1)
- Maintainability |
app/layout.tsx:73-85
Using a global naming convention likewindow['func ' + event]is very broad and may mask genuine configuration issues (or conflict with other tooling) beyond the specific Phantom Wallet scenario. If the problem is limited to a known set of extensions/events, consider narrowing the patch to the minimum necessary surface area (e.g., onlysseError/sseOpen) or gating the fallback behind detection of HTMX usage/presence to avoid papering over real errors.
Summary of changes
What changed
- Added an explicit
<head>section toapp/layout.tsx. - Injected an inline
<script>viadangerouslySetInnerHTMLthat:- Defines a list of HTMX-related event names (e.g.,
sseError,sseOpen,xhr:loadstart). - For each event, creates a global
window["func " + event]no-op handler if it doesn’t already exist. - Emits a
console.warn(...)when a missing handler is invoked, acting as a safety fallback against browser extension conflicts.
- Defines a list of HTMX-related event names (e.g.,
| <head> | ||
| <script | ||
| dangerouslySetInnerHTML={{ | ||
| __html: ` | ||
| (function() { | ||
| const htmxEvents = [ | ||
| 'sseError', 'sseOpen', 'swapError', 'targetError', 'timeout', | ||
| 'validation:validate', 'validation:failed', 'validation:halted', | ||
| 'xhr:abort', 'xhr:loadend', 'xhr:loadstart' | ||
| ]; | ||
| htmxEvents.forEach(event => { | ||
| const funcName = 'func ' + event; | ||
| if (typeof window[funcName] === 'undefined') { | ||
| window[funcName] = function() { | ||
| console.warn('HTMX event handler "' + funcName + '" was called but not defined. Providing safety fallback.'); | ||
| }; | ||
| } | ||
| }); | ||
| })(); | ||
| `, | ||
| }} | ||
| /> | ||
| </head> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This script uses dangerouslySetInnerHTML without any scoping/guards and will run on every page load, potentially in environments where window isn’t available (or before extensions/HTMX are ready). While the code references window only at runtime, it’s still worth explicitly guarding for non-browser contexts and avoiding unnecessary work when document/window aren’t present.
Also, because this is a root layout in Next.js, you should be deliberate about when the script runs. If the goal is to prevent early calls from extensions, consider next/script with an appropriate strategy (e.g., beforeInteractive) and a stable id to avoid duplication/rehydration surprises.
Suggestion
Consider switching to next/script and adding explicit guards:
- Use
<Script id="htmx-func-fallback" strategy="beforeInteractive">to ensure the fallback exists as early as possible. - Add
if (typeof window === 'undefined') return;inside the IIFE to harden against non-browser execution.
Example:
import Script from 'next/script'
// ...
<head>
<Script id="htmx-func-fallback" strategy="beforeInteractive">
{`(function(){
if (typeof window === 'undefined') return;
const htmxEvents = [/* ... */];
for (const event of htmxEvents) {
const funcName = 'func ' + event;
if (typeof window[funcName] === 'undefined') {
window[funcName] = function() {};
}
}
})();`}
</Script>
</head>Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this change.
| htmxEvents.forEach(event => { | ||
| const funcName = 'func ' + event; | ||
| if (typeof window[funcName] === 'undefined') { | ||
| window[funcName] = function() { | ||
| console.warn('HTMX event handler "' + funcName + '" was called but not defined. Providing safety fallback.'); | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback function logs a warning every time an extension triggers the missing handler, which can spam the console (and, in some setups, log aggregation) during SSE streams. Since the intent is resilience, not observability, this should ideally warn once per handler (or be gated behind a development check).
Suggestion
Rate-limit or dedupe the warning per handler (or only warn in development). For example:
const warned = new Set();
// ...
window[funcName] = function() {
if (!warned.has(funcName)) {
warned.add(funcName);
console.warn(`HTMX event handler "${funcName}" was called but not defined. Providing safety fallback.`);
}
};Alternatively, log only when process.env.NODE_ENV !== 'production'.
Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@app/layout.tsx`:
- Around line 68-90: Move the inline HTMX fallback script out of app/layout.tsx
into an external static file (e.g., public/htmx-fallback.js) that contains the
IIFE creating the htmxEvents array and the window['func ' + event] safety
handlers, then load that file with Next.js's next/script using
strategy="beforeInteractive" in layout.tsx (or alternatively generate and apply
a CSP nonce and add it to the inline script) so the bootstrap runs when
script-src disallows unsafe-inline; update references to the IIFE/htmxEvents and
the window handler names (the 'func ' + event handlers) to ensure the same
behavior after moving the code.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
app/layout.tsx
🧰 Additional context used
🪛 ast-grep (0.40.5)
app/layout.tsx
[warning] 69-69: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.3.13)
app/layout.tsx
[error] 70-70: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| <head> | ||
| <script | ||
| dangerouslySetInnerHTML={{ | ||
| __html: ` | ||
| (function() { | ||
| const htmxEvents = [ | ||
| 'sseError', 'sseOpen', 'swapError', 'targetError', 'timeout', | ||
| 'validation:validate', 'validation:failed', 'validation:halted', | ||
| 'xhr:abort', 'xhr:loadend', 'xhr:loadstart' | ||
| ]; | ||
| htmxEvents.forEach(event => { | ||
| const funcName = 'func ' + event; | ||
| if (typeof window[funcName] === 'undefined') { | ||
| window[funcName] = function() { | ||
| console.warn('HTMX event handler "' + funcName + '" was called but not defined. Providing safety fallback.'); | ||
| }; | ||
| } | ||
| }); | ||
| })(); | ||
| `, | ||
| }} | ||
| /> | ||
| </head> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Inline script may be blocked by CSP; prefer external script or nonce.
If script-src disallows unsafe-inline, this script won’t run and the fallback won’t be installed. Consider moving the bootstrap to a static file loaded with next/script (beforeInteractive) or apply a CSP nonce if you use nonces.
🛠️ Proposed refactor (external script)
+import Script from 'next/script'
...
- <head>
- <script
- dangerouslySetInnerHTML={{
- __html: `
- (function() {
- const htmxEvents = [
- 'sseError', 'sseOpen', 'swapError', 'targetError', 'timeout',
- 'validation:validate', 'validation:failed', 'validation:halted',
- 'xhr:abort', 'xhr:loadend', 'xhr:loadstart'
- ];
- htmxEvents.forEach(event => {
- const funcName = 'func ' + event;
- if (typeof window[funcName] === 'undefined') {
- window[funcName] = function() {
- console.warn('HTMX event handler "' + funcName + '" was called but not defined. Providing safety fallback.');
- };
- }
- });
- })();
- `,
- }}
- />
- </head>
+ <head>
+ <Script src="/htmx-fallback.js" strategy="beforeInteractive" />
+ </head>Then add public/htmx-fallback.js:
(function () {
const htmxEvents = [
'sseError', 'sseOpen', 'swapError', 'targetError', 'timeout',
'validation:validate', 'validation:failed', 'validation:halted',
'xhr:abort', 'xhr:loadend', 'xhr:loadstart'
];
htmxEvents.forEach(event => {
const funcName = 'func ' + event;
if (typeof window[funcName] === 'undefined') {
window[funcName] = function () {
console.warn(
'HTMX event handler "' + funcName + '" was called but not defined. Providing safety fallback.'
);
};
}
});
})();🧰 Tools
🪛 ast-grep (0.40.5)
[warning] 69-69: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.3.13)
[error] 70-70: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🤖 Prompt for AI Agents
In `@app/layout.tsx` around lines 68 - 90, Move the inline HTMX fallback script
out of app/layout.tsx into an external static file (e.g.,
public/htmx-fallback.js) that contains the IIFE creating the htmxEvents array
and the window['func ' + event] safety handlers, then load that file with
Next.js's next/script using strategy="beforeInteractive" in layout.tsx (or
alternatively generate and apply a CSP nonce and add it to the inline script) so
the bootstrap runs when script-src disallows unsafe-inline; update references to
the IIFE/htmxEvents and the window handler names (the 'func ' + event handlers)
to ensure the same behavior after moving the code.
User description
This PR adds a global safety fallback for HTMX event handlers in the root layout. This prevents production failures caused by browser extensions (like Phantom Wallet) attempting to call undefined HTMX functions during SSE streams.
PR Type
Bug fix
Description
Adds global safety fallback for HTMX event handlers in root layout
Prevents production failures from browser extensions calling undefined functions
Defines stub functions for 11 HTMX events with console warnings
Executes initialization script in document head before body rendering
Diagram Walkthrough
File Walkthrough
layout.tsx
Add HTMX event handler safety fallback scriptapp/layout.tsx
section with inline script to root layoutetc.)
Summary by CodeRabbit