3 Commits
Author SHA1 Message Date
valknarandClaude Sonnet 5 20989987f6 Suppress hydration-warning noise from browser-extension DOM tweaks on body
cz-shortcut-listen is ColorZilla's own marker attribute, injected into
<body> client-side before React hydrates - not an app bug. This only
silences mismatches on body's own attributes, not its children, so a
real hydration bug elsewhere would still surface normally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 19:49:08 +02:00
valknarandClaude Sonnet 5 9dc45f751a Delegate non-/ws/runs upgrade requests to Next instead of dropping them
Our upgrade handler on the shared httpServer was destroying every socket
that wasn't for /ws/runs, which silently killed Next's own dev-mode HMR
websocket (/_next/hmr) too - breaking hot reload with no useful error,
just a failed WebSocket connection in the browser console. Delegate to
app.getUpgradeHandler() instead, which must be called after prepare().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 19:46:41 +02:00
valknarandClaude Sonnet 5 d3e3360d6e Remove deprecated url.parse() usage from the custom server
Node flags legacy url.parse() (DEP0169) as having security implications
and recommends the WHATWG URL API instead. The main request handler's
parsedUrl argument to Next's handle() is optional and unused by us, so
that call is dropped entirely (matching Next's own minimal custom-server
example); the WS upgrade path-check now uses `new URL()` instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 19:41:37 +02:00
2 changed files with 7 additions and 5 deletions
+6 -4
View File
@@ -1,6 +1,5 @@
import "./src/bootstrap/async-local-storage-polyfill";
import { createServer } from "node:http";
import { parse } from "node:url";
import next from "next";
import { WebSocketServer } from "ws";
import { getConfig } from "./src/lib/config/load";
@@ -24,17 +23,20 @@ const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const nextUpgradeHandler = app.getUpgradeHandler();
const httpServer = createServer((req, res) => {
handle(req, res, parse(req.url ?? "/", true));
handle(req, res);
});
const wss = new WebSocketServer({ noServer: true });
attachWsServer(wss);
httpServer.on("upgrade", (req, socket, head) => {
const { pathname } = parse(req.url ?? "/");
const { pathname } = new URL(req.url ?? "/", "http://internal");
if (pathname !== "/ws/runs") {
socket.destroy();
// Anything else (e.g. Next's own dev-mode HMR websocket at /_next/hmr) is Next's to handle.
nextUpgradeHandler(req, socket, head).catch(() => socket.destroy());
return;
}
+1 -1
View File
@@ -29,7 +29,7 @@ export default function RootLayout({
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<body className="bg-background text-foreground flex min-h-full flex-col">
<body className="bg-background text-foreground flex min-h-full flex-col" suppressHydrationWarning>
<TooltipProvider>
{children}
<Toaster />