diff --git a/contributors.yml b/contributors.yml
index 430b616774d..fdb38a9648c 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -11,6 +11,7 @@
 - AdiRishi
 - ahabhgk
 - ahbruns
+- AhmadMayo
 - ahmedeldessouki
 - ahuth
 - aiji42
@@ -35,6 +36,7 @@
 - alongdate
 - AltanS
 - alvinthen
+- amanape
 - amir-ziaei
 - amorriscode
 - andreiduca
@@ -84,6 +86,7 @@
 - bogas04
 - BogdanDevBst
 - bolchowka
+- brenr
 - brettscott
 - brookslybrand
 - brophdawg11
@@ -500,6 +503,7 @@
 - nobeeakon
 - nordiauwu
 - not-ivy
+- npapagna
 - nrako
 - nurul3101
 - nvh95
@@ -522,6 +526,7 @@
 - plastic041
 - plondon
 - pmbanugo
+- Pouet--
 - prasook-jain
 - pratikdevdas
 - princerajroy
diff --git a/docs/discussion/pending-ui.md b/docs/discussion/pending-ui.md
index a75d04428fe..4f3445186d5 100644
--- a/docs/discussion/pending-ui.md
+++ b/docs/discussion/pending-ui.md
@@ -192,7 +192,7 @@ function ProjectListItem({ project }) {
           value={starred ? "0" : "1"}
         >
           {/* 👇 display optimistic value */}
-          {starred ? "☆" : "★"}
+          {starred ? "★" : "☆"}
         </button>
       </fetcher.Form>
     </>
diff --git a/docs/file-conventions/routes.md b/docs/file-conventions/routes.md
index f90c3007965..e33004d18d5 100644
--- a/docs/file-conventions/routes.md
+++ b/docs/file-conventions/routes.md
@@ -21,8 +21,8 @@ Large applications with hundred or thousands of routes will _always_ be a bit ch
 So, before we dive into the details of the Remix default convention, here's some community alternatives you can check out if you decide that our default is not your cup of tea.
 
 - [`remix-flat-routes`][flat_routes] - The Remix default is basically a simplified version of this package. The author has continued to iterate on and evolve this package so if you generally like the "flat routes" idea but want a bit more power (including a hybrid approach of files and folders), definitely check this one out.
-- [`remix-custom-routes`][custom_routes] - If you want even more customization, this package lets you define that types of files should be treated as routes. This let's you go beyond simply flat/nested and do something such as _"any file with an extension of `.route.tsx` is a route"_.
-- [`remix-json-routes`][json_routes] - If you just want to specify your routes in a config, this is your jam - just give Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too.
+- [`remix-custom-routes`][custom_routes] - If you want even more customization, this package lets you define that types of files should be treated as routes. This lets you go beyond the simple flat/nested concept and do something such as _"any file with an extension of `.route.tsx` is a route"_.
+- [`remix-json-routes`][json_routes] - If you just want to specify your routes via a config file, this is your jam - just provide Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too.
 
 ## Root Route
 
diff --git a/docs/guides/single-fetch.md b/docs/guides/single-fetch.md
index 5571be0d4ec..22fc56c0496 100644
--- a/docs/guides/single-fetch.md
+++ b/docs/guides/single-fetch.md
@@ -6,7 +6,7 @@ title: Single Fetch
 
 <docs-warning>This is an unstable API and will continue to change, do not adopt in production</docs-warning>
 
-Single Fetch is a new data data loading strategy and streaming format. When you enable Single Fetch, Remix will make a single HTTP call to your server on client-side transitions, instead of multiple HTTP calls in parallel (one per loader). Additionally, Single Fetch also allows you to send down naked objects from your `loader` and `action`, such as `Date`, `Error`, `Promise`, `RegExp`, and more.
+Single Fetch is a new data loading strategy and streaming format. When you enable Single Fetch, Remix will make a single HTTP call to your server on client-side transitions, instead of multiple HTTP calls in parallel (one per loader). Additionally, Single Fetch also allows you to send down naked objects from your `loader` and `action`, such as `Date`, `Error`, `Promise`, `RegExp`, and more.
 
 ## Overview
 
diff --git a/docs/hooks/use-action-data.md b/docs/hooks/use-action-data.md
index c0bc40ead70..ed7b7852ba7 100644
--- a/docs/hooks/use-action-data.md
+++ b/docs/hooks/use-action-data.md
@@ -5,7 +5,7 @@ toc: false
 
 # `useActionData`
 
-Returns the serialized data from the most recent route action or `undefined` if there isn't one.
+Returns the serialized data from the most recent route [action][action] or `undefined` if there isn't one. This hook only returns action data from the route in context - it can not access data from other parent or child routes.
 
 ```tsx lines=[10,14]
 import type { ActionFunctionArgs } from "@remix-run/node"; // or cloudflare/deno
diff --git a/docs/start/quickstart.md b/docs/start/quickstart.md
index 47eabca68cf..c38822e6a27 100644
--- a/docs/start/quickstart.md
+++ b/docs/start/quickstart.md
@@ -95,7 +95,7 @@ First build the app for production:
 npx remix vite:build
 ```
 
-You should now see a `build` folder containing a `server` folder (the server version of your app) and a `client` folder (the browser version) with some build artifacts in them. (This is all [configurable][remix_config].)
+You should now see a `build` folder containing a `server` folder (the server version of your app) and a `client` folder (the browser version) with some build artifacts in them. (This is all [configurable][vite_config].)
 
 👉 **Run the app with `remix-serve`**
 
@@ -276,7 +276,7 @@ What's next?
 [runtimes]: ../discussion/runtimes
 [inspect]: https://nodejs.org/en/docs/guides/debugging-getting-started/
 [tutorial]: ./tutorial
-[remix_config]: ../file-conventions/remix-config
+[vite_config]: ../file-conventions/vite-config
 [templates]: /resources?category=templates
 [http-localhost-3000]: http://localhost:3000
 [es-modules]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
diff --git a/templates/cloudflare-workers/load-context.ts b/templates/cloudflare-workers/load-context.ts
index e9604b71ba0..5fc575ba11c 100644
--- a/templates/cloudflare-workers/load-context.ts
+++ b/templates/cloudflare-workers/load-context.ts
@@ -1,7 +1,13 @@
 import { type PlatformProxy } from "wrangler";
 
+// PlatformProxy’s caches property is incompatible with the caches global
+// https://github.com/cloudflare/workers-sdk/blob/main/packages/wrangler/src/api/integrations/platform/caches.ts
+type Cloudflare = Omit<PlatformProxy<Env>, "dispose" | "caches"> & {
+  caches: CacheStorage;
+};
+
 declare module "@remix-run/cloudflare" {
   interface AppLoadContext {
-    cloudflare: Omit<PlatformProxy<Env>, "dispose">;
+    cloudflare: Cloudflare;
   }
 }
diff --git a/templates/cloudflare-workers/package.json b/templates/cloudflare-workers/package.json
index 94c82f16be8..5c226bfde73 100644
--- a/templates/cloudflare-workers/package.json
+++ b/templates/cloudflare-workers/package.json
@@ -7,7 +7,7 @@
     "deploy": "wrangler deploy",
     "dev": "remix vite:dev",
     "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
-    "start": "wrangler dev ./server.js",
+    "start": "wrangler dev",
     "typegen": "wrangler types",
     "typecheck": "tsc"
   },
