Skip to content

Commit 041bd05

Browse files
matthew-sessionskodster28
authored andcommitted
Update tanstack.mdx (cloudflare#23026)
* Update tanstack.mdx * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> * Update src/content/docs/workers/framework-guides/web-apps/tanstack.mdx Co-authored-by: Kody Jackson <[email protected]> --------- Co-authored-by: Kody Jackson <[email protected]>
1 parent 0a220e4 commit 041bd05

File tree

1 file changed

+120
-70
lines changed
  • src/content/docs/workers/framework-guides/web-apps

1 file changed

+120
-70
lines changed

src/content/docs/workers/framework-guides/web-apps/tanstack.mdx

Lines changed: 120 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ sidebar:
55
order: 7
66
head: []
77
tags: ["full-stack"]
8-
description: Create a TanStack Router application and deploy it to Cloudflare Workers with Workers Assets.
8+
description: Create a TanStack Start application and deploy it to Cloudflare Workers with Workers Assets.
99
---
1010

1111
import { WranglerConfig, Steps, PackageManagers, Details } from "~/components";
1212

1313
## What is TanStack Start?
1414

15-
TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using tools like Nitro and Vite.
15+
TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using Vite and modern web standards.
1616

1717
## Create a new TanStack Start
1818

19-
TanStack provides a start-basic project. We'll use this starter project to create a new TanStack Start application.
19+
TanStack Start Beta has significantly improved Cloudflare compatibility compared to the Alpha version, making deployment and development much more straightforward.
2020

2121
<Steps>
2222

@@ -27,10 +27,10 @@ TanStack provides a start-basic project. We'll use this starter project to creat
2727
cd start-basic
2828
npm install
2929
```
30-
31-
<Details header="How is this project set up?">
32-
This command will clone the TanStack Start basic project to your local machine, change directory to the project, and install the dependencies. TanStack [provides other examples](https://tanstack.com/start/latest/docs/framework/react/quick-start#examples) that you can use by replacing `start-basic` with the example you want to use.
33-
</Details>
30+
31+
<Details header="How is this project set up?">
32+
This command will clone the TanStack Start basic project to your local machine, change directory to the project, and install the dependencies. TanStack [provides other examples](https://tanstack.com/start/latest/docs/framework/react/quick-start#examples) that you can use by replacing `start-basic` with the example you want to use.
33+
</Details>
3434

3535
2. **Develop locally**
3636

@@ -46,34 +46,33 @@ Whether you created a new TanStack Start project or are using an existing projec
4646

4747
<Steps>
4848

49-
1. **Install `unenv` & `nitroCloudflareBindings` package**
50-
51-
[`unenv`](https://github.com/unjs/unenv) is a package that normalizes runtime environments across Node.js, browsers, and edge runtimes like Cloudflare Workers. It’s essential for TanStack Router because certain Node.js APIs are unavailable in the Workers environment. `unenv` offers compatible replacements for those APIs.
52-
53-
[`nitro-cloudflare-dev`](https://github.com/nitrojs/nitro-cloudflare-dev) enables access to the Cloudflare runtime bindings like R2, D1, and other Cloudflare services in the development server.
54-
55-
<PackageManagers pkg="unenv nitro-cloudflare-dev" />
56-
57-
2. **Modify the `app.config.ts` file**
58-
59-
To configure your application for Cloudflare Workers deployment, add the following lines to your `app.config.ts` file:
60-
61-
```ts
62-
// Required imports
63-
import { cloudflare } from 'unenv'
64-
import nitroCloudflareBindings from "nitro-cloudflare-dev";
65-
66-
// Add this new server section to the defineConfig object
67-
server: {
68-
preset: "cloudflare-module",
69-
unenv: cloudflare,
70-
modules: [nitroCloudflareBindings],
71-
},
49+
1. **Configure Vite for Cloudflare compatibility**
50+
51+
Update your `vite.config.ts` file to use the `cloudflare-module` target for a compatible build:
52+
53+
```ts title="vite.config.ts" {14}
54+
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
55+
import { defineConfig } from "vite";
56+
import tsConfigPaths from "vite-tsconfig-paths";
57+
58+
export default defineConfig({
59+
server: {
60+
port: 3000,
61+
},
62+
plugins: [
63+
tsConfigPaths({
64+
projects: ["./tsconfig.json"],
65+
}),
66+
tanstackStart({
67+
target: "cloudflare-module", // Key configuration for Cloudflare compatibility
68+
}),
69+
],
70+
});
7271
```
7372

74-
This will set the correct build format and runtime environment for Cloudflare.
73+
This single configuration change is all that's needed to make your TanStack Start application compatible with Cloudflare Workers.
7574

76-
3. **Add a Wrangler file**
75+
2. **Add a Wrangler file**
7776

7877
Create a `wrangler.jsonc` or `wrangler.toml` file in the root of your project, `wrangler.jsonc` is the recommended approach. This file is used to configure the Cloudflare Workers deployment.
7978

@@ -82,23 +81,45 @@ Whether you created a new TanStack Start project or are using an existing projec
8281
```json
8382
{
8483
"$schema": "node_modules/wrangler/config-schema.json",
85-
"name": "start-basic",
86-
"main": "./.output/server/index.mjs",
87-
"compatibility_date": "2025-04-14",
84+
"name": "my-start-app",
85+
"main": ".output/server/index.mjs",
86+
"compatibility_date": "$today",
87+
"compatibility_flags": ["nodejs_compat"],
88+
"assets": {
89+
"directory": ".output/public"
90+
},
8891
"observability": {
8992
"enabled": true
9093
},
91-
"assets": {
92-
"directory": "./.output/public/"
93-
},
94-
"compatibility_flags": ["nodejs_compat"]
94+
"kv_namespaces": [
95+
{
96+
"binding": "CACHE",
97+
"id": "<Your KV ID>"
98+
}
99+
]
95100
}
96101
```
97102

98103
</WranglerConfig>
99104

100-
Note that the `directory` key is set to `.output/public/`, which is the folder that will be filled with the build output. Additionally, the `main` key is set to `.output/server/index.mjs`, indicating to Cloudflare Workers where to locate the entry point for your application.
105+
Note that the `directory` key is set to `.output/public`, which is the folder that will be filled with the build output. Additionally, the `main` key is set to `.output/server/index.mjs`, indicating to Cloudflare Workers where to locate the entry point for your application. The `kv_namespaces` section shows an example of how to configure a KV namespace binding.
106+
107+
3. **Add deployment scripts to package.json**
108+
109+
Add the following scripts to your `package.json` file to streamline deployment and type generation:
110+
111+
```json title="package.json
112+
{
113+
"scripts": {
114+
...
115+
"deploy": "npm run build && wrangler deploy",
116+
"cf-typegen": "wrangler types --env-interface Env"
117+
}
118+
}
119+
```
101120

121+
The `deploy` script combines building and deploying in one command, while `cf-typegen` generates TypeScript types for your Cloudflare bindings.
122+
102123
4. **Build the application**
103124

104125
You must build your application before deploying it to Cloudflare Workers.
@@ -107,75 +128,104 @@ Whether you created a new TanStack Start project or are using an existing projec
107128

108129
5. **Deploy the application**
109130

110-
The command below will deploy your application to Cloudflare Workers and provide a deployment URL. Make sure to rebuild your application after making any changes to see those changes reflected in the deployment.
131+
You can now use the deploy script to build and deploy your application in one command:
132+
133+
<PackageManagers type="run" args={"deploy"} />
134+
135+
Alternatively, you can still deploy directly with Wrangler:
111136

112137
```sh
113138
npx wrangler deploy
114139
```
115140

116-
When making changes in the future ensure you rebuild your application. The deploy will deploy what is in your `.output/public` folder and that only gets updated when you run the build command.
117-
118141
</Steps>
119142

120143
## Using Cloudflare Bindings
121144

122145
<Steps>
123146

124-
1. **Create a helper function to get access to Cloudflare bindings**
147+
1. **Generate TypeScript types for your bindings**
125148

126-
Create a helper function named `cloudflareBindings.ts` in the `src/utils` folder, and paste in the below code. You can create a `utils` folder in your project if you don't already have one. The example assumes you have a KV namespace with a binding name of `CACHE` already created in your account and added to the wrangler file.
149+
Before using Cloudflare bindings in your code, generate the TypeScript types to ensure proper type safety:
127150

128-
```ts
129-
import type { KVNamespace } from "@cloudflare/workers-types";
151+
<PackageManagers type="run" args={"cf-typegen"} />
152+
153+
This command reads your `wrangler.jsonc` configuration and generates an `Env` interface with all your configured bindings.
130154

131-
interface CloudflareBindings {
132-
CACHE: KVNamespace;
155+
2. **Create a helper function to get access to Cloudflare bindings**
156+
157+
Create a helper function named `bindings.ts` in the `src/utils` folder (create the folder if it doesn't exist), and paste in the below code. The example assumes you have a KV namespace with a binding name of `CACHE` already created in your account and added to the wrangler file.
158+
159+
160+
```ts title="src/utils/bindings.ts"
161+
162+
let cachedEnv: Env | null = null;
163+
164+
// This gets called once at startup when running locally
165+
const initDevEnv = async () => {
166+
const { getPlatformProxy } = await import("wrangler");
167+
const proxy = await getPlatformProxy();
168+
cachedEnv = proxy.env as unknown as Env;
169+
};
170+
171+
if (import.meta.env.DEV) {
172+
await initDevEnv();
133173
}
174+
134175
/**
135176
* Will only work when being accessed on the server. Obviously, CF bindings are not available in the browser.
136177
* @returns
137178
*/
138-
export async function getBindings() {
179+
export function getBindings(): Env {
139180
if (import.meta.env.DEV) {
140-
const { getPlatformProxy } = await import("wrangler");
141-
const { env } = await getPlatformProxy();
142-
return env as unknown as CloudflareBindings;
181+
if (!cachedEnv) {
182+
throw new Error(
183+
"Dev bindings not initialized yet. Call initDevEnv() first."
184+
);
185+
}
186+
return cachedEnv;
143187
}
144188

145-
return process.env as unknown as CloudflareBindings;
189+
return process.env as unknown as Env;
146190
}
147191
```
148192

149193
<Details header="How is this code working?">
150-
To ensure your bindings work locally with vinxi, the helper function uses
151-
[getPlatformProxy](https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy)
152-
method from wrangler. This logic is placed under a check if
153-
import.meta.env.DEV is true.
194+
The helper function uses [getPlatformProxy](/workers/wrangler/api/#getplatformproxy) method from wrangler to provide access to your Cloudflare bindings during local development. The bindings are cached at startup for better performance. In production, bindings are accessed via `process.env`. Make sure you've run `npm run cf-typegen` to generate the `Env` types that this code references.
154195
</Details>
155196

156-
2. **Example using a Cloudflare Binding**
197+
3. **Example using a Cloudflare Binding in Server Functions**
157198

158-
Now that you have a helper function to get access to your Cloudflare bindings, you can use them in your application.
199+
Now that you have a helper function to get access to your Cloudflare bindings, you can use them in your server functions.
159200

160201
Remember bindings are only available on the server.
161202

162203
```ts
163-
const bindings = await getBindings();
164-
const cache = bindings.CACHE;
165-
const queryCount = (await cache.get("queryCount")) || "0";
166-
await cache.put("queryCount", String(Number(queryCount) + 1));
204+
import { createServerFn } from "@tanstack/react-start";
205+
import { getBindings } from "~/utils/bindings";
206+
207+
const personServerFn = createServerFn({ method: "GET" })
208+
.validator((d: string) => d)
209+
.handler(async ({ data: name }) => {
210+
const env = getBindings();
211+
let growingAge = Number((await env.CACHE.get("age")) || 0);
212+
growingAge++;
213+
await env.CACHE.put("age", growingAge.toString());
214+
return { name, randomNumber: growingAge };
215+
});
167216
```
168217

169-
A special thanks to GitHub user [backpine](https://github.com/backpine) for the code that supports Cloudflare Bindings in TanStack, which is demonstrated in their [TanStack Start on Workers example](https://github.com/backpine/tanstack-start-on-cloudflare-workers-v0).
218+
A special thanks to GitHub user [backpine](https://github.com/backpine) for the code that supports Cloudflare Bindings in TanStack Start, which is demonstrated in their [TanStack Start Beta on Cloudflare example](https://github.com/backpine/tanstack-start-beta-on-cloudflare).
170219

171220
</Steps>
172221

173-
#### Optional: Update utils file with deployment URL
222+
## Environment Handling
223+
224+
The TanStack Start Beta version provides seamless environment handling:
174225

175-
This step is required for the `/users` page to function properly in the `start-basic` example. Update the `/src/utils/users.tsx` file with the Cloudflare Workers deployment URL.
226+
- **Development**: Bindings are accessed via [`getPlatformProxy()`](/workers/wrangler/api/#getplatformproxy) from Wrangler and cached at startup
227+
- **Production**: Bindings are accessed via [`process.env`](/workers/runtime-apis/nodejs/process/#processenv)
176228

177-
```ts
178-
export const DEPLOY_URL = "YOUR_DEPLOYMENT_URL";
179-
```
229+
This approach ensures your bindings are properly typed throughout your project and provides a smooth development experience.
180230

181231
By following the steps above, you will have deployed your TanStack Start application to Cloudflare Workers.

0 commit comments

Comments
 (0)