|
| 1 | +--- |
| 2 | +pcx_content_type: how-to |
| 3 | +title: TanStack Router |
| 4 | +head: [] |
| 5 | +description: Create a TanStack Router application and deploy it to Cloudflare Workers with Workers Assets. |
| 6 | +--- |
| 7 | + |
| 8 | +import { WranglerConfig, Steps, PackageManagers, Details } from "~/components"; |
| 9 | + |
| 10 | +## What is TanStack Start? |
| 11 | + |
| 12 | +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. |
| 13 | + |
| 14 | +## Create a new TanStack Start |
| 15 | + |
| 16 | +TanStack provides a start-basic project. We'll use this starter project to create a new TanStack Start application. |
| 17 | + |
| 18 | +<Steps> |
| 19 | + |
| 20 | +1. **Create a new TanStack Start project** |
| 21 | + |
| 22 | + ```sh |
| 23 | + npx gitpick TanStack/router/tree/main/examples/react/start-basic start-basic |
| 24 | + cd start-basic |
| 25 | + npm install |
| 26 | + ``` |
| 27 | + |
| 28 | + <Details header="How is this project set up?"> |
| 29 | + 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. |
| 30 | + </Details> |
| 31 | + |
| 32 | +2. **Develop locally** |
| 33 | + |
| 34 | + After creating your project, run the following command in your project directory to start a local development server. By default this starts a local development server on `http://localhost:3000/` |
| 35 | + |
| 36 | + <PackageManagers type="run" args="dev" /> |
| 37 | + |
| 38 | +</Steps> |
| 39 | + |
| 40 | +## Preparing for Deployment to Cloudflare Workers |
| 41 | + |
| 42 | +Whether you created a new TanStack Start project or are using an existing project, you'll need to make some changes to prepare for deployment to Cloudflare Workers. |
| 43 | + |
| 44 | +<Steps> |
| 45 | + |
| 46 | +1. **Install `unenv` & `nitroCloudflareBindings` package** |
| 47 | + |
| 48 | + [`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. |
| 49 | + |
| 50 | + [`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. |
| 51 | + |
| 52 | + <PackageManagers pkg="unenv nitro-cloudflare-dev" type="install" /> |
| 53 | + |
| 54 | +2. **Modify the `app.config.ts` file** |
| 55 | + |
| 56 | + To configure your application for Cloudflare Workers deployment, add the following lines to your `app.config.ts` file: |
| 57 | + |
| 58 | + ```ts |
| 59 | + // Required imports |
| 60 | + import { cloudflare } from 'unenv' |
| 61 | + import nitroCloudflareBindings from "nitro-cloudflare-dev"; |
| 62 | + |
| 63 | + // Add this new server section to the defineConfig object |
| 64 | + server: { |
| 65 | + preset: "cloudflare-module", |
| 66 | + unenv: cloudflare, |
| 67 | + modules: [nitroCloudflareBindings], |
| 68 | + }, |
| 69 | + ``` |
| 70 | + |
| 71 | + This will set the correct build format and runtime environment for Cloudflare. |
| 72 | + |
| 73 | +3. **Add a Wrangler file** |
| 74 | + |
| 75 | + 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. |
| 76 | + |
| 77 | + <WranglerConfig> |
| 78 | + ```json |
| 79 | + { |
| 80 | + "$schema": "node_modules/wrangler/config-schema.json", |
| 81 | + "name": "start-basic", |
| 82 | + "main": "./.output/server/index.mjs", |
| 83 | + "compatibility_date": "2025-04-14", |
| 84 | + "observability": { |
| 85 | + "enabled": true, |
| 86 | + }, |
| 87 | + "assets": { |
| 88 | + "directory": "./.output/public/", |
| 89 | + }, |
| 90 | + "compatibility_flags": ["nodejs_compat"], |
| 91 | + } |
| 92 | + ``` |
| 93 | + </WranglerConfig> |
| 94 | + |
| 95 | + 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. |
| 96 | + |
| 97 | +4. **Build the application** |
| 98 | + |
| 99 | + You must build your application before deploying it to Cloudflare Workers. |
| 100 | + |
| 101 | + <PackageManagers type="run" args={"build"} /> |
| 102 | + |
| 103 | + |
| 104 | +5. **Deploy the application** |
| 105 | + |
| 106 | + 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. |
| 107 | + |
| 108 | + ```sh |
| 109 | + npx wrangler deploy |
| 110 | + ``` |
| 111 | + |
| 112 | + 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. |
| 113 | + |
| 114 | +</Steps> |
| 115 | + |
| 116 | +## Using Cloudflare Bindings |
| 117 | + |
| 118 | +<Steps> |
| 119 | + |
| 120 | +1. **Create a helper function to get access to Cloudflare bindings** |
| 121 | + |
| 122 | + 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. |
| 123 | + |
| 124 | + ```ts |
| 125 | + import type { KVNamespace } from "@cloudflare/workers-types"; |
| 126 | + |
| 127 | + interface CloudflareBindings { |
| 128 | + CACHE: KVNamespace; |
| 129 | + } |
| 130 | + /** |
| 131 | + * Will only work when being accessed on the server. Obviously, CF bindings are not available in the browser. |
| 132 | + * @returns |
| 133 | + */ |
| 134 | + export async function getBindings() { |
| 135 | + if (import.meta.env.DEV) { |
| 136 | + const { getPlatformProxy } = await import("wrangler"); |
| 137 | + const { env } = await getPlatformProxy(); |
| 138 | + return env as unknown as CloudflareBindings; |
| 139 | + } |
| 140 | + |
| 141 | + return process.env as unknown as CloudflareBindings; |
| 142 | + } |
| 143 | + ``` |
| 144 | + <Details header="How is this code working?"> |
| 145 | + To ensure your bindings work locally with vinxi, the helper function uses [getPlatformProxy](https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy) method from wrangler. This logic is placed under a check if import.meta.env.DEV is true. |
| 146 | + </Details> |
| 147 | + |
| 148 | +2. **Example using a Cloudflare Binding** |
| 149 | + |
| 150 | + Now that you have a helper function to get access to your Cloudflare bindings, you can use them in your application. |
| 151 | + |
| 152 | + Remember bindings are only available on the server. |
| 153 | + |
| 154 | + ```ts |
| 155 | + const bindings = await getBindings(); |
| 156 | + const cache = bindings.CACHE; |
| 157 | + const queryCount = (await cache.get("queryCount")) || "0"; |
| 158 | + await cache.put("queryCount", String(Number(queryCount) + 1)); |
| 159 | + ``` |
| 160 | + |
| 161 | + 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). |
| 162 | + |
| 163 | + |
| 164 | +</Steps> |
| 165 | + |
| 166 | +#### Optional: Update utils file with deployment URL |
| 167 | + |
| 168 | +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. |
| 169 | + |
| 170 | +```ts |
| 171 | +export const DEPLOY_URL = "YOUR_DEPLOYMENT_URL"; |
| 172 | +``` |
| 173 | + |
| 174 | +By following the steps above, you will have deployed your TanStack Start application to Cloudflare Workers. |
0 commit comments