feat: add isBot option to renderRouterToStream for streaming SSR bot detection#7661
feat: add isBot option to renderRouterToStream for streaming SSR bot detection#7661anonrig wants to merge 2 commits into
isBot option to renderRouterToStream for streaming SSR bot detection#7661Conversation
Streaming SSR hardcoded the `isbot` User-Agent check that decides whether to wait for the full document (React `allReady`) before responding or to stream the shell first. Add an `ssr.isBot` router option (boolean | (request) => boolean) to override it; the default (undefined) keeps the current `isbot` behavior. Implemented across the react, solid, and vue adapters.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds an optional ChangesisBot configurable bot detection for SSR streaming
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (4)
packages/solid-router/src/ssr/renderRouterToStream.tsx (1)
18-19: ⚡ Quick winUse braces for
ifstatements inresolveIsBot.This currently breaks the repository control-statement style rule.
As per coding guidelines,
**/*.{ts,tsx,js,jsx}must always use curly braces forif,else, loops, and similar control statements.🤖 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/solid-router/src/ssr/renderRouterToStream.tsx` around lines 18 - 19, The if statements in the resolveIsBot function are missing curly braces, which violates the repository's control-statement style guidelines. Add curly braces around the return statements for both if conditions that check typeof isBot === 'function' and typeof isBot === 'boolean' to ensure consistent code style across the repository.Source: Coding guidelines
packages/react-router/src/ssr/renderRouterToStream.tsx (1)
48-49: ⚡ Quick winWrap
ifbranches in braces inresolveIsBot.This violates the project control-statement style rule for TS/TSX files.
Suggested fix
const resolveIsBot = (router: AnyRouter, request: Request): boolean => { const isBot = router.options.ssr?.isBot - if (typeof isBot === 'function') return isBot(request) - if (typeof isBot === 'boolean') return isBot + if (typeof isBot === 'function') { + return isBot(request) + } + if (typeof isBot === 'boolean') { + return isBot + } return isbot(request.headers.get('User-Agent')) }As per coding guidelines,
**/*.{ts,tsx,js,jsx}must always use curly braces forif,else, loops, and similar control statements.🤖 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-router/src/ssr/renderRouterToStream.tsx` around lines 48 - 49, The `if` statements in the `resolveIsBot` function are missing curly braces around their bodies, which violates the project's control-statement style rule. Add curly braces around both the `if (typeof isBot === 'function')` and `if (typeof isBot === 'boolean')` conditional bodies so that the return statements are wrapped within braces.Source: Coding guidelines
packages/vue-router/src/ssr/renderRouterToStream.tsx (1)
21-22: ⚡ Quick winAdd braces around
resolveIsBotifbranches.Current form violates the project JS/TS control-statement style requirement.
As per coding guidelines,
**/*.{ts,tsx,js,jsx}must always use curly braces forif,else, loops, and similar control statements.🤖 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/vue-router/src/ssr/renderRouterToStream.tsx` around lines 21 - 22, The two if statements in the resolveIsBot function that check the type of isBot are missing required curly braces around their bodies. Add curly braces around the return statement in the condition checking typeof isBot === 'function' and also add curly braces around the return statement in the condition checking typeof isBot === 'boolean' to comply with the project's control statement style requirements.Source: Coding guidelines
packages/router-core/src/router.ts (1)
515-517: ⚡ Quick winUse framework-neutral wording in core
ssr.isBotdocs.This API is shared across React/Solid/Vue adapters, but the comment currently names React-specific
allReady, which can mislead non-React users.Suggested doc tweak
- * document to render (React's `allReady`) before responding, so crawlers + * document to render before responding, so crawlers🤖 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/router-core/src/router.ts` around lines 515 - 517, The documentation comment for the ssr.isBot API contains React-specific terminology (React's `allReady`) that is not framework-neutral. Since this API is shared across React, Solid, and Vue adapters, replace the React-specific reference with framework-agnostic language that describes the same behavior (waiting for the entire document to render before responding to bot requests) without naming React APIs. Ensure the reworded comment clearly explains the bot detection behavior in terms that apply to all supported frameworks.
🤖 Prompt for all review comments with 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.
Nitpick comments:
In `@packages/react-router/src/ssr/renderRouterToStream.tsx`:
- Around line 48-49: The `if` statements in the `resolveIsBot` function are
missing curly braces around their bodies, which violates the project's
control-statement style rule. Add curly braces around both the `if (typeof isBot
=== 'function')` and `if (typeof isBot === 'boolean')` conditional bodies so
that the return statements are wrapped within braces.
In `@packages/router-core/src/router.ts`:
- Around line 515-517: The documentation comment for the ssr.isBot API contains
React-specific terminology (React's `allReady`) that is not framework-neutral.
Since this API is shared across React, Solid, and Vue adapters, replace the
React-specific reference with framework-agnostic language that describes the
same behavior (waiting for the entire document to render before responding to
bot requests) without naming React APIs. Ensure the reworded comment clearly
explains the bot detection behavior in terms that apply to all supported
frameworks.
In `@packages/solid-router/src/ssr/renderRouterToStream.tsx`:
- Around line 18-19: The if statements in the resolveIsBot function are missing
curly braces, which violates the repository's control-statement style
guidelines. Add curly braces around the return statements for both if conditions
that check typeof isBot === 'function' and typeof isBot === 'boolean' to ensure
consistent code style across the repository.
In `@packages/vue-router/src/ssr/renderRouterToStream.tsx`:
- Around line 21-22: The two if statements in the resolveIsBot function that
check the type of isBot are missing required curly braces around their bodies.
Add curly braces around the return statement in the condition checking typeof
isBot === 'function' and also add curly braces around the return statement in
the condition checking typeof isBot === 'boolean' to comply with the project's
control statement style requirements.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bd458c22-3db0-4906-ba99-ec2eb9016b26
📒 Files selected for processing (6)
.changeset/ssr-isbot-option.mdpackages/react-router/src/ssr/renderRouterToStream.tsxpackages/react-router/tests/renderRouterToStream.test.tsxpackages/router-core/src/router.tspackages/solid-router/src/ssr/renderRouterToStream.tsxpackages/vue-router/src/ssr/renderRouterToStream.tsx
createRouter runs isomorphically, so an `ssr.isBot` predicate (and anything it imports) would be bundled into the client. Move the option to `renderRouterToStream` (in ssr/server, server-only) so the bot decision is made in the request handler instead. Default behavior is unchanged. Reverts the router-core RouterOptions change.
ssr.isBot router option for streaming SSR bot detectionisBot option to renderRouterToStream for streaming SSR bot detection
Closes #7660
Summary
Streaming SSR waits for the entire document (React's
allReady) for requests thatisbotflags by theirUser-Agent, and streams the shell first for everyone else. It's a reasonable default, but it isn't configurable — andisbotclassifies synthetic performance tools (Lighthouse, PageSpeed Insights, WebPageTest, Pingdom, …) as bots, so lab audits get measured on the buffered path instead of the streaming path real users actually receive.This PR adds an
isBotoption torenderRouterToStreamso the decision is made in the server request handler, defaulting to the current behavior (no breaking change):Why the request handler, not
createRouterAn earlier revision put this on the router's
ssroptions. That's the wrong home:createRouterruns isomorphically, so anisBotpredicate (and anything it imports) would be bundled into the client.renderRouterToStreamlives inssr/serverand only ever runs on the server, so the option — and the user's predicate — stay server-side. It's also available in the Start path, whosedefaultStreamHandlercallsrenderRouterToStreamtoo.Changes
@tanstack/react-router,@tanstack/solid-router,@tanstack/vue-router:renderRouterToStreamacceptsisBot?: boolean | ((request: Request) => boolean), falling back toisbot(request.headers.get('User-Agent'))when unset.react-router/tests/renderRouterToStream.test.tsxcovering the default,true,false, and predicate forms.Verification
build— router-core + all three adapterstest:unit— react/solid/vuetest:types— ts5.5 → ts6.0 (all three adapters)test:eslint— 0 errorsSummary by CodeRabbit
New Features
isBotconfiguration option for streaming server-side rendering to customize how bot detection works