一键导入
tanstack-start-client-only
Configure TanStack Start in client-only mode (defaultSsr=false) for SPA-like behavior without server-side rendering.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Configure TanStack Start in client-only mode (defaultSsr=false) for SPA-like behavior without server-side rendering.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Master multi-agent orchestration using Claude Code's TeammateTool and Task system. Use when coordinating multiple agents, running parallel code reviews, creating pipeline workflows with dependencies, building self-organizing task queues, or any task benefiting from divide-and-conquer patterns.
API client setup with fetch wrapper, error handling, authentication headers, and React Query integration for TanStack Start/Router.
Token-based authentication for TanStack Client (SPA) apps including login/logout, protected routes, auth context, token storage, and route guards. SHARED skill for both TanStack Start (client-only mode) and TanStack Router.
Mutation patterns with useMutation, optimistic updates, cache invalidation, and rollback strategies. SHARED skill for both TanStack Start (SSR) and TanStack Router (SPA).
Query patterns with queryOptions factory, key conventions, prefetching strategies, and type-safe reusable query definitions. SHARED skill for both TanStack Start (SSR) and TanStack Router (SPA).
Configure TanStack Query (React Query) with QueryClient, provider, devtools, and optimal defaults. SHARED skill for both TanStack Start (SSR) and TanStack Router (SPA).
| name | tanstack-start-client-only |
| description | Configure TanStack Start in client-only mode (defaultSsr=false) for SPA-like behavior without server-side rendering. |
This skill covers configuring TanStack Start to run in client-only mode by disabling server-side rendering (SSR). This is useful when you want SPA-like behavior or when your application doesn't benefit from SSR.
Use client-only mode when:
Modify your src/router.tsx to disable SSR:
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export const router = createRouter({
routeTree,
defaultSsr: false, // Disable server-side rendering globally
})
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
You can also control SSR on a per-route basis by setting ssr: false in individual route definitions:
// src/routes/dashboard.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/dashboard')({
// Disable SSR for this specific route
ssr: false,
component: DashboardComponent,
})
function DashboardComponent() {
return <div>Dashboard (Client-Only)</div>
}
Ensure your src/routes/__root.tsx is properly configured for client-only rendering:
import { createRootRoute, Outlet } from '@tanstack/react-router'
export const Route = createRootRoute({
component: () => (
<html>
<head>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TanStack Start App (Client-Only)</title>
</head>
<body>
<div id="root">
<Outlet />
</div>
</body>
</html>
),
})
In client-only mode, you can safely use browser APIs without checking for SSR:
import { createFileRoute } from '@tanstack/react-router'
import { useEffect, useState } from 'react'
export const Route = createFileRoute('/example')({
component: ExampleComponent,
})
function ExampleComponent() {
const [data, setData] = useState(null)
useEffect(() => {
// Browser APIs work directly since there's no SSR
const stored = localStorage.getItem('data')
if (stored) {
setData(JSON.parse(stored))
}
// Window object is available
console.log('Window size:', window.innerWidth, window.innerHeight)
}, [])
return <div>Example Component</div>
}
For pure client-only builds, you can simplify your vite.config.ts:
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
server: {
port: 3000,
},
plugins: [
tsconfigPaths(),
tanstackStart({
// Client-only mode configuration
ssr: false, // Disable SSR at build level
}),
viteReact(),
],
})
Create .env for client-side environment variables:
# .env
VITE_API_BASE_URL=http://localhost:8000/api/v1
VITE_APP_NAME=My TanStack App
Access them in your components:
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL
const appName = import.meta.env.VITE_APP_NAME
Note: In client-only mode, all VITE_* variables are exposed to the client bundle. Never store secrets here.
Build your client-only application:
bun run build
This creates a static bundle in .output/ that can be deployed to:
| Feature | SSR (default) | Client-Only (defaultSsr=false) |
|---|---|---|
| Initial page load | Fully rendered HTML | Empty HTML shell |
| SEO | Excellent | Limited (depends on crawlers) |
| Time to First Byte (TTFB) | Slower (server processing) | Fast (static HTML) |
| JavaScript bundle | Hydration required | Direct execution |
| Server-side APIs | Available via server functions | Must use external API |
| Browser APIs | Require checks | Always available |
| Deployment | Node.js server required | Static hosting works |
Use client-only for authenticated apps: Dashboards, admin panels, and internal tools benefit from simpler client-only architecture.
Combine both modes: Use SSR for marketing pages (/, /pricing, /blog) and client-only for app routes (/dashboard/*, /settings/*):
// src/routes/__root.tsx
export const Route = createRootRoute({
component: RootComponent,
})
// src/routes/index.tsx (SSR - default)
export const Route = createFileRoute('/')({
component: HomePage,
})
// src/routes/dashboard.tsx (Client-only)
export const Route = createFileRoute('/dashboard')({
ssr: false, // Disable SSR for dashboard
component: Dashboard,
})
import { lazy } from 'react'
const HeavyComponent = lazy(() => import('./HeavyComponent'))
function Dashboard() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
</div>
)
}
// src/routes/__root.tsx
export const Route = createRootRoute({
component: () => (
<html>
<head>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TanStack Start App</title>
<style>{`
.app-loading {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
font-family: system-ui;
}
`}</style>
</head>
<body>
<div id="root">
<div className="app-loading">Loading application...</div>
<Outlet />
</div>
</body>
</html>
),
})
After configuring client-only mode:
bun run dev
Cause: Accidentally running SSR code when defaultSsr: false isn't set.
Solution: Ensure defaultSsr: false in router configuration:
export const router = createRouter({
routeTree,
defaultSsr: false,
})
Cause: JavaScript bundle failed to load or execute.
Solution: Check browser console for errors and verify bundle path in network tab.
Cause: Mixing SSR and client-only rendering.
Solution: Be consistent - either use defaultSsr: false globally or manage per-route carefully.
After configuring client-only mode:
tanstack-react-query-setup skill)tanstack-client-auth skill)tanstack-client-api-layer skill)tanstack-shadcn-setup skill)