React Router
This guide demonstrates how to deploy a React Router (formerly Remix.js) application to Cloudflare with Alchemy.
Init
Start by creating a new React Router project using Alchemy:
bunx alchemy create my-react-router-app --template=react-router
cd my-react-router-app
npx alchemy create my-react-router-app --template=react-router
cd my-react-router-app
pnpm dlx alchemy create my-react-router-app --template=react-router
cd my-react-router-app
yarn dlx alchemy create my-react-router-app --template=react-router
cd my-react-router-app
Login
Before you can deploy, you need to authenticate by running wrangler login
.
bun wrangler login
npx wrangler login
pnpm wrangler login
yarn wrangler login
TIP
Alchemy will by default try and use your wrangler OAuth token and Refresh Token to connect but see the Cloudflare Auth for other methods.
Deploy
Now we can run and deploy our Alchemy stack:
bun run deploy
npm run deploy
pnpm run deploy
yarn run deploy
It will log out the URL of your new React Router website hosted on Cloudflare:
{
url: "https://website.${your-sub-domain}.workers.dev",
}
Local
bun run dev
npm run dev
pnpm run dev
yarn run dev
Destroy
For illustrative purposes, let's destroy the Alchemy stack:
bun run destroy
npm run destroy
pnpm run destroy
yarn run destroy
Explore
.env
Alchemy requires a locally set password to encrypt Secrets that are stored in state. Be sure to change this.
NOTE
See the Secret documentation to learn more.
ALCHEMY_PASSWORD=change-me
alchemy.run.ts
The alchemy.run.ts
file contains your infrastructure setup:
/// <reference types="@types/node" />
import alchemy from "alchemy";
import { ReactRouter } from "alchemy/cloudflare";
const app = await alchemy("my-react-router-app");
export const worker = await ReactRouter("website", {
main: "./workers/app.ts",
command: "bun run build",
});
console.log({
url: worker.url,
});
await app.finalize();
types/env.d.ts
The types/env.d.ts
file provides type-safe access to Cloudflare bindings:
// This file infers types for the cloudflare:workers environment from your Alchemy Worker.
// @see https://alchemy.run/docs/concepts/bindings.html#type-safe-bindings
import type { worker } from "../alchemy.run.ts";
export type CloudflareEnv = typeof worker.Env;
declare global {
type Env = CloudflareEnv;
}
declare module "cloudflare:workers" {
namespace Cloudflare {
export interface Env extends CloudflareEnv {}
}
}
tsconfig.node.json
The CLI updated the tsconfig.node.json
to include alchemy.run.ts
and register @cloudflare/workers-types
+ types/env.d.ts
globally
TIP
The alchemy.run.ts
script will be run by node
but still needs to infer the Binding types which depends on @cloudflare/workers-types
:
{
"extends": "./tsconfig.json",
"include": [
"vite.config.ts",
// ensure our types and alchemy.run.ts are included
"types/**/*.ts",
"alchemy.run.ts"
],
"compilerOptions": {
"composite": true,
"strict": true,
// register cloudflare types and our Env types globally
"types": ["@cloudflare/workers-types", "./types/env.d.ts"],
"lib": ["ES2022"],
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler"
}
}