Skip to content

Conversation

@birkskyum
Copy link
Member

@birkskyum birkskyum commented Oct 26, 2025

Blocked by

Related to

Summary by CodeRabbit

  • New Features

    • Added prerendering support with full end-to-end testing coverage and configuration.
  • Tests

    • Introduced prerender mode test suite verifying static route generation and content validation.
    • New test pipeline scripts for dedicated prerender mode testing.
    • Updated test workflow to include prerender mode in the overall testing pipeline.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 26, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR introduces end-to-end prerendering support for Solid Start. Changes include adding prerender mode detection utilities, new test scripts, updating Playwright and Vite configurations to support prerendering, adding a comprehensive prerendering test suite, and adjusting existing tests to account for prerender mode behavior.

Changes

Cohort / File(s) Summary
Build and Test Scripts
e2e/solid-start/basic/package.json
Added build:prerender script with MODE=prerender vite build && tsc --noEmit. Added prerender-specific e2e test scripts (test:e2e:prerender, test:e2e:startDummyServer, test:e2e:stopDummyServer). Updated test:e2e to include prerender mode via test:e2e:prerender chain.
Prerender Mode Support
e2e/solid-start/basic/tests/utils/isPrerender.ts
New utility file exporting isPrerender constant that detects prerender mode via process.env.MODE === 'prerender'.
Configuration Updates
e2e/solid-start/basic/playwright.config.ts, e2e/solid-start/basic/vite.config.ts
Updated Playwright config to detect prerender mode and select appropriate dev server command. Added Vite config with prerenderConfiguration object specifying prerender filters and maxRedirects: 100, conditionally passed to tanstackStart plugin.
Prerendering Tests
e2e/solid-start/basic/tests/prerendering.spec.ts
New test suite for prerendering verification. Includes tests for static route prerendering (verifying presence of index.html files for specific routes), exclusion of pathless layouts and API routes, and content validation of prerendered HTML files.
Test Mode Conditionals
e2e/solid-start/basic/tests/search-params.spec.ts
Updated import paths for utilities and added isPrerender import. Modified redirect assertions to exclude both SPA and prerender modes (!isSpaMode && !isPrerender). Removed trailing slashes in navigation URLs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • New test suite (prerendering.spec.ts) requires verification of test logic for route prerendering verification and HTML content assertions
  • Conditional logic changes in search-params.spec.ts need verification that prerender mode behavior aligns with redirect handling
  • Playwright config helper function (getCommand) logic should be validated for correct mode selection

Possibly related PRs

  • TanStack/router#5475: Implements and wires up prerendering support across the codebase with similar patterns of adding isPrerender utilities, prerender-specific tests, and vite/playwright configuration changes.

Suggested labels

package: solid-start

Suggested reviewers

  • schiller-manuel

Poem

🐰 With prerender mode now in sight,
Static routes are built just right,
Tests verify each HTML file,
Making builds prerendered and worthwhile!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title Check ✅ Passed The pull request title "test(solid-start): prerendering - sync #5475 to solid" is directly and clearly related to the changeset. The modifications across all files are focused on adding prerendering support to the solid-start e2e tests, including new build scripts, test suites, playwright configuration, and vite configuration. The title accurately captures this primary objective and specifies the scope (test, solid-start) and feature (prerendering). The title is concise, free from vague language or excessive noise, and would enable teammates scanning the history to quickly understand that this PR introduces prerendering functionality to the solid-start e2e test suite.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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.

❤️ Share

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

@nx-cloud
Copy link

nx-cloud bot commented Oct 26, 2025

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 7cc1c22

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

☁️ Nx Cloud last updated this comment at 2025-10-28 03:00:47 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 26, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: 7cc1c22

@birkskyum birkskyum changed the title test(solid-start): prerendering - sync #5476 to solid test(solid-start): prerendering - sync #5475 to solid Oct 26, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
e2e/solid-start/basic/tests/prerendering.spec.ts (2)

10-31: Consider adding a dist directory existence check.

The test assumes dist/client exists without verifying. If the build fails or the test runs from an unexpected location, the error messages could be confusing.

