← Cloudflare Workers / workers / framework-guides / web-apps
TanStack Start
TanStack Start ↗ представляет собой full-stack фреймворк для создания веб-приложений с серверным рендерингом, потоковой передачей данных, серверными функциями и сборкой (bundling).
Создайте новое приложение
Создайте приложение TanStack Start, предварительно настроенное для Cloudflare Workers:
npm create cloudflare@latest -- my-tanstack-start-app --framework=tanstack-startЗапустите локальный сервер разработки, чтобы просматривать проект в процессе разработки:
npm run devНастройка существующего приложения
Если у вас уже есть приложение TanStack Start, настройте его для запуска на Cloudflare Workers:
-
Установка
@cloudflare/vite-pluginиwrangler:npm i @cloudflare/vite-plugin wrangler -- -D -
Добавьте плагин Cloudflare в конфигурацию Vite:
vite.config.jsimport { defineConfig } from "vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import { cloudflare } from "@cloudflare/vite-plugin"; import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [ cloudflare({ viteEnvironment: { name: "ssr" } }), tanstackStart(), react(), ], });vite.config.tsimport { defineConfig } from "vite"; import { tanstackStart } from "@tanstack/react-start/plugin/vite"; import { cloudflare } from "@cloudflare/vite-plugin"; import react from "@vitejs/plugin-react"; export default defineConfig({ plugins: [ cloudflare({ viteEnvironment: { name: "ssr" } }), tanstackStart(), react(), ], }); -
Добавьте
wrangler.jsoncфайл конфигурации:{ "$schema": "node_modules/wrangler/config-schema.json", "name": "<YOUR_PROJECT_NAME>", // Set this to today's date "compatibility_date": "2026-08-28", "compatibility_flags": ["nodejs_compat"], "main": "@tanstack/react-start/server-entry", "observability": { "enabled": true, }, }"$schema" = "node_modules/wrangler/config-schema.json" name = "<YOUR_PROJECT_NAME>" # Set this to today's date compatibility_date = "2026-08-28" compatibility_flags = [ "nodejs_compat" ] main = "@tanstack/react-start/server-entry" [observability] enabled = true -
Обновите
scriptsраздел вpackage.json:package.json{ "scripts": { "dev": "vite dev", "build": "vite build", "preview": "vite preview", "deploy": "npm run build && wrangler deploy", "cf-typegen": "wrangler types" } }
Развернуть
Развертывание в *.workers.dev поддомен или пользовательский домен с вашего компьютера или из любой системы CI/CD, включая Workers Builds.
npm run deployПользовательские точки входа
TanStack Start использует @tanstack/react-start/server-entry в качестве точки входа по умолчанию. Создайте собственную точку входа сервера, чтобы добавить дополнительные обработчики Workers, такие как Queues и Cron Triggers. Здесь же можно добавить дополнительные экспортируемые объекты, например Durable Objects и Workflows.
-
Создайте пользовательский файл точки входа сервера:
src/server.jsimport handler from "@tanstack/react-start/server-entry"; // Export Durable Objects as named exports export { MyDurableObject } from "./my-durable-object"; export default { fetch: handler.fetch, // Handle Queue messages async queue(batch, env, ctx) { for (const message of batch.messages) { console.log("Processing message:", message.body); message.ack(); } }, // Handle Cron Triggers async scheduled(event, env, ctx) { console.log("Cron triggered:", event.cron); }, };src/server.tsimport handler from "@tanstack/react-start/server-entry"; // Export Durable Objects as named exports export { MyDurableObject } from "./my-durable-object"; export default { fetch: handler.fetch, // Handle Queue messages async queue(batch, env, ctx) { for (const message of batch.messages) { console.log("Processing message:", message.body); message.ack(); } }, // Handle Cron Triggers async scheduled(event, env, ctx) { console.log("Cron triggered:", event.cron); }, }; -
Обновите конфигурацию Wrangler, чтобы она указывала на вашу пользовательскую точку входа:
{ "main": "src/server.ts", }main = "src/server.ts"
Локальное тестирование запланированных обработчиков
Протестируйте запланированный обработчик локально с помощью /cdn-cgi/handler/scheduled конечная точка:
curl "http://localhost:3000/cdn-cgi/handler/scheduled?cron=*+*+*+*+*"Пример: использование Workflows
Экспортируйте класс Workflow из вашей пользовательской точки входа, чтобы выполнять устойчивые многоэтапные задачи:
import {
WorkflowEntrypoint,
WorkflowStep,
WorkflowEvent,
} from "cloudflare:workers";
export class MyWorkflow extends WorkflowEntrypoint {
async run(event, step) {
const result = await step.do("process data", async () => {
return `Processed: ${event.payload.input}`;
});
await step.sleep("wait", "10 seconds");
await step.do("finalize", async () => {
console.log("Workflow complete:", result);
});
}
}import {
WorkflowEntrypoint,
WorkflowStep,
WorkflowEvent,
} from "cloudflare:workers";
export class MyWorkflow extends WorkflowEntrypoint<Env> {
async run(event: WorkflowEvent<{ input: string }>, step: WorkflowStep) {
const result = await step.do("process data", async () => {
return `Processed: ${event.payload.input}`;
});
await step.sleep("wait", "10 seconds");
await step.do("finalize", async () => {
console.log("Workflow complete:", result);
});
}
}Добавьте конфигурацию Workflow в конфигурацию Wrangler:
{
"workflows": [
{
"name": "my-workflow",
"binding": "MY_WORKFLOW",
"class_name": "MyWorkflow",
},
],
}[[workflows]]
name = "my-workflow"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"Пример: использование Service Bindings
Добавьте service binding, чтобы вызывать RPC-методы другого Worker из приложения TanStack Start:
{
"services": [
{
"binding": "AUTH_SERVICE",
"service": "auth-worker",
},
],
}[[services]]
binding = "AUTH_SERVICE"
service = "auth-worker"Вызывайте методы привязанного Worker из серверной функции:
import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
const verifyUser = createServerFn()
.inputValidator((token) => token)
.handler(async ({ data: token }) => {
const result = await env.AUTH_SERVICE.verify(token);
return result;
});import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
const verifyUser = createServerFn()
.inputValidator((token: string) => token)
.handler(async ({ data: token }) => {
const result = await env.AUTH_SERVICE.verify(token);
return result;
});Bindings
Ваше приложение на TanStack Start можно полностью интегрировать с Cloudflare Developer Platform как в локальной разработке, так и в продакшене, с помощью привязки.
Доступ к привязкам по импорт env объект в коде на стороне сервера:
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
export const Route = createFileRoute("/")({
loader: () => getData(),
component: RouteComponent,
});
const getData = createServerFn().handler(() => {
// Access bindings via env
// For example: env.MY_KV, env.MY_BUCKET, env.AI, etc.
});
function RouteComponent() {
// ...
}import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
export const Route = createFileRoute("/")({
loader: () => getData(),
component: RouteComponent,
});
const getData = createServerFn().handler(() => {
// Access bindings via env
// For example: env.MY_KV, env.MY_BUCKET, env.AI, etc.
});
function RouteComponent() {
// ...
}Сгенерируйте типы TypeScript для ваших привязок на основе конфигурации Wrangler:
npm run cf-typegenБлагодаря bindings ваше приложение можно полностью интегрировать с Cloudflare Developer Platform, получив доступ к вычислениям, хранилищу, AI и другим возможностям.
Используйте R2 в серверной функции
Добавьте Привязка бакета R2 в конфигурацию Wrangler:
{
"r2_buckets": [
{
"binding": "MY_BUCKET",
"bucket_name": "<YOUR_BUCKET_NAME>",
},
],
}[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<YOUR_BUCKET_NAME>"Доступ к бакету в серверной функции:
import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
const uploadFile = createServerFn({ method: "POST" })
.validator((data) => data)
.handler(async ({ data }) => {
await env.MY_BUCKET.put(data.key, data.content);
return { success: true };
});
const getFile = createServerFn()
.validator((key) => key)
.handler(async ({ data: key }) => {
const object = await env.MY_BUCKET.get(key);
return object ? await object.text() : null;
});import { createServerFn } from "@tanstack/react-start";
import { env } from "cloudflare:workers";
const uploadFile = createServerFn({ method: "POST" })
.validator((data: { key: string; content: string }) => data)
.handler(async ({ data }) => {
await env.MY_BUCKET.put(data.key, data.content);
return { success: true };
});
const getFile = createServerFn()
.validator((key: string) => key)
.handler(async ({ data: key }) => {
const object = await env.MY_BUCKET.get(key);
return object ? await object.text() : null;
});Статический предрендеринг
Пререндерите приложение в статический HTML на этапе сборки и раздавайте его как статические ресурсы.
import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
cloudflare({ viteEnvironment: { name: "ssr" } }),
tanstackStart({
prerender: {
enabled: true,
},
}),
react(),
],
});import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
cloudflare({ viteEnvironment: { name: "ssr" } }),
tanstackStart({
prerender: {
enabled: true,
},
}),
react(),
],
});Подробнее о дополнительных параметрах см. в Статический предрендеринг в TanStack Start ↗.
Источники данных для пререндеринга
Чтобы выполнить пререндеринг с использованием рабочих данных, используйте удаленные привязки.
В средах CI переменные окружения и секреты могут быть недоступны во время сборки. Чтобы сделать их доступными:
- Задайте
CLOUDFLARE_INCLUDE_PROCESS_ENV=trueв вашей среде CI и указать необходимые значения в виде переменных окружения. - При использовании Workers Builds, обновите настройки сборки.