Skip to content

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Dec 23, 2025

Summary by CodeRabbit

  • New Features

    • Added a client-only page reachable from main navigation that shows a loading fallback and renders client-only content after hydration.
    • Added a WindowSize component that displays the current window width and height on the client.
  • Tests

    • Added end-to-end tests for navigation, server-rendered fallback, and client hydration of the window-size UI.
    • Added unit/snapshot tests covering server-side handling of client-only JSX patterns.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

Adds server-side detection and transformation for ClientOnly JSX, a new client-only demo route/component with E2E tests, and integrates JSX candidate collection and handling into the server-fn compiler pipeline.

Changes

Cohort / File(s) Summary
E2E Demo - Client-only route
e2e/react-start/basic/src/components/WindowSize.tsx, e2e/react-start/basic/src/routes/client-only.tsx, e2e/react-start/basic/src/routes/__root.tsx, e2e/react-start/basic/src/routeTree.gen.ts, e2e/react-start/basic/tests/client-only.spec.ts
New WindowSize component; adds /client-only file route and nav entry; registers route in generated route tree; E2E tests validate server fallback and client hydration rendering window dimensions.
Compiler — JSX handler
packages/start-plugin-core/src/create-server-fn-plugin/handleClientOnlyJSX.ts
New exported function handleClientOnlyJSX that strips children and converts matched ClientOnly JSX elements to self-closing elements for server output (preserves fallback prop when present).
Compiler — core integration
packages/start-plugin-core/src/create-server-fn-plugin/compiler.ts, packages/start-plugin-core/src/create-server-fn-plugin/plugin.ts
Introduces ClientOnlyJSX lookup kind, JSX detection utilities, collects JSX candidates during AST traversal (JSXElement visitor), integrates JSX candidate processing into candidate pipeline, and adds server lookup configuration for ClientOnly JSX.
Tests — clientOnlyJSX suite & fixtures
packages/start-plugin-core/tests/clientOnlyJSX/clientOnlyJSX.test.ts, packages/start-plugin-core/tests/clientOnlyJSX/test-files/*, packages/start-plugin-core/tests/clientOnlyJSX/snapshots/server/*
New test harness and numerous test files/snapshots covering basic, multiple, nested, aliased, non-TanStack imports, no-fallback, and negative cases to validate server-side JSX transformation behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant S as Source (TSX files)
  participant C as ServerFnCompiler
  participant H as handleClientOnlyJSX
  participant R as Server Renderer
  participant B as Browser (Client)

  Note over S,C: Build / compile time
  S->>C: Parse AST, detect ClientOnly imports and JSX usage
  C->>H: Send matching JSXElement node(s) (server env)
  H-->>C: Return transformed JSX (children removed, self-closing)
  C-->>R: Emit server-safe code / HTML with preserved fallbacks
  Note over R,B: Runtime / hydration
  R->>B: Send server-rendered HTML (fallback placeholders)
  B->>B: Hydration loads client bundles
  B->>B: Client-only components mount and render (e.g., WindowSize)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • nlynzaad

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: it introduces server-side handling to strip ClientOnly JSX element children during compilation, which is the core feature across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch client-only-server

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 169ef84 and c4faeee.

📒 Files selected for processing (1)
  • packages/start-plugin-core/src/create-server-fn-plugin/handleClientOnlyJSX.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/start-plugin-core/src/create-server-fn-plugin/handleClientOnlyJSX.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/start-plugin-core/src/create-server-fn-plugin/handleClientOnlyJSX.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (3)
packages/start-plugin-core/src/create-server-fn-plugin/handleClientOnlyJSX.ts (3)

1-2: LGTM! Clean type imports.

The type-only imports follow TypeScript best practices and properly reference the Babel types needed for AST transformation.


4-19: LGTM! Excellent documentation.

The JSDoc clearly explains the transformation purpose and provides helpful before/after examples for both fallback scenarios.


20-32: LGTM! Clean and correct transformation logic.

The implementation correctly transforms ClientOnly JSX elements by:

  1. Removing all children (client-only content)
  2. Converting to a self-closing tag

The mutation-based approach is standard for Babel transformations, and the type safety is solid. The unused _opts parameter (indicated by the underscore prefix) is appropriate for API consistency or future extensibility.


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

@nx-cloud
Copy link

nx-cloud bot commented Dec 23, 2025

View your CI Pipeline Execution ↗ for commit c4faeee

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 13m 20s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 20s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-23 07:25:27 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 23, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6193

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@6193

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6193

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6193

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6193

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6193

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6193

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6193

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6193

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6193

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6193

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6193

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6193

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6193

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6193

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6193

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6193

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6193

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6193

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6193

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@6193

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6193

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6193

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6193

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6193

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6193

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6193

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6193

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6193

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6193

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6193

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6193

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6193

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6193

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6193

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6193

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6193

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6193

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6193

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6193

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6193

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6193

commit: c4faeee

@schiller-manuel schiller-manuel merged commit 97d9f30 into main Dec 23, 2025
6 checks passed
@schiller-manuel schiller-manuel deleted the client-only-server branch December 23, 2025 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants