Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

TanStack Start

最終更新 Markdown で表示Agent セットアップ

TanStack Start は、サーバーサイドレンダリング、ストリーミング、サーバー関数、バンドルを備えた、Web アプリケーション向けのフルスタックフレームワークです。

TanStack Start検出済み
生成された設定
wrangler.jsonc
main:.output/server/index.mjs
wrangler.jsonc
assets:directory: .output/public
wrangler.jsonc
compatibility_flags:nodejs_compat
wrangler.jsonc
observability:enabled: true
Workersデプロイ済み
Wrangler が設定を自動で処理します

新しいアプリケーションを作成する

Cloudflare Workers 向けに事前設定された TanStack Start アプリケーションを作成します。

npm create cloudflare@latest -- my-tanstack-start-app --framework=tanstack-start

開発中にプロジェクトをプレビューするローカル開発サーバーを起動します。

npm run dev

既存のアプリケーションを設定する

既存の TanStack Start アプリケーションがある場合は、Cloudflare Workers で動くように設定します。

  1. @cloudflare/vite-pluginwrangler をインストールします。

    npm i @cloudflare/vite-plugin wrangler -- -D
  2. Vite 設定に Cloudflare プラグインを追加します。

    vite.config.jsjs
    import { 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.tsts
    import { 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(),
    	],
    });
  3. wrangler.jsonc 設定ファイルを追加します。

    {
    	"$schema": "node_modules/wrangler/config-schema.json",
    	"name": "<YOUR_PROJECT_NAME>",
    	// Set this to today's date
    	"compatibility_date": "2026-09-20",
    	"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-09-20"
    compatibility_flags = [ "nodejs_compat" ]
    main = "@tanstack/react-start/server-entry"
    
    [observability]
    enabled = true
  4. package.jsonscripts セクションを更新します。

    package.jsonjson
    {
    	"scripts": {
    		"dev": "vite dev",
    		"build": "vite build",
    		"preview": "vite preview",
    		"deploy": "npm run build && wrangler deploy",
    		"cf-typegen": "wrangler types"
    	}
    }

デプロイする

自分のマシン、または Workers Builds を含む任意の CI/CD システムから、*.workers.dev サブドメインまたは カスタムドメイン にデプロイします。

npm run deploy

カスタムエントリポイント

TanStack Start のデフォルトエントリポイントは @tanstack/react-start/server-entry です。カスタムのサーバーエントリポイントを作成すると、QueuesCron Triggers などの追加の Workers ハンドラーを足せます。Durable ObjectsWorkflows などの追加のエクスポートも、ここで足せます。

  1. カスタムのサーバーエントリポイントファイルを作成します。

    src/server.jsjs
    import 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.tsts
    import 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);
    	},
    };
  2. Wrangler 設定を、カスタムエントリポイントを指すように更新します。

    {
    	"main": "src/server.ts",
    }
    main = "src/server.ts"

スケジュールハンドラーをローカルでテストする

/cdn-cgi/local/scheduled エンドポイントを使い、スケジュールハンドラーをローカルでテストします。

curl "http://localhost:3000/cdn-cgi/local/scheduled?cron=*+*+*+*+*"

例: Workflows を使う

耐久性のある複数ステップのタスクを実行するには、カスタムエントリポイントから Workflow クラスをエクスポートします。

app/server.jsjs
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);
		});
	}
}
app/server.tsts
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);
		});
	}
}

Wrangler 設定に Workflow の設定を追加します。

{
	"workflows": [
		{
			"name": "my-workflow",
			"binding": "MY_WORKFLOW",
			"class_name": "MyWorkflow",
		},
	],
}
[[workflows]]
name = "my-workflow"
binding = "MY_WORKFLOW"
class_name = "MyWorkflow"

例: サービスバインディングを使う

TanStack Start アプリケーションから別の Worker の RPC メソッドを呼ぶには、サービスバインディングを追加します。

{
	"services": [
		{
			"binding": "AUTH_SERVICE",
			"service": "auth-worker",
		},
	],
}
[[services]]
binding = "AUTH_SERVICE"
service = "auth-worker"

サーバー関数から、バインドした Worker のメソッドを呼び出します。

app/routes/index.jsxjs
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;
	});
app/routes/index.tsxts
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;
	});

バインディング

TanStack Start アプリケーションは、バインディング を使うと、ローカル開発でも本番でも Cloudflare Developer Platform と完全に統合できます。

サーバーサイドのコードでは、env オブジェクトをインポート してバインディングにアクセスします。

app/routes/index.jsxjs
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() {
	// ...
}
app/routes/index.tsxts
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() {
	// ...
}

Wrangler 設定に基づいて、バインディングの TypeScript 型を生成します。

npm run cf-typegen

バインディングを使うと、アプリケーションを Cloudflare Developer Platform と完全に統合でき、コンピュート、ストレージ、AI などへアクセスできます。

サーバー関数で R2 を使う

Wrangler 設定に R2 バケットバインディング を追加します。

{
	"r2_buckets": [
		{
			"binding": "MY_BUCKET",
			"bucket_name": "<YOUR_BUCKET_NAME>",
		},
	],
}
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<YOUR_BUCKET_NAME>"

サーバー関数からバケットにアクセスします。

app/routes/index.jsxjs
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;
	});
app/routes/index.tsxts
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 へプリレンダリングし、静的アセット として配信します。

vite.config.jsjs
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(),
	],
});
vite.config.tsts
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 環境では、ビルド中に環境変数やシークレットが使えないことがあります。使えるようにするには、次のいずれかを行います。

  • CI 環境で CLOUDFLARE_INCLUDE_PROCESS_ENV=true を設定し、必要な値を環境変数として渡します。
  • Workers Builds を使っている場合は、ビルド設定 を更新します。

役に立ちましたか?