diff --git a/templates/cloudflare-workers/server.js b/templates/cloudflare-workers/server.ts
similarity index 75%
rename from templates/cloudflare-workers/server.js
rename to templates/cloudflare-workers/server.ts
index 034653d326a..7a988c47d9b 100644
--- a/templates/cloudflare-workers/server.js
+++ b/templates/cloudflare-workers/server.ts
@@ -1,11 +1,14 @@
 import { getAssetFromKV } from "@cloudflare/kv-asset-handler";
-import { createRequestHandler } from "@remix-run/cloudflare";
-import * as remixBuild from "./build/server";
+import { createRequestHandler, type ServerBuild } from "@remix-run/cloudflare";
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore This file won’t exist if it hasn’t yet been built
+import * as build from "./build/server"; // eslint-disable-line import/no-unresolved
 // eslint-disable-next-line import/no-unresolved
 import __STATIC_CONTENT_MANIFEST from "__STATIC_CONTENT_MANIFEST";
 
 const MANIFEST = JSON.parse(__STATIC_CONTENT_MANIFEST);
-const handleRemixRequest = createRequestHandler(remixBuild);
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const handleRemixRequest = createRequestHandler(build as any as ServerBuild);
 
 export default {
   async fetch(request, env, ctx) {
@@ -50,4 +53,4 @@ export default {
       return new Response("An unexpected error occurred", { status: 500 });
     }
   },
-};
+} satisfies ExportedHandler<Env & { __STATIC_CONTENT: KVNamespace<string> }>;
diff --git a/templates/cloudflare-workers/wrangler.toml b/templates/cloudflare-workers/wrangler.toml
index 51b671d52f8..bdebe9f88ea 100644
--- a/templates/cloudflare-workers/wrangler.toml
+++ b/templates/cloudflare-workers/wrangler.toml
@@ -1,6 +1,6 @@
 name = "remix-cloudflare-workers-template"
 
-main = "./server.js"
+main = "./server.ts"
 workers_dev = true
 # https://developers.cloudflare.com/workers/platform/compatibility-dates
 compatibility_date = "2023-04-20"
diff --git a/templates/cloudflare/README.md b/templates/cloudflare/README.md
index d3df5abea1d..dec7f30b37a 100644
--- a/templates/cloudflare/README.md
+++ b/templates/cloudflare/README.md
@@ -30,10 +30,6 @@ You will need to rerun typegen whenever you make changes to `wrangler.toml`.
 
 ## Deployment
 
-> [!WARNING]  
-> Cloudflare does _not_ use `wrangler.toml` to configure deployment bindings.
-> You **MUST** [configure deployment bindings manually in the Cloudflare dashboard][bindings].
-
 First, build your app for production:
 
 ```sh
@@ -46,8 +42,6 @@ Then, deploy your app to Cloudflare Pages:
 npm run deploy
 ```
 
-[bindings]: https://developers.cloudflare.com/pages/functions/bindings/
-
 ## Styling
 
 This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information.