diff --git a/packages/react-router/src/Matches.tsx b/packages/react-router/src/Matches.tsx
index 5b34093f09..3e8d27bdf4 100644
--- a/packages/react-router/src/Matches.tsx
+++ b/packages/react-router/src/Matches.tsx
@@ -54,7 +54,7 @@ export function Matches() {
const inner = (
-
+ {!router.isServer && }
)
diff --git a/packages/react-router/src/Transitioner.tsx b/packages/react-router/src/Transitioner.tsx
index 75b913bb33..04e140acfc 100644
--- a/packages/react-router/src/Transitioner.tsx
+++ b/packages/react-router/src/Transitioner.tsx
@@ -30,14 +30,12 @@ export function Transitioner() {
const isPagePending = isLoading || hasPendingMatches
const previousIsPagePending = usePrevious(isPagePending)
- if (!router.isServer) {
- router.startTransition = (fn: () => void) => {
- setIsTransitioning(true)
- React.startTransition(() => {
- fn()
- setIsTransitioning(false)
- })
- }
+ router.startTransition = (fn: () => void) => {
+ setIsTransitioning(true)
+ React.startTransition(() => {
+ fn()
+ setIsTransitioning(false)
+ })
}
// Subscribe to location changes
diff --git a/packages/solid-router/package.json b/packages/solid-router/package.json
index 6f39d7b4c3..7e62c34df2 100644
--- a/packages/solid-router/package.json
+++ b/packages/solid-router/package.json
@@ -33,7 +33,7 @@
"test:types:ts56": "node ../../node_modules/typescript56/lib/tsc.js -p tsconfig.legacy.json",
"test:types:ts57": "node ../../node_modules/typescript57/lib/tsc.js -p tsconfig.legacy.json",
"test:types:ts58": "tsc -p tsconfig.legacy.json",
- "test:unit": "vitest",
+ "test:unit": "vitest && vitest --mode server",
"test:unit:dev": "pnpm run test:unit --watch --hideSkippedTests",
"test:perf": "vitest bench",
"test:perf:dev": "pnpm run test:perf --watch --hideSkippedTests",
diff --git a/packages/solid-router/src/Matches.tsx b/packages/solid-router/src/Matches.tsx
index 0735f16078..f11814112c 100644
--- a/packages/solid-router/src/Matches.tsx
+++ b/packages/solid-router/src/Matches.tsx
@@ -50,7 +50,7 @@ export function Matches() {
const inner = (
-
+ {!router.isServer && }
)
diff --git a/packages/solid-router/src/Transitioner.tsx b/packages/solid-router/src/Transitioner.tsx
index d277a20c5e..2d602a2022 100644
--- a/packages/solid-router/src/Transitioner.tsx
+++ b/packages/solid-router/src/Transitioner.tsx
@@ -30,12 +30,10 @@ export function Transitioner() {
const isPagePending = () => isLoading() || hasPendingMatches()
const previousIsPagePending = usePrevious(isPagePending)
- if (!router.isServer) {
- router.startTransition = async (fn: () => void | Promise) => {
- setIsTransitioning(true)
- await fn()
- setIsTransitioning(false)
- }
+ router.startTransition = async (fn: () => void | Promise) => {
+ setIsTransitioning(true)
+ await fn()
+ setIsTransitioning(false)
}
// Subscribe to location changes
@@ -66,7 +64,6 @@ export function Transitioner() {
// Try to load the initial location
Solid.createRenderEffect(() => {
- if (router.isServer) return
Solid.untrack(() => {
if (
// if we are hydrating from SSR, loading is triggered in ssr-client
@@ -100,6 +97,7 @@ export function Transitioner() {
},
),
)
+
Solid.createRenderEffect(
Solid.on(
[isPagePending, previousIsPagePending],
diff --git a/packages/solid-router/tests/Transitioner.test.tsx b/packages/solid-router/tests/Transitioner.test.tsx
index 5467795e22..ffd3ffb100 100644
--- a/packages/solid-router/tests/Transitioner.test.tsx
+++ b/packages/solid-router/tests/Transitioner.test.tsx
@@ -10,11 +10,13 @@ import { RouterProvider } from '../src/RouterProvider'
describe('Transitioner', () => {
it('should call router.load() when Transitioner mounts on the client', async () => {
+ const loader = vi.fn()
const rootRoute = createRootRoute()
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: () => Index
,
+ loader,
})
const routeTree = rootRoute.addChildren([indexRoute])
@@ -26,43 +28,16 @@ describe('Transitioner', () => {
})
// Mock router.load() to verify it gets called
- const loadSpy = vi.spyOn(router, 'load').mockResolvedValue(undefined)
+ const loadSpy = vi.spyOn(router, 'load')
- render(() => )
-
- // Wait for the createRenderEffect to run and call router.load()
- await waitFor(() => {
- expect(loadSpy).toHaveBeenCalledTimes(1)
- })
-
- loadSpy.mockRestore()
- })
-
- it('should not call router.load() when on the server', async () => {
- const rootRoute = createRootRoute()
- const indexRoute = createRoute({
- getParentRoute: () => rootRoute,
- path: '/',
- component: () => Index
,
- })
-
- const routeTree = rootRoute.addChildren([indexRoute])
- const router = createRouter({
- routeTree,
- history: createMemoryHistory({
- initialEntries: ['/'],
- }),
- isServer: true,
- })
-
- // Mock router.load() to verify it gets called
- const loadSpy = vi.spyOn(router, 'load').mockResolvedValue(undefined)
+ await router.load()
render(() => )
// Wait for the createRenderEffect to run and call router.load()
await waitFor(() => {
- expect(loadSpy).toHaveBeenCalledTimes(0)
+ expect(loadSpy).toHaveBeenCalledTimes(2)
+ expect(loader).toHaveBeenCalledTimes(1)
})
loadSpy.mockRestore()
diff --git a/packages/solid-router/tests/server/Transitioner.test.tsx b/packages/solid-router/tests/server/Transitioner.test.tsx
new file mode 100644
index 0000000000..7afdd57058
--- /dev/null
+++ b/packages/solid-router/tests/server/Transitioner.test.tsx
@@ -0,0 +1,43 @@
+import { describe, expect, it, vi } from 'vitest'
+import { renderToStringAsync } from 'solid-js/web'
+import {
+ createMemoryHistory,
+ createRootRoute,
+ createRoute,
+ createRouter,
+} from '../../src'
+import { RouterProvider } from '../../src/RouterProvider'
+
+describe('Transitioner (server)', () => {
+ it('should call router.load() only once when on the server', async () => {
+ const loader = vi.fn()
+ const rootRoute = createRootRoute()
+ const indexRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/',
+ component: () => Index
,
+ loader,
+ })
+
+ const routeTree = rootRoute.addChildren([indexRoute])
+ const router = createRouter({
+ routeTree,
+ history: createMemoryHistory({
+ initialEntries: ['/'],
+ }),
+ isServer: true,
+ })
+
+ // Mock router.load() to verify it gets called
+ const loadSpy = vi.spyOn(router, 'load')
+
+ await router.load()
+
+ await renderToStringAsync(() => )
+
+ expect(loadSpy).toHaveBeenCalledTimes(1)
+ expect(loader).toHaveBeenCalledTimes(1)
+
+ loadSpy.mockRestore()
+ })
+})
diff --git a/packages/solid-router/vite.config.ts b/packages/solid-router/vite.config.ts
index 725568f1c9..0d90e89b74 100644
--- a/packages/solid-router/vite.config.ts
+++ b/packages/solid-router/vite.config.ts
@@ -4,22 +4,40 @@ import solid from 'vite-plugin-solid'
import packageJson from './package.json'
import type { ViteUserConfig } from 'vitest/config'
-const config = defineConfig({
- plugins: [solid()] as ViteUserConfig['plugins'],
- test: {
- name: packageJson.name,
- dir: './tests',
- watch: false,
- environment: 'jsdom',
- typecheck: { enabled: true },
- setupFiles: ['./tests/setupTests.tsx'],
- },
+const config = defineConfig(({ mode }) => {
+ if (mode === 'server') {
+ return {
+ plugins: [solid({ ssr: true })] as ViteUserConfig['plugins'],
+ test: {
+ name: `${packageJson.name} (server)`,
+ dir: './tests/server',
+ watch: false,
+ environment: 'node',
+ typecheck: { enabled: true },
+ },
+ }
+ }
+
+ return {
+ plugins: [solid()] as ViteUserConfig['plugins'],
+ test: {
+ name: packageJson.name,
+ dir: './tests',
+ exclude: ['server'],
+ watch: false,
+ environment: 'jsdom',
+ typecheck: { enabled: true },
+ setupFiles: ['./tests/setupTests.tsx'],
+ },
+ }
})
-export default mergeConfig(
- config,
- tanstackViteConfig({
- entry: ['./src/index.tsx', './src/ssr/client.ts', './src/ssr/server.ts'],
- srcDir: './src',
- }),
+export default defineConfig((env) =>
+ mergeConfig(
+ config(env),
+ tanstackViteConfig({
+ entry: ['./src/index.tsx', './src/ssr/client.ts', './src/ssr/server.ts'],
+ srcDir: './src',
+ }),
+ ),
)