TanStack Startとは
TanStack Startは、TanStack RouterをベースにしたフルスタックReactフレームワークです。型安全なルーティング、サーバー関数、SSR/SSGを統合し、Next.jsの代替として注目されています。
特徴
✓ 完全な型安全性
✓ ファイルベースルーティング
✓ サーバー関数
✓ ストリーミングSSR
✓ 複数のデプロイターゲット
✓ TanStack Query統合
プロジェクトのセットアップ
npm create tanstack-start@latest my-app
cd my-app
npm install
npm run dev
ファイルベースルーティング
app/
├── routes/
│ ├── __root.tsx # ルートレイアウト
│ ├── index.tsx # /
│ ├── about.tsx # /about
│ ├── posts/
│ │ ├── index.tsx # /posts
│ │ ├── $postId.tsx # /posts/:postId
│ │ └── new.tsx # /posts/new
│ └── _auth/ # レイアウトグループ
│ ├── login.tsx
│ └── register.tsx
└── routes.gen.ts # 自動生成
ルート定義
基本的なルート
// routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/')({
component: HomePage
});
function HomePage() {
return <h1>Welcome to TanStack Start!</h1>;
}
動的ルート
// routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params }) => {
// params.postId は型安全
const post = await fetchPost(params.postId);
return { post };
},
component: PostPage
});
function PostPage() {
const { post } = Route.useLoaderData();
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}
サーバー関数
定義と使用
// app/serverFunctions/posts.ts
import { createServerFn } from '@tanstack/start';
import { z } from 'zod';
export const getPosts = createServerFn('GET', async () => {
return db.posts.findMany();
});
export const createPost = createServerFn('POST', async (data) => {
const validated = z.object({
title: z.string(),
content: z.string()
}).parse(data);
return db.posts.create({ data: validated });
});
クライアントからの呼び出し
// routes/posts/index.tsx
import { getPosts, createPost } from '../serverFunctions/posts';
export const Route = createFileRoute('/posts/')({
loader: () => getPosts(),
component: PostsPage
});
function PostsPage() {
const posts = Route.useLoaderData();
const handleCreate = async () => {
await createPost({ title: 'New Post', content: 'Content' });
};
return (
<div>
{posts.map(post => <PostCard key={post.id} post={post} />)}
<button onClick={handleCreate}>Create Post</button>
</div>
);
}
データフェッチング
Loaderパターン
export const Route = createFileRoute('/dashboard')({
// サーバーサイドでデータを取得
loader: async ({ context }) => {
const [user, stats] = await Promise.all([
getUser(context.userId),
getStats(context.userId)
]);
return { user, stats };
},
// ペンディング状態の表示
pendingComponent: () => <div>Loading...</div>,
// エラー状態の表示
errorComponent: ({ error }) => <div>Error: {error.message}</div>,
component: DashboardPage
});
TanStack Queryとの統合
import { createFileRoute } from '@tanstack/react-router';
import { useSuspenseQuery } from '@tanstack/react-query';
export const Route = createFileRoute('/posts/')({
component: PostsPage
});
function PostsPage() {
const { data: posts } = useSuspenseQuery({
queryKey: ['posts'],
queryFn: () => fetch('/api/posts').then(r => r.json())
});
return <PostList posts={posts} />;
}
レイアウト
// routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router';
export const Route = createRootRoute({
component: RootLayout
});
function RootLayout() {
return (
<html>
<head>
<meta charSet="utf-8" />
<title>My App</title>
</head>
<body>
<nav>
<Link to="/">Home</Link>
<Link to="/posts">Posts</Link>
</nav>
<main>
<Outlet />
</main>
</body>
</html>
);
}
型安全なリンク
import { Link } from '@tanstack/react-router';
// 型エラー: パラメータが不足
<Link to="/posts/$postId">Post</Link>
// 正しい使い方
<Link to="/posts/$postId" params={{ postId: '123' }}>
Post 123
</Link>
// 検索パラメータも型安全
<Link to="/search" search={{ q: 'react', page: 1 }}>
Search
</Link>
ミドルウェア
// app/middleware.ts
import { createMiddleware } from '@tanstack/start';
export const authMiddleware = createMiddleware({
beforeLoad: async ({ context }) => {
const session = await getSession();
if (!session) {
throw redirect({ to: '/login' });
}
return { ...context, session };
}
});
// ルートで使用
export const Route = createFileRoute('/dashboard')({
middleware: [authMiddleware],
component: Dashboard
});
デプロイ
# Node.js
npm run build
npm start
# Cloudflare Workers
npm run build --preset cloudflare-pages
# Vercel
npm run build --preset vercel
# Netlify
npm run build --preset netlify
まとめ
TanStack Startは、完全な型安全性とモダンなサーバー機能を備えたフルスタックReactフレームワークです。TanStack Routerの強力なルーティングシステムと、シンプルなサーバー関数により、効率的なフルスタック開発が可能です。
← 一覧に戻る