From 78c52bfbca4c422d46e83737e975b7e710dde57b Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 09:31:07 +0100 Subject: [PATCH 1/8] feat: improve perf --- .../src/client/embedded-dev-tools.tsx | 5 +---- .../react-router-devtools/src/client/tabs/NetworkTab.tsx | 9 ++++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index 6b83043..02a239f 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -10,7 +10,6 @@ import { Tabs } from "./layout/Tabs.js" import type { ReactRouterDevtoolsProps } from "./react-router-dev-tools.js" // Import to ensure global reset styles are injected import "./styles/use-styles.js" -import { RequestProvider } from "./context/requests/request-context.js" import { REACT_ROUTER_DEV_TOOLS } from "./utils/storage.js" export interface EmbeddedDevToolsProps extends ReactRouterDevtoolsProps { @@ -58,9 +57,7 @@ const EmbeddedDevTools = ({ config, mainPanelClassName, className }: EmbeddedDev return ( - - - + ) } diff --git a/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx b/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx index 073b8ad..7bbaf92 100644 --- a/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx @@ -1,10 +1,17 @@ import { TabHeader } from "../components/TabHeader.js" import { Icon } from "../components/icon/Icon.js" import NetworkPanel from "../components/network-tracer/NetworkPanel.js" -import { useRequestContext } from "../context/requests/request-context.js" +import { RequestProvider, useRequestContext } from "../context/requests/request-context.js" import { useStyles } from "../styles/use-styles.js" export const NetworkTab = () => { + return ( + + + + ) +} +const NetworkTabBase = () => { const { styles } = useStyles() const { requests, removeAllRequests, isLimitReached } = useRequestContext() From d4a63daca1157b5e754ede51aa19a750ec56fc85 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 11:12:18 +0100 Subject: [PATCH 2/8] add memo for better perf, hide until open --- packages/react-router-devtools/package.json | 1 + .../src/client/components/Tag.tsx | 6 +++--- .../src/client/components/icon/Icon.tsx | 6 +++--- .../src/client/embedded-dev-tools.tsx | 18 +++++++++++++----- pnpm-lock.yaml | 3 +++ 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/react-router-devtools/package.json b/packages/react-router-devtools/package.json index 0b9ab50..5e0a64b 100644 --- a/packages/react-router-devtools/package.json +++ b/packages/react-router-devtools/package.json @@ -131,6 +131,7 @@ "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@radix-ui/react-accordion": "^1.2.12", + "@tanstack/devtools-client": "^0.0.5", "@tanstack/devtools-event-client": "^0.4.0", "@tanstack/devtools-vite": "^0.4.1", "@tanstack/react-devtools": "^0.9.1", diff --git a/packages/react-router-devtools/src/client/components/Tag.tsx b/packages/react-router-devtools/src/client/components/Tag.tsx index 44f4267..94afe06 100644 --- a/packages/react-router-devtools/src/client/components/Tag.tsx +++ b/packages/react-router-devtools/src/client/components/Tag.tsx @@ -1,4 +1,4 @@ -import type { ReactNode } from "react" +import { type ReactNode, memo } from "react" import { cx, useStyles } from "../styles/use-styles.js" export const TAG_COLORS = { @@ -16,7 +16,7 @@ interface TagProps { size?: "small" | "default" } -const Tag = ({ color, children, className, size = "default" }: TagProps) => { +const Tag = memo(({ color, children, className, size = "default" }: TagProps) => { const { styles } = useStyles() return ( { {children} ) -} +}) export { Tag } diff --git a/packages/react-router-devtools/src/client/components/icon/Icon.tsx b/packages/react-router-devtools/src/client/components/icon/Icon.tsx index 2002fb8..e83aaa3 100644 --- a/packages/react-router-devtools/src/client/components/icon/Icon.tsx +++ b/packages/react-router-devtools/src/client/components/icon/Icon.tsx @@ -1,4 +1,4 @@ -import type { SVGProps } from "react" +import { type SVGProps, memo } from "react" import { cx } from "../../styles/use-styles.js" import { useStyles } from "../../styles/use-styles.js" import type { IconName } from "./icons/types.js" @@ -30,7 +30,7 @@ const strokeIcon: Partial[] = [] * Icon component wrapper for SVG icons. * @returns SVG icon as a react component */ -export const Icon = ({ name, title, testId, className, size = "sm", ...props }: IconProps) => { +export const Icon = memo(({ name, title, testId, className, size = "sm", ...props }: IconProps) => { const { styles } = useStyles() const iconSize = IconSize[size] const isEmptyFill = emptyFill.includes(name) @@ -316,4 +316,4 @@ export const Icon = ({ name, title, testId, className, size = "sm", ...props }: ) -} +}) diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index 02a239f..20536a0 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -10,8 +10,8 @@ import { Tabs } from "./layout/Tabs.js" import type { ReactRouterDevtoolsProps } from "./react-router-dev-tools.js" // Import to ensure global reset styles are injected import "./styles/use-styles.js" +import { devtoolsEventClient } from "@tanstack/devtools-client" import { REACT_ROUTER_DEV_TOOLS } from "./utils/storage.js" - export interface EmbeddedDevToolsProps extends ReactRouterDevtoolsProps { mainPanelClassName?: string className?: string @@ -21,6 +21,12 @@ const Embedded = ({ mainPanelClassName, className }: EmbeddedDevToolsProps) => { useFindRouteOutlets() useSetRouteBoundaries() + const [isOpen, setIsOpen] = useState(true) + useEffect(() => { + devtoolsEventClient.on("trigger-toggled", (e) => { + setIsOpen(e.payload.isOpen) + }) + }, []) return (
{ }} className={clsx("react-router-dev-tools", "h-full flex-row w-full", className)} > - - - - + {isOpen ? ( + + + + + ) : null}
) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29d4a26..a16af5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -244,6 +244,9 @@ importers: '@radix-ui/react-accordion': specifier: ^1.2.12 version: 1.2.12(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/devtools-client': + specifier: ^0.0.5 + version: 0.0.5 '@tanstack/devtools-event-client': specifier: ^0.4.0 version: 0.4.0 From 8b30a830fbf277284b3a1bd64d5ddd943f6dde5f Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 11:13:04 +0100 Subject: [PATCH 3/8] add memo for better perf, hide until open --- .../react-router-devtools/src/client/embedded-dev-tools.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index 20536a0..5e3b762 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -23,9 +23,10 @@ const Embedded = ({ mainPanelClassName, className }: EmbeddedDevToolsProps) => { const [isOpen, setIsOpen] = useState(true) useEffect(() => { - devtoolsEventClient.on("trigger-toggled", (e) => { + const cleanup = devtoolsEventClient.on("trigger-toggled", (e) => { setIsOpen(e.payload.isOpen) }) + return cleanup }, []) return (
Date: Wed, 14 Jan 2026 11:17:21 +0100 Subject: [PATCH 4/8] fix issue with statenodes --- .../src/client/hooks/useReactTreeListeners.ts | 2 +- packages/react-router-devtools/src/client/tabs/index.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-router-devtools/src/client/hooks/useReactTreeListeners.ts b/packages/react-router-devtools/src/client/hooks/useReactTreeListeners.ts index df2e922..b4127c3 100644 --- a/packages/react-router-devtools/src/client/hooks/useReactTreeListeners.ts +++ b/packages/react-router-devtools/src/client/hooks/useReactTreeListeners.ts @@ -21,7 +21,7 @@ export function useFindRouteOutlets() { const styleNearestElement = useCallback((fiberNode: any) => { if (!fiberNode) return - if (fiberNode.stateNode) { + if (typeof fiberNode?.stateNode?.classList?.add === "function") { return fiberNode.stateNode.classList.add(ROUTE_CLASS) } styleNearestElement(fiberNode.child) diff --git a/packages/react-router-devtools/src/client/tabs/index.tsx b/packages/react-router-devtools/src/client/tabs/index.tsx index 2cdf0b1..47a2c35 100644 --- a/packages/react-router-devtools/src/client/tabs/index.tsx +++ b/packages/react-router-devtools/src/client/tabs/index.tsx @@ -19,21 +19,21 @@ export const tabs = [ name: "Active page", icon: , id: "page", - component: PageTab, + component: () => , hideTimeline: false, }, { name: "Routes", icon: , id: "routes", - component: RoutesTab, + component: () => , hideTimeline: false, }, { name: "Network", icon: , id: "network", - component: NetworkTab, + component: () => , hideTimeline: true, }, From 11a486acc7a3c17776e93170f42b44b6e3d30493 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 11:25:13 +0100 Subject: [PATCH 5/8] fix issues --- .../src/client/components/TabContent.tsx | 5 +- .../src/client/embedded-dev-tools.tsx | 6 +- .../src/client/layout/Tabs.tsx | 63 ++++++++++--------- .../src/client/tabs/RoutesTab.tsx | 6 +- .../src/client/tabs/TimelineTab.tsx | 9 +-- 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/packages/react-router-devtools/src/client/components/TabContent.tsx b/packages/react-router-devtools/src/client/components/TabContent.tsx index accd18f..e3c38da 100644 --- a/packages/react-router-devtools/src/client/components/TabContent.tsx +++ b/packages/react-router-devtools/src/client/components/TabContent.tsx @@ -1,10 +1,11 @@ +import { memo } from "react" import { useStyles } from "../styles/use-styles.js" interface TabContentProps { children: React.ReactNode } -export const TabContent = ({ children }: TabContentProps) => { +export const TabContent = memo(({ children }: TabContentProps) => { const { styles } = useStyles() return
{children}
-} +}) diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index 5e3b762..a27be9a 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -1,5 +1,5 @@ import clsx from "clsx" -import { useEffect, useState } from "react" +import { memo, useEffect, useState } from "react" import { RDTContextProvider } from "./context/RDTContext.js" import { useFindRouteOutlets } from "./hooks/useReactTreeListeners.js" import { useSetRouteBoundaries } from "./hooks/useSetRouteBoundaries.js" @@ -16,7 +16,7 @@ export interface EmbeddedDevToolsProps extends ReactRouterDevtoolsProps { mainPanelClassName?: string className?: string } -const Embedded = ({ mainPanelClassName, className }: EmbeddedDevToolsProps) => { +const Embedded = memo(({ mainPanelClassName, className }: EmbeddedDevToolsProps) => { useTimelineHandler() useFindRouteOutlets() useSetRouteBoundaries() @@ -44,7 +44,7 @@ const Embedded = ({ mainPanelClassName, className }: EmbeddedDevToolsProps) => { ) : null}
) -} +}) let hydrating = true diff --git a/packages/react-router-devtools/src/client/layout/Tabs.tsx b/packages/react-router-devtools/src/client/layout/Tabs.tsx index 7246978..9046470 100644 --- a/packages/react-router-devtools/src/client/layout/Tabs.tsx +++ b/packages/react-router-devtools/src/client/layout/Tabs.tsx @@ -1,3 +1,4 @@ +import { memo } from "react" import { useSettingsContext } from "../context/useRDTContext.js" import { useHorizontalScroll } from "../hooks/useHorizontalScroll.js" import { useTabs } from "../hooks/useTabs.js" @@ -11,37 +12,39 @@ declare global { } } -const Tab = ({ - tab, - activeTab, - className, - onClick, -}: { - tab: TabType - activeTab?: string - className?: string - onClick?: () => void -}) => { - const { setSettings } = useSettingsContext() - const { styles } = useStyles() +const Tab = memo( + ({ + tab, + activeTab, + className, + onClick, + }: { + tab: TabType + activeTab?: string + className?: string + onClick?: () => void + }) => { + const { setSettings } = useSettingsContext() + const { styles } = useStyles() - return ( - - ) -} + return ( + + ) + } +) const Tabs = () => { const { settings } = useSettingsContext() diff --git a/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx b/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx index 20cd21e..de55b57 100644 --- a/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/RoutesTab.tsx @@ -50,7 +50,7 @@ const RoutesTab = () => { } // Add root from manifest - routeObject.root = window.__reactRouterManifest?.routes?.root + routeObject.root = { ...window.__reactRouterManifest?.routes?.root } // Update tree view routes with merged data setTreeRoutes(createRouteTree(routeObject)) @@ -63,9 +63,7 @@ const RoutesTab = () => { // Request routes info from the server AFTER listener is set up eventClient.emit("routes-tab-mounted", {}) - return () => { - unsubscribe() - } + return unsubscribe }, []) return (
diff --git a/packages/react-router-devtools/src/client/tabs/TimelineTab.tsx b/packages/react-router-devtools/src/client/tabs/TimelineTab.tsx index 5a93728..68d0595 100644 --- a/packages/react-router-devtools/src/client/tabs/TimelineTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/TimelineTab.tsx @@ -1,3 +1,4 @@ +import { memo } from "react" import { TabContent } from "../components/TabContent.js" import { TabHeader } from "../components/TabHeader.js" import { type TAG_COLORS, Tag } from "../components/Tag.js" @@ -17,7 +18,7 @@ const Translations: Record = { FETCHER_RESPONSE: "Fetcher action response", } -const RedirectEventComponent = (event: RedirectEvent) => { +const RedirectEventComponent = memo((event: RedirectEvent) => { const { styles } = useStyles() return (
@@ -31,9 +32,9 @@ const RedirectEventComponent = (event: RedirectEvent) => { )}
) -} +}) -const FormEventComponent = (event: FormEvent) => { +const FormEventComponent = memo((event: FormEvent) => { const { styles } = useStyles() const isRedirect = event.type === "ACTION_REDIRECT" const responseData = event.responseData @@ -73,7 +74,7 @@ const FormEventComponent = (event: FormEvent) => {
) -} +}) export const METHOD_COLORS: Record = { GET: "GREEN", From 650c47570dd866c4eeb5a15587effcc3d19e90fb Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 11:53:50 +0100 Subject: [PATCH 6/8] additional perf improvements --- .../src/client/components/jsonRenderer.tsx | 4 +- .../src/client/layout/ContentPanel.tsx | 6 +- .../src/client/layout/MainPanel.tsx | 5 +- .../src/client/layout/Tabs.tsx | 4 +- .../src/client/tabs/PageTab.tsx | 2 +- test-apps/react-router-vite/app/root.tsx | 201 +++++++++--------- 6 files changed, 114 insertions(+), 108 deletions(-) diff --git a/packages/react-router-devtools/src/client/components/jsonRenderer.tsx b/packages/react-router-devtools/src/client/components/jsonRenderer.tsx index d741327..661aae2 100644 --- a/packages/react-router-devtools/src/client/components/jsonRenderer.tsx +++ b/packages/react-router-devtools/src/client/components/jsonRenderer.tsx @@ -14,7 +14,7 @@ const isPromise = (value: any): value is Promise => { return value && typeof value.then === "function" } -const JsonRendererComponent = ({ data, expansionLevel }: JsonRendererProps) => { +const JsonRendererComponent = memo(({ data, expansionLevel }: JsonRendererProps) => { const { styles } = useStyles() const { settings } = useSettingsContext() const ref = useRef(true) @@ -71,7 +71,7 @@ const JsonRendererComponent = ({ data, expansionLevel }: JsonRendererProps) => { return ( ) -} +}) const JsonRenderer = memo(JsonRendererComponent) diff --git a/packages/react-router-devtools/src/client/layout/ContentPanel.tsx b/packages/react-router-devtools/src/client/layout/ContentPanel.tsx index 332ecfb..522b2d5 100644 --- a/packages/react-router-devtools/src/client/layout/ContentPanel.tsx +++ b/packages/react-router-devtools/src/client/layout/ContentPanel.tsx @@ -1,10 +1,10 @@ -import { Fragment } from "react" +import { Fragment, memo } from "react" import { useTabs } from "../hooks/useTabs.js" import { cx } from "../styles/use-styles.js" import { useStyles } from "../styles/use-styles.js" import { TimelineTab } from "../tabs/TimelineTab.js" -const ContentPanel = () => { +const ContentPanel = memo(() => { const { Component, hideTimeline, activeTab } = useTabs() const { styles } = useStyles() @@ -29,6 +29,6 @@ const ContentPanel = () => { )} ) -} +}) export { ContentPanel } diff --git a/packages/react-router-devtools/src/client/layout/MainPanel.tsx b/packages/react-router-devtools/src/client/layout/MainPanel.tsx index b06cc53..b21f0bc 100644 --- a/packages/react-router-devtools/src/client/layout/MainPanel.tsx +++ b/packages/react-router-devtools/src/client/layout/MainPanel.tsx @@ -1,3 +1,4 @@ +import { memo } from "react" import { cx } from "../styles/use-styles.js" import { useStyles } from "../styles/use-styles.js" @@ -8,7 +9,7 @@ interface MainPanelProps { className?: string } -const MainPanel = ({ children, isOpen, className }: MainPanelProps) => { +const MainPanel = memo(({ children, isOpen, className }: MainPanelProps) => { const { styles } = useStyles() return ( @@ -26,6 +27,6 @@ const MainPanel = ({ children, isOpen, className }: MainPanelProps) => { {children} ) -} +}) export { MainPanel } diff --git a/packages/react-router-devtools/src/client/layout/Tabs.tsx b/packages/react-router-devtools/src/client/layout/Tabs.tsx index 9046470..4e18c23 100644 --- a/packages/react-router-devtools/src/client/layout/Tabs.tsx +++ b/packages/react-router-devtools/src/client/layout/Tabs.tsx @@ -46,7 +46,7 @@ const Tab = memo( } ) -const Tabs = () => { +const Tabs = memo(() => { const { settings } = useSettingsContext() const { styles } = useStyles() const { activeTab } = settings @@ -62,6 +62,6 @@ const Tabs = () => { ) -} +}) export { Tabs } diff --git a/packages/react-router-devtools/src/client/tabs/PageTab.tsx b/packages/react-router-devtools/src/client/tabs/PageTab.tsx index 73922c3..d5e8e84 100644 --- a/packages/react-router-devtools/src/client/tabs/PageTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/PageTab.tsx @@ -13,7 +13,7 @@ const PageTab = () => { const { revalidate, state } = useRevalidator() // Memoize reversed routes to avoid creating new array on every render - const reversedRoutes = useMemo(() => routes.toReversed(), [routes]) + const reversedRoutes = useMemo(() => [...routes.toReversed()], [routes]) return ( <> diff --git a/test-apps/react-router-vite/app/root.tsx b/test-apps/react-router-vite/app/root.tsx index b4dc2bb..cf17051 100644 --- a/test-apps/react-router-vite/app/root.tsx +++ b/test-apps/react-router-vite/app/root.tsx @@ -1,98 +1,103 @@ -import { - type ActionFunctionArgs, - data, - Links, - type LoaderFunctionArgs, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "react-router"; -import { userSomething } from "./modules/user.server"; - -// Server middleware -const authMiddleware = async (args: any, next: () => Promise) => { - console.log("Auth middleware - checking authentication"); - return next(); -} - -const loggingMiddleware = async (args: any, next: () => Promise) => { - console.log("Logging middleware - request:", args.request.url); - const response = await next(); - console.log("Logging middleware - response status:", response.status); - return response; -} - -export const middleware = [authMiddleware, loggingMiddleware]; - -// Client middleware -const clientAuthMiddleware = async (args: any, next: () => Promise) => { - console.log("Client auth middleware - checking client-side authentication"); - return next(); -} - -const clientLoggingMiddleware = async (args: any, next: () => Promise) => { - console.log("Client logging middleware - request:", args.request.url); - const response = await next(); - console.log("Client logging middleware - response status:", response.status); - return response; -} - -export const clientMiddleware = [ - clientAuthMiddleware, - clientLoggingMiddleware, -]; - -export const links = () => []; - -export const loader = ({context, devTools }: LoaderFunctionArgs) => { - userSomething(); - const mainPromise = new Promise((resolve, reject) => { - setTimeout(() => { - const subPromise = new Promise((resolve, reject) => { - setTimeout(() => { - resolve("test"); - }, 2000); - }); - resolve({ test: "test", subPromise}); - }, 2000); - }); - console.log("loader called"); - const end =devTools?.tracing.start("test")!; - end(); - return data({ message: "Hello World", mainPromise, bigInt: BigInt(10) }, ); -} - -export const action =async ({devTools}: ActionFunctionArgs) => { - const end = devTools?.tracing.start("action submission") - await new Promise((resolve, reject) => { - setTimeout(() => { - resolve("test"); - }, 2000); - }); - end?.(); - console.log("action called"); - return ({ message: "Hello World", bigInt: BigInt(10) }); -} - -function App() { - return ( - - - - - - - - - - - - - - - - ); -} - -export { App as default } \ No newline at end of file +import type { Route } from "./+types/root"; +import { + type ActionFunctionArgs, + data, + Links, + type LoaderFunctionArgs, + Meta, + Outlet, + Scripts, + ScrollRestoration } from +"react-router"; +import { userSomething } from "./modules/user.server"; + +// Server middleware +const authMiddleware = async (args: any, next: () => Promise) => { + console.log("Auth middleware - checking authentication"); + return next(); +}; + +const loggingMiddleware = async (args: any, next: () => Promise) => { + console.log("Logging middleware - request:", args.request.url); + const response = await next(); + console.log("Logging middleware - response status:", response.status); + return response; +}; + +export const middleware: Route.MiddlewareFunction[] = [authMiddleware, loggingMiddleware]; + +// Client middleware +const clientAuthMiddleware = async (args: any, next: () => Promise) => { + console.log("Client auth middleware - checking client-side authentication"); + return next(); +}; + +const clientLoggingMiddleware = async (args: any, next: () => Promise) => { + console.log("Client logging middleware - request:", args.request.url); + const response = await next(); + console.log("Client logging middleware - response status:", response.status); + return response; +}; + +export const clientMiddleware: Route.ClientMiddlewareFunction[] = [ +clientAuthMiddleware, +clientLoggingMiddleware]; + + +export const links = () => []; + +export const loader = ({ context, devTools }: LoaderFunctionArgs) => { + userSomething(); + const mainPromise = new Promise((resolve, reject) => { + setTimeout(() => { + const subPromise = new Promise((resolve, reject) => { + setTimeout(() => { + resolve("test"); + }, 2000); + }); + resolve({ test: "test", subPromise }); + }, 2000); + }); + console.log("loader called"); + const end = devTools?.tracing.start("test")!; + end(); + return data({ message: "Hello World", mainPromise, bigInt: BigInt(10) }); +}; + +export const action = async ({ devTools }: ActionFunctionArgs) => { + const end = devTools?.tracing.start("action submission"); + await new Promise((resolve, reject) => { + setTimeout(() => { + resolve("test"); + }, 2000); + }); + end?.(); + console.log("action called"); + return { message: "Hello World", bigInt: BigInt(10) }; +}; + +function App() { + return ( + + + + + + + + + + + + + + + + ); + +} + +export { App as default }; \ No newline at end of file From f836e18cf60f108c9e11ffad131194c9b5ecf694 Mon Sep 17 00:00:00 2001 From: Alem Tuzlak Date: Wed, 14 Jan 2026 12:15:04 +0100 Subject: [PATCH 7/8] revert provider location --- .../src/client/embedded-dev-tools.tsx | 5 ++++- .../src/client/tabs/NetworkTab.tsx | 10 +--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx index a27be9a..fe89ce4 100644 --- a/packages/react-router-devtools/src/client/embedded-dev-tools.tsx +++ b/packages/react-router-devtools/src/client/embedded-dev-tools.tsx @@ -11,6 +11,7 @@ import type { ReactRouterDevtoolsProps } from "./react-router-dev-tools.js" // Import to ensure global reset styles are injected import "./styles/use-styles.js" import { devtoolsEventClient } from "@tanstack/devtools-client" +import { RequestProvider } from "./context/requests/request-context.js" import { REACT_ROUTER_DEV_TOOLS } from "./utils/storage.js" export interface EmbeddedDevToolsProps extends ReactRouterDevtoolsProps { mainPanelClassName?: string @@ -66,7 +67,9 @@ const EmbeddedDevTools = ({ config, mainPanelClassName, className }: EmbeddedDev return ( - + + + ) } diff --git a/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx b/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx index 7bbaf92..1475dc4 100644 --- a/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx +++ b/packages/react-router-devtools/src/client/tabs/NetworkTab.tsx @@ -1,20 +1,12 @@ import { TabHeader } from "../components/TabHeader.js" import { Icon } from "../components/icon/Icon.js" import NetworkPanel from "../components/network-tracer/NetworkPanel.js" -import { RequestProvider, useRequestContext } from "../context/requests/request-context.js" +import { useRequestContext } from "../context/requests/request-context.js" import { useStyles } from "../styles/use-styles.js" export const NetworkTab = () => { - return ( - - - - ) -} -const NetworkTabBase = () => { const { styles } = useStyles() const { requests, removeAllRequests, isLimitReached } = useRequestContext() - return (
Date: Wed, 14 Jan 2026 12:22:06 +0100 Subject: [PATCH 8/8] version bump --- packages/react-router-devtools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-router-devtools/package.json b/packages/react-router-devtools/package.json index 5e0a64b..7fe3b0d 100644 --- a/packages/react-router-devtools/package.json +++ b/packages/react-router-devtools/package.json @@ -2,7 +2,7 @@ "name": "react-router-devtools", "description": "Devtools for React Router - debug, trace, find hydration errors, catch bugs and inspect server/client data with react-router-devtools", "author": "Alem Tuzlak", - "version": "6.1.0", + "version": "6.2.0", "license": "MIT", "keywords": [ "react-router",