Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/bundle-size/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"vue": "^3.5.16"
},
"devDependencies": {
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/router-plugin": "workspace:^",
"@types/react": "^19.0.8",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-router/rspack-basic-file-based/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tanstack/router-e2e-utils": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tanstack/router-e2e-utils": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/vite": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/css-inline/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.0",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/router-e2e-utils": "workspace:^",
"@types/node": "^22.10.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/custom-server-rsbuild/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tanstack/router-e2e-utils": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/hmr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/vite": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/import-protection/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/router-e2e-utils": "workspace:^",
"@types/node": "^22.10.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/rsc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/eslint-plugin-start": "workspace:^",
"@tanstack/router-e2e-utils": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion e2e/react-start/server-functions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/vite": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/solid-router/rspack-basic-file-based/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-solid": "^1.1.1",
"@tailwindcss/postcss": "^4.2.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-solid": "^1.1.1",
"@tailwindcss/postcss": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/solid-start/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-solid": "^1.1.1",
"@tailwindcss/postcss": "^4.2.2",
Expand Down
2 changes: 1 addition & 1 deletion e2e/vue-router/rspack-basic-file-based/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-vue": "^1.2.7",
"@rsbuild/plugin-vue-jsx": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-vue": "^1.2.7",
"@rsbuild/plugin-vue-jsx": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion e2e/vue-start/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.0.5",
"@rsbuild/plugin-vue": "^1.2.2",
"@rsbuild/plugin-vue-jsx": "^1.1.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/react/quickstart-rspack-file-based/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"tailwindcss": "^4.2.2"
},
"devDependencies": {
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-react": "^2.0.0",
"@tanstack/router-plugin": "^1.167.35",
"@types/react": "^19.0.8",
Expand Down
2 changes: 1 addition & 1 deletion examples/solid/quickstart-rspack-file-based/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"tailwindcss": "^4.2.2"
},
"devDependencies": {
"@rsbuild/core": "^2.0.1",
"@rsbuild/core": "^2.0.6",
"@rsbuild/plugin-babel": "^1.1.2",
"@rsbuild/plugin-solid": "^1.1.1",
"@tanstack/router-plugin": "^1.167.35",
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@
"@tanstack/eslint-plugin-router": "workspace:*",
"@tanstack/router-utils": "workspace:*",
"@tanstack/start-static-server-functions": "workspace:*",
"@tanstack/nitro-v2-vite-plugin": "workspace:*"
"@tanstack/nitro-v2-vite-plugin": "workspace:*",
"@rspack/core": "npm:@rspack-canary/core@2.0.4-canary-32cafdc6-20260518042857"
}
}
}
17 changes: 10 additions & 7 deletions packages/react-start-rsc/src/awaitLazyElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ReactElement, ReactLazy, ReactSuspense } from './reactSymbols'

/**
* Optional callback for collecting CSS hrefs during tree traversal.
* Only called server-side when processing <link rel="stylesheet" data-rsc-css-href>
* Only called when processing explicitly marked RSC CSS stylesheet links.
*/
export type CssHrefCollector = (href: string) => void

/**
* Yields pending lazy element payloads from a tree, stopping at Suspense boundaries.
* Also collects CSS hrefs from <link rel="stylesheet" data-rsc-css-href> elements.
* Also collects CSS hrefs from explicitly marked RSC CSS stylesheet links.
*/
function* findPendingLazyPayloads(
obj: unknown,
Expand All @@ -26,14 +26,18 @@ function* findPendingLazyPayloads(
return
}

// Collect CSS hrefs from <link rel="stylesheet" data-rsc-css-href>
// The active RSC bundler adapter injects these for CSS module imports
// Collect CSS hrefs from explicit Start-managed CSS markers. Do not collect
// ordinary React 19 stylesheet resources here: preiniting those before render
// marks them inserted and bypasses React's suspensey stylesheet commit wait.
if (
el.$$typeof === ReactElement &&
el.type === 'link' &&
el.props?.rel === 'stylesheet'
) {
const cssHref = el.props['data-rsc-css-href'] as string | undefined
let cssHref: string | undefined
if ('data-rsc-css-href' in el.props) {
cssHref = el.props.href
}
if (cssHref && cssCollector) {
Comment on lines +37 to 41
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect marker-based href extraction and current lack of string guard.
rg -n -C3 "data-rsc-css-href|cssHref = el.props.href|cssCollector\\(" packages/react-start-rsc/src/awaitLazyElements.ts

Repository: TanStack/router

Length of output: 322


🏁 Script executed:

#!/bin/bash
# Get the full function context to understand types
head -80 packages/react-start-rsc/src/awaitLazyElements.ts | tail -80

Repository: TanStack/router

Length of output: 2466


🏁 Script executed:

#!/bin/bash
# Search for cssCollector definition and type signature
rg -n "cssCollector" packages/react-start-rsc/src/awaitLazyElements.ts -B 5 -A 5

Repository: TanStack/router

Length of output: 1717


🏁 Script executed:

#!/bin/bash
# Look for the function signature and parameter types
rg -n "function|const.*=.*\(" packages/react-start-rsc/src/awaitLazyElements.ts | head -20

Repository: TanStack/router

Length of output: 185


Guard href type before sending it to cssCollector.

At line 39, el.props.href comes from any and lacks a runtime type check before assignment to cssHref. Since CssHrefCollector expects (href: string) => void, a non-string value could violate the contract.

Proposed fix
-    let cssHref: string | undefined
-    if ('data-rsc-css-href' in el.props) {
-      cssHref = el.props.href
-    }
+    const cssHref =
+      'data-rsc-css-href' in el.props && typeof el.props.href === 'string'
+        ? el.props.href
+        : undefined

Per coding guidelines, **/*.{ts,tsx} must use TypeScript strict mode with extensive type safety.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let cssHref: string | undefined
if ('data-rsc-css-href' in el.props) {
cssHref = el.props.href
}
if (cssHref && cssCollector) {
const cssHref =
'data-rsc-css-href' in el.props && typeof el.props.href === 'string'
? el.props.href
: undefined
if (cssHref && cssCollector) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-start-rsc/src/awaitLazyElements.ts` around lines 37 - 41, The
code assigns el.props.href (of any type) to cssHref and passes it to
cssCollector without a runtime type check; update the logic in awaitLazyElements
(the block using cssHref, cssCollector and the 'data-rsc-css-href' prop) to
verify typeof el.props.href === 'string' before assigning to cssHref or invoking
cssCollector, ensuring cssHref remains a string | undefined and only string
values are passed into CssHrefCollector; keep the existing conditional flow
('data-rsc-css-href' in el.props then cssHref && cssCollector) but add the
runtime typeof guard to satisfy strict TypeScript safety.

cssCollector(cssHref)
}
Expand Down Expand Up @@ -71,8 +75,7 @@ function* findPendingLazyPayloads(
* This ensures client component chunks are fully loaded before rendering,
* preventing Suspense boundaries from flashing during SWR navigation.
*
* Also collects CSS hrefs from <link rel="stylesheet" data-rsc-css-href>
* elements for preloading in <head>.
* Also collects CSS hrefs from explicitly marked RSC CSS stylesheet links.
*
* @param tree - The tree to process
* @param cssCollector - Optional callback to collect CSS hrefs (server-only)
Expand Down
Loading