Apply this diff to add an initial check:

  test('should automatically discover and prerender static routes', () => {
    // Check that static routes were automatically discovered and prerendered
    const distDir = join(process.cwd(), 'dist', 'client')
+   expect(existsSync(distDir)).toBe(true)

    // These static routes should be automatically discovered and prerendered
    expect(existsSync(join(distDir, 'index.html'))).toBe(true)

34-52: Consider parameterizing the content verification tests.

The two tests have identical structure and could be combined using test.each to reduce duplication and make it easier to add more content checks.

Example refactor:

test.describe('Static Files Verification', () => {
  test.each([
    { route: 'posts', expectedContent: 'Select a post.' },
    { route: 'users', expectedContent: 'Select a user.' },
  ])('should contain prerendered content in $route.html', ({ route, expectedContent }) => {
    const distDir = join(process.cwd(), 'dist', 'client')
    const htmlPath = join(distDir, route, 'index.html')
    
    expect(existsSync(htmlPath)).toBe(true)
    const html = readFileSync(htmlPath, 'utf-8')
    expect(html).toContain(expectedContent)
  })
})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e557f9 and 7b61b60.

📒 Files selected for processing (6)
  • e2e/solid-start/basic/package.json (1 hunks)
  • e2e/solid-start/basic/playwright.config.ts (4 hunks)
  • e2e/solid-start/basic/tests/prerendering.spec.ts (1 hunks)
  • e2e/solid-start/basic/tests/search-params.spec.ts (4 hunks)
  • e2e/solid-start/basic/tests/utils/isPrerender.ts (1 hunks)
  • e2e/solid-start/basic/vite.config.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • e2e/solid-start/basic/tests/utils/isPrerender.ts
  • e2e/solid-start/basic/vite.config.ts
  • e2e/solid-start/basic/tests/search-params.spec.ts
  • e2e/solid-start/basic/playwright.config.ts
  • e2e/solid-start/basic/tests/prerendering.spec.ts
e2e/**

📄 CodeRabbit inference engine (AGENTS.md)

Store end-to-end tests under the e2e/ directory

Files:

  • e2e/solid-start/basic/tests/utils/isPrerender.ts
  • e2e/solid-start/basic/package.json
  • e2e/solid-start/basic/vite.config.ts
  • e2e/solid-start/basic/tests/search-params.spec.ts
  • e2e/solid-start/basic/playwright.config.ts
  • e2e/solid-start/basic/tests/prerendering.spec.ts
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Use workspace:* protocol for internal dependencies in package.json files

Files:

  • e2e/solid-start/basic/package.json
🧬 Code graph analysis (4)
e2e/solid-start/basic/vite.config.ts (1)
e2e/solid-start/basic/tests/utils/isPrerender.ts (1)
  • isPrerender (1-1)
e2e/solid-start/basic/tests/search-params.spec.ts (1)
e2e/solid-start/basic/tests/utils/isPrerender.ts (1)
  • isPrerender (1-1)
e2e/solid-start/basic/playwright.config.ts (2)
e2e/solid-start/basic/tests/utils/isSpaMode.ts (1)
  • isSpaMode (1-1)
e2e/solid-start/basic/tests/utils/isPrerender.ts (1)
  • isPrerender (1-1)
e2e/solid-start/basic/tests/prerendering.spec.ts (1)
e2e/solid-start/basic/tests/utils/isPrerender.ts (1)
  • isPrerender (1-1)
🔇 Additional comments (11)
e2e/solid-start/basic/vite.config.ts (2)

6-6: LGTM!

The import follows the established pattern of the isSpaMode utility.


15-26: Clarify the filter logic concern — one example is invalid, and the suggested fix has issues.

The substring matching concern is partially valid but contains errors:

  • Valid: A path like /redirect-me would incorrectly match and be filtered out (false positive)
  • Invalid: A path /not-found/something/else would NOT match /not-found/via-loader (that substring doesn't exist in the path)

Additionally, the first suggested fix is incorrect: .includes(page.path) checks if the array contains the path as an element (exact matching), which is not the intended behavior.

The .startsWith() approach would be appropriate if you want prefix-based exclusion of all nested routes under /redirect and /not-found. However, you should verify whether the current substring-matching behavior is intentional given that the codebase has routes like /redirect/$target/via-beforeLoad that would match the /redirect pattern regardless.

e2e/solid-start/basic/tests/utils/isPrerender.ts (1)

1-1: LGTM!

Clean utility following the established pattern of isSpaMode.

e2e/solid-start/basic/playwright.config.ts (3)

7-8: LGTM!

The imports are correct, and the JSON import assertion syntax is appropriate.


28-28: LGTM!

The console logging helps with debugging test execution modes.


46-46: LGTM!

Using the getCommand() helper improves code clarity.

e2e/solid-start/basic/tests/search-params.spec.ts (2)

31-33: LGTM!

The updated redirect logic correctly accounts for prerender mode. Prerendered pages are static, so server-side redirects don't occur at request time—they're handled during the build.

Also applies to: 56-58


69-69: LGTM!

URL normalization by removing the unnecessary trailing slash before the query parameters improves consistency.

e2e/solid-start/basic/tests/prerendering.spec.ts (1)

1-8: LGTM!

The imports are appropriate for filesystem-based prerender verification, and the conditional skip ensures tests only run in the correct mode.

e2e/solid-start/basic/package.json (2)

11-11: LGTM!

The build script follows the established pattern and correctly sets the MODE environment variable.


18-19: LGTM!

The test scripts properly integrate prerender mode into the e2e test workflow, and the sequential chaining with && ensures that failures in any mode stop the test run.

Comment on lines +20 to +26
const prerenderModeCommand = `pnpm run test:e2e:startDummyServer && pnpm build:prerender && pnpm run test:e2e:stopDummyServer && pnpm start`

const getCommand = () => {
if (isSpaMode) return spaModeCommand
if (isPrerender) return prerenderModeCommand
return ssrModeCommand
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Review the dummy server lifecycle management for potential issues.

The prerenderModeCommand chains commands with &&, which could lead to:

  1. Resource leak: If build:prerender fails, stopDummyServer won't execute, leaving the dummy server running.
  2. Race condition: There's no synchronization between startDummyServer and build:prerender. If the dummy server takes time to initialize, the build might start before the server is ready.

The getCommand() helper refactoring is clean and improves readability.

Consider adding error handling to ensure cleanup:

-const prerenderModeCommand = `pnpm run test:e2e:startDummyServer && pnpm build:prerender && pnpm run test:e2e:stopDummyServer && pnpm start`
+const prerenderModeCommand = `pnpm run test:e2e:startDummyServer && (pnpm build:prerender; pnpm run test:e2e:stopDummyServer) && pnpm start`

Or verify that the dummy server scripts include their own timeout/retry logic to handle startup delays.


🏁 Script executed:

#!/bin/bash
# View the playwright config file to see the current state
cat e2e/solid-start/basic/playwright.config.ts

Length of output: 1965


🏁 Script executed:

#!/bin/bash
# Search for dummy server script definitions in package.json or other config files
fd -t f "package.json" | head -5 | xargs -I {} sh -c 'echo "=== {} ===" && grep -A 2 -B 2 "startDummyServer\|stopDummyServer" {} 2>/dev/null || true'

Length of output: 254


🏁 Script executed:

#!/bin/bash
# Check for any scripts directory or test setup files that might define the dummy server
fd -t f "(startDummyServer|stopDummyServer|dummy)" e2e/

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Look for any error handling or cleanup logic in e2e test setup
rg -n "trap\|catch\|error\|cleanup" e2e/solid-start/basic/ --type ts --type js

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for dummy server script definitions in root package.json
cat package.json | grep -A 100 '"scripts"' | head -50

Length of output: 2485


🏁 Script executed:

#!/bin/bash
# Search for these specific scripts across the entire codebase
rg -n "startDummyServer|stopDummyServer" --type json --type ts --type js -B 1 -A 1

Length of output: 1672


🏁 Script executed:

#!/bin/bash
# Check if there's a workspace configuration that might define these scripts
fd -t f "pnpm-workspace.yaml|turbo.json|package.json" -x grep -l "startDummyServer\|stopDummyServer" {} \;

Length of output: 73


🏁 Script executed:

#!/bin/bash
# View the global setup and teardown files to understand their robustness
cat e2e/solid-start/basic/tests/setup/global.setup.ts

Length of output: 220


🏁 Script executed:

#!/bin/bash
# View teardown file
cat e2e/solid-start/basic/tests/setup/global.teardown.ts

Length of output: 221


🏁 Script executed:

#!/bin/bash
# Check if there are any existing error handling patterns in the e2e config or setup
grep -r "trap\|error\|catch\|finally" e2e/solid-start/basic/tests/setup/ --include="*.ts" -n

Length of output: 0


Address dummy server lifecycle management issues in prerender command.

The resource leak and race condition concerns are confirmed valid:

  1. Resource leak: If build:prerender fails, stopDummyServer never executes due to && chaining, leaving the background dummy server process orphaned.
  2. Race condition: startDummyServer runs backgrounded (&), allowing build:prerender to start immediately without explicit synchronization. The server may still be initializing when the build begins.

The suggested fix using subshell syntax (pnpm build:prerender; pnpm run test:e2e:stopDummyServer) does ensure cleanup runs, but it changes error propagation—if cleanup fails, the subsequent pnpm start also fails.

Verify and apply one of these approaches:

  • Option A (Cleanup priority): Use the suggested subshell approach if cleanup failures should halt execution.
  • Option B (Explicit trap): Use shell trap to guarantee cleanup: trap 'pnpm run test:e2e:stopDummyServer' EXIT before the build.
  • Option C (Explicit wait): Add explicit wait logic after startDummyServer to ensure the dummy server is ready before proceeding.

Same issue exists in e2e/react-start/basic/playwright.config.ts line 20.

🤖 Prompt for AI Agents
In e2e/solid-start/basic/playwright.config.ts around lines 20 to 26, the
prerender command uses chained commands that can leak the background dummy
server and race with the build; replace the one-liner with a safe sequence that
starts the dummy server, waits for it to be ready, runs build:prerender, and
always stops the dummy server on exit—either (A) wrap build and cleanup in a
subshell so cleanup runs and failures propagate, (B) set a shell trap to run
pnpm run test:e2e:stopDummyServer on EXIT before starting the server, or (C) add
an explicit readiness wait after starting the server (e.g., polling a health
endpoint) then run build and finally stop the server; apply the same change to
e2e/react-start/basic/playwright.config.ts at line 20.

Comment on lines +3 to +4
import { isSpaMode } from 'tests/utils/isSpaMode'
import { isPrerender } from './utils/isPrerender'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent import paths for utilities.

Line 3 uses tests/utils/isSpaMode (absolute/tsconfig path) while line 4 uses ./utils/isPrerender (relative path). For consistency, both utilities should use the same import pattern.

Apply this diff to make imports consistent:

-import { isSpaMode } from 'tests/utils/isSpaMode'
-import { isPrerender } from './utils/isPrerender'
+import { isSpaMode } from './utils/isSpaMode'
+import { isPrerender } from './utils/isPrerender'

Or if tsconfig paths are preferred:

-import { isSpaMode } from 'tests/utils/isSpaMode'
-import { isPrerender } from './utils/isPrerender'
+import { isSpaMode } from 'tests/utils/isSpaMode'
+import { isPrerender } from 'tests/utils/isPrerender'
📝 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
import { isSpaMode } from 'tests/utils/isSpaMode'
import { isPrerender } from './utils/isPrerender'
import { isSpaMode } from 'tests/utils/isSpaMode'
import { isPrerender } from 'tests/utils/isPrerender'
🤖 Prompt for AI Agents
In e2e/solid-start/basic/tests/search-params.spec.ts around lines 3 to 4, the
two utility imports use inconsistent paths (one using tsconfig/absolute
'tests/utils/isSpaMode' and the other a relative './utils/isPrerender'); make
them consistent by changing the import so both use the same pattern—either
update line 3 to a relative import './utils/isSpaMode' or update line 4 to the
tsconfig path 'tests/utils/isPrerender' depending on the project convention
(prefer tsconfig paths if that is the established pattern), and run a quick
compile to ensure the chosen path resolves.

@birkskyum birkskyum force-pushed the sync-#5475-to-solid branch from 7b61b60 to 7ea0729 Compare October 26, 2025 01:29
@birkskyum birkskyum marked this pull request as draft October 26, 2025 02:16
@birkskyum birkskyum added the ssr Everything around SSR the story label Oct 26, 2025
@birkskyum birkskyum added this to the catch up solid to react milestone Oct 26, 2025
@birkskyum birkskyum force-pushed the sync-#5475-to-solid branch from 7ea0729 to e87340c Compare October 26, 2025 23:12
@birkskyum birkskyum force-pushed the sync-#5475-to-solid branch 4 times, most recently from 67fb5fd to 0f51b20 Compare October 28, 2025 00:13
@birkskyum birkskyum force-pushed the sync-#5475-to-solid branch from 0f51b20 to 7cc1c22 Compare October 28, 2025 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: start-plugin-core ssr Everything around SSR the story

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants