tanstack-start-cursorrules-prompt-file — правило Cursor
Правило задаёт Cursor ориентиры для разработки на TanStack Start: от серверных функций и маршрутов до потоковой загрузки и SSR.
.cursor/rules/tanstack-start-cursorrules-prompt-file.mdcЧто делает tanstack-start-cursorrules-prompt-file
Правило направляет Cursor при работе с приложениями на TanStack Start, TanStack Router и React. Оно описывает файловую маршрутизацию, серверные функции createServerFn с проверкой входных данных через Zod, загрузчики маршрутов и мутации через TanStack Query. Для обычной серверной логики правило рекомендует серверные функции, а API-маршруты оставляет для HTTP-точек вроде вебхуков.
В рекомендациях также есть потоковая передача данных через defer() и <Suspense>, проверка доступа через beforeLoad и чтение cookies и заголовков в серверном контексте. Настройка целевого окружения описана через server.preset в app.config.ts; среди вариантов перечислены Node.js, Vercel, Netlify, Bun и Cloudflare Pages. Переменные process.env нельзя использовать в клиентских компонентах, поэтому эту границу стоит учитывать при генерации кода.
Для установки в Cursor поместите файл в .cursor/rules/tanstack-start-cursorrules-prompt-file.mdc. Правило предназначено для всех файлов проекта (**/*), но alwaysApply выключен: оно не включается безусловно.
Какие задачи решает
- организовать файловые маршруты TanStack Start
- создать типизированную серверную функцию с проверкой Zod
- загрузить данные маршрута и обработать мутацию через TanStack Query
- передать некритичные данные через
defer()и<Suspense> - настроить проверку доступа и серверное чтение cookies
Примеры запросов агенту
- Создай серверную функцию для получения поста по идентификатору и проверь входные данные через Zod.
- Добавь маршрут
/posts/$postId, который загружает пост через серверную функцию. - Настрой потоковую загрузку комментариев через
defer()и<Suspense>.
Как установить tanstack-start-cursorrules-prompt-file
Вручную: положить файлы
.cursor/rules/tanstack-start-cursorrules-prompt-file.mdcВо frontmatter: description, globs, alwaysApply
Вручную: положить файлы
.claude/rules/tanstack-start-cursorrules-prompt-file.mdПоле paths во frontmatter ограничивает файлы: globs из источника → paths
AGENTS.md
Codex читает AGENTS.md: вставьте текст правила туда
Вручную: положить файлы
.github/instructions/tanstack-start-cursorrules-prompt-file.instructions.mdПоле applyTo задаёт, к каким файлам применять: globs из источника → applyTo
Вручную: положить файлы
.devin/rules/tanstack-start-cursorrules-prompt-file.mdВручную: положить файлы
.clinerules/tanstack-start-cursorrules-prompt-file.mdПо шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules
Вопросы о tanstack-start-cursorrules-prompt-file
Как установить tanstack-start-cursorrules-prompt-file в Cursor?
Сохраните файл правила по пути .cursor/rules/tanstack-start-cursorrules-prompt-file.mdc в проекте.
Что делает tanstack-start-cursorrules-prompt-file?
Правило подсказывает Cursor, как строить приложения на TanStack Start: использовать серверные функции, файловые маршруты, SSR и потоковую передачу данных.
Как правило советует разделять серверные функции и API-маршруты?
Для основной серверной логики оно рекомендует createServerFn. createAPIFileRoute предлагается для сырых HTTP-точек, например вебхуков и интеграций со сторонними сервисами.
Исходный текст
tanstack-start-cursorrules-prompt-file.mdc · CC0-1.0
---
description: "Cursor rules for TanStack Start full-stack React framework including server functions, API routes, streaming with defer(), SSR, and multi-platform deployment."
globs: **/*
alwaysApply: false
---
You are an expert in TanStack Start, TanStack Router, React, TypeScript, Vinxi, and full-stack type-safe web applications.
# TanStack Start Guidelines
## What is TanStack Start
TanStack Start is a full-stack React framework built on top of TanStack Router and Vinxi (Vite + Nitro). It provides SSR, streaming, server functions, and API routes with end-to-end type safety.
## Core Principles
- TanStack Start is file-based routing via TanStack Router — all routing conventions apply
- Server Functions (`createServerFn`) are the primary way to run server-side logic
- Full-stack type safety: server function inputs/outputs are typed end-to-end
- Streaming and Suspense are first-class — use them for progressive rendering
- Start is NOT an API-first framework — server functions replace REST endpoints for most use cases
## Project Structure
```
src/
routes/
__root.tsx ← Root layout with HTML shell
index.tsx ← Home route
posts/
index.tsx
$postId.tsx
server/
functions/ ← Server functions (recommended organization)
posts.ts
auth.ts
lib/
db.ts ← Database client
auth.ts ← Auth utilities
app.config.ts ← TanStack Start / Vinxi config
```
## app.config.ts
```ts
import { defineConfig } from '@tanstack/start/config'
import tsConfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
vite: {
plugins: [tsConfigPaths()],
},
server: {
preset: 'node-server', // or 'vercel', 'netlify', 'bun', 'cloudflare-pages'
},
})
```
## Root Route Setup
```tsx
// src/routes/__root.tsx
import { createRootRoute, ScrollRestoration, Scripts, Outlet } from '@tanstack/react-router'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
export const Route = createRootRoute({
component: RootComponent,
})
function RootComponent() {
return (
<html lang="en">
<head />
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === 'development' && (
<>
<TanStackRouterDevtools />
<ReactQueryDevtools />
</>
)}
</body>
</html>
)
}
```
## Server Functions
- Use `createServerFn` to define functions that always run on the server
- Validate inputs with Zod using `.validator()`
- Use `.handler()` for the implementation
- Server functions are called like regular async functions from components or loaders
```ts
// src/server/functions/posts.ts
import { createServerFn } from '@tanstack/start'
import { z } from 'zod'
export const getPost = createServerFn()
.validator(z.object({ id: z.string() }))
.handler(async ({ data }) => {
const post = await db.post.findUnique({ where: { id: data.id } })
if (!post) throw new Error('Post not found')
return post
})
export const createPost = createServerFn()
.validator(z.object({ title: z.string().min(1), body: z.string() }))
.handler(async ({ data, context }) => {
// context has access to request headers, cookies, etc.
return db.post.create({ data })
})
```
## Using Server Functions in Routes
```tsx
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router'
import { getPost } from '../../server/functions/posts'
export const Route = createFileRoute('/posts/$postId')({
loader: ({ params }) => getPost({ data: { id: params.postId } }),
component: PostDetail,
})
function PostDetail() {
const post = Route.useLoaderData()
return <article><h1>{post.title}</h1></article>
}
```
## Mutations with Server Functions
- Call server functions directly in event handlers or via TanStack Query mutations
```tsx
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { createPost } from '../../server/functions/posts'
function CreatePostForm() {
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: (input: { title: string; body: string }) =>
createPost({ data: input }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['posts'] })
},
})
return (
<form onSubmit={(e) => {
e.preventDefault()
const fd = new FormData(e.currentTarget)
mutation.mutate({ title: fd.get('title') as string, body: fd.get('body') as string })
}}>
<input name="title" />
<textarea name="body" />
<button type="submit" disabled={mutation.isPending}>
{mutation.isPending ? 'Creating...' : 'Create'}
</button>
</form>
)
}
```
## API Routes
- Use `createAPIFileRoute` for raw HTTP endpoints (webhooks, third-party integrations)
- Place in `src/routes/api/` directory
```ts
// src/routes/api/webhook.ts
import { createAPIFileRoute } from '@tanstack/start/api'
export const Route = createAPIFileRoute('/api/webhook')({
POST: async ({ request }) => {
const body = await request.json()
// handle webhook
return Response.json({ received: true })
},
})
```
## Streaming & Suspense
- Use `defer()` to stream non-critical data after the initial render
- Wrap deferred data consumers in `<Suspense>`
```tsx
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
const post = await getPost({ data: { id: params.postId } }) // awaited (critical)
const comments = getComments({ data: { postId: params.postId } }) // not awaited (deferred)
return { post, comments: defer(comments) }
},
component: PostDetail,
})
function PostDetail() {
const { post, comments } = Route.useLoaderData()
return (
<div>
<h1>{post.title}</h1>
<Suspense fallback={<CommentsSkeleton />}>
<Await promise={comments}>
{(resolved) => <CommentsList comments={resolved} />}
</Await>
</Suspense>
</div>
)
}
```
## Authentication
- Read cookies/headers in server functions using TanStack Start's server context
- Use `beforeLoad` in routes for auth guards
```ts
import { getWebRequest } from '@tanstack/start/server'
export const getSession = createServerFn().handler(async () => {
const request = getWebRequest()
const sessionToken = getCookie(request, 'session')
return validateSession(sessionToken)
})
```
## Deployment Targets
- `node-server` — default Node.js server
- `vercel` — Vercel serverless/edge
- `netlify` — Netlify Functions
- `bun` — Bun runtime
- `cloudflare-pages` — Cloudflare Pages + Workers
- Configure in `app.config.ts` under `server.preset`
## Environment Variables
- Access server-only vars directly from `process.env` inside server functions
- Use Vite's `import.meta.env` for client-exposed variables (prefix with `VITE_`)
- Never access `process.env` in client components
## TanStack Query Integration
- Provide `QueryClient` via router context for loader-level prefetching
- Use `ensureQueryData` in loaders to populate cache before render
- This eliminates loading states for route-level data fetching
© PatrickJS · CC0-1.0 · PatrickJS/awesome-cursorrules