From c487132ad6641cb4cf00ad3965d49c5e9691e0ca Mon Sep 17 00:00:00 2001 From: Arnas Donauskas <61235555+ArnasDon@users.noreply.github.com> Date: Wed, 1 Jul 2026 18:18:09 +0300 Subject: [PATCH 1/6] docs: add Hostinger as a hosting provider (#15268) * docs: add Hostinger as a hosting provider for deploying Co-Authored-By: Claude Opus 4.8 * Sign the CLA Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- contributors.yml | 1 + docs/start/framework/deploying.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/contributors.yml b/contributors.yml index 7cd8265fed..8b39ff999c 100644 --- a/contributors.yml +++ b/contributors.yml @@ -41,6 +41,7 @@ - arjunyel - arka1002 - Armanio +- ArnasDon - arnassavickas - aroyan - arpitjain099 diff --git a/docs/start/framework/deploying.md b/docs/start/framework/deploying.md index 16194ef1cc..a7a57e6f22 100644 --- a/docs/start/framework/deploying.md +++ b/docs/start/framework/deploying.md @@ -98,3 +98,7 @@ EdgeOne Pages maintains their own template for React Router. Checkout the [EdgeO ### DeployHQ DeployHQ maintains their own guide for deploying React Router to your own server. Checkout the [DeployHQ Guide](https://www.deployhq.com/guides/deploy-react-router-from-github) for more information. + +### Hostinger + +Hostinger supports deploying React Router applications with server rendering on its managed Node.js hosting, including automatic deployments from GitHub. Checkout the [Hostinger Guide](https://www.hostinger.com/web-apps-hosting/react-router-hosting) for more information. From 59c13c5a46d16b2909478f4ff99c0a0a5aa4740f Mon Sep 17 00:00:00 2001 From: Ayush Chaudhary <147637466+ayush23chaudhary@users.noreply.github.com> Date: Wed, 1 Jul 2026 20:57:21 +0530 Subject: [PATCH 2/6] docs: improve useMatches conceptual explanation and examples (#15205) (#15267) * docs: improve useMatches conceptual explanation and examples * chore: sign CLA * docs: fix jsx syntax, apply typeof filter, and clean whitespace in useMatches * Update docs * Update docs --------- Co-authored-by: Matt Brophy --- contributors.yml | 1 + packages/react-router/lib/hooks.tsx | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/contributors.yml b/contributors.yml index 8b39ff999c..6537cae2c5 100644 --- a/contributors.yml +++ b/contributors.yml @@ -51,6 +51,7 @@ - AviVahl - awreese - aymanemadidi +- ayushchaudhary - ayushmanchhabra - babafemij-k - bangseongbeom diff --git a/packages/react-router/lib/hooks.tsx b/packages/react-router/lib/hooks.tsx index fb593eba98..b0e297a7ff 100644 --- a/packages/react-router/lib/hooks.tsx +++ b/packages/react-router/lib/hooks.tsx @@ -1533,6 +1533,29 @@ export function useRevalidator(): { * parent/child routes or the route [`handle`](../../start/framework/route-module#handle) * property * + * Pairing the route `handle` with `useMatches` gets very powerful since you can put + * whatever you want on a route handle and have access to `useMatches` anywhere. + * Please see the [handle](../../how-to/using-handle) documentation for an example + * of breadcrumbs via `useMatches`/`handle`. + * + * ```tsx + * import { useMatches } from "react-router"; + * + * function SomeComponent() { + * const matches = useMatches(); + * // matches[i].id // route id + * // matches[i].pathname // the portion of the URL the route matched + * // matches[i].params // the parsed params from the URL + * // matches[i].loaderData // the data from the loader + * // matches[i].handle // the route handle with any app specific data + * } + * ``` + * + * useMatches only works with a data router like `createBrowserRouter`, + * since they know the full route tree up front and can provide all of the current + * matches. Additionally, `useMatches` will not match down into any descendant route + * trees since the router isn't aware of the descendant routes. + * * @public * @category Hooks * @mode framework From f8bff7a846bd1f27452991b27528cb4e194b74f2 Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Wed, 1 Jul 2026 15:28:22 +0000 Subject: [PATCH 3/6] chore: generate markdown docs from jsdocs --- docs/api/hooks/useMatches.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/api/hooks/useMatches.md b/docs/api/hooks/useMatches.md index 0fa0f79181..4a43c71eaa 100644 --- a/docs/api/hooks/useMatches.md +++ b/docs/api/hooks/useMatches.md @@ -26,6 +26,29 @@ Returns the active route matches, useful for accessing `loaderData` for parent/child routes or the route [`handle`](../../start/framework/route-module#handle) property +Pairing the route `handle` with `useMatches` gets very powerful since you can put +whatever you want on a route handle and have access to `useMatches` anywhere. +Please see the [handle](../../how-to/using-handle) documentation for an example +of breadcrumbs via `useMatches`/`handle`. + +```tsx +import { useMatches } from "react-router"; + +function SomeComponent() { + const matches = useMatches(); + // matches[i].id // route id + // matches[i].pathname // the portion of the URL the route matched + // matches[i].params // the parsed params from the URL + // matches[i].loaderData // the data from the loader + // matches[i].handle // the route handle with any app specific data +} +``` + +useMatches only works with a data router like `createBrowserRouter`, +since they know the full route tree up front and can provide all of the current +matches. Additionally, `useMatches` will not match down into any descendant route +trees since the router isn't aware of the descendant routes. + ## Signature ```tsx From 2cc25c701b2c565180a600c820bf01ae903ad1da Mon Sep 17 00:00:00 2001 From: Edmund Hung Date: Wed, 1 Jul 2026 17:15:46 +0100 Subject: [PATCH 4/6] feat: add default web-streams based server entry (#14759) * feat: add default server entry for non-Node runtimes * remove node runtime check from default server entry * update contributors.yml * improve runtime detection in default server entries * improve the name of the added test * Updates * add change file * reorder * Switch to web streams * Realign import * Update change file * Remove uneccesary playground entry * Fix E2E tests * Updatre change file * Another update --------- Co-authored-by: Matt Brophy --- .../framework-conventions/entry.server.tsx.md | 8 +- integration/defer-test.ts | 80 ++++++++++++----- integration/link-test.ts | 5 +- integration/vite-plugin-cloudflare-test.ts | 19 +++- .../.changes/minor.web-streams-entry.md | 11 +++ packages/react-router-dev/cli/commands.ts | 11 +-- packages/react-router-dev/config/config.ts | 8 +- .../config/defaults/entry.server.node.tsx | 86 ------------------- .../config/defaults}/entry.server.tsx | 15 +++- .../app/entry.server.tsx | 43 ---------- 10 files changed, 107 insertions(+), 179 deletions(-) create mode 100644 packages/react-router-dev/.changes/minor.web-streams-entry.md delete mode 100644 packages/react-router-dev/config/defaults/entry.server.node.tsx rename {integration/helpers/vite-plugin-cloudflare-template/app => packages/react-router-dev/config/defaults}/entry.server.tsx (79%) delete mode 100644 playground/vite-plugin-cloudflare/app/entry.server.tsx diff --git a/docs/api/framework-conventions/entry.server.tsx.md b/docs/api/framework-conventions/entry.server.tsx.md index aa9e854162..cbad2a1c67 100644 --- a/docs/api/framework-conventions/entry.server.tsx.md +++ b/docs/api/framework-conventions/entry.server.tsx.md @@ -145,11 +145,9 @@ _Note that you generally want to avoid logging when the request was aborted, sin **Streaming Rendering Errors** -When you are streaming your HTML responses via [`renderToPipeableStream`][rendertopipeablestream] or [`renderToReadableStream`][rendertoreadablestream], your own `handleError` implementation will only handle errors encountered during the initial shell render. If you encounter a rendering error during subsequent streamed rendering you will need to handle these errors manually since the React Router server has already sent the Response by that point. +When you are streaming your HTML responses via [`renderToReadableStream`][rendertoreadablestream], your own `handleError` implementation will only handle errors encountered during the initial shell render. If you encounter a rendering error during subsequent streamed rendering you will need to handle these errors manually since the React Router server has already sent the Response by that point. You can handle these errors in the `onError` callback function. -For `renderToPipeableStream`, you can handle these errors in the `onError` callback function. You will need to toggle a boolean in `onShellReady` so you know if the error was a shell rendering error (and can be ignored) or an async - -For an example, please refer to the default [`entry.server.tsx`][node-streaming-entry-server] for Node. +For an example, please refer to the default [`entry.server.tsx`][streaming-entry-server]. **Thrown Responses** @@ -160,5 +158,5 @@ Note that this does not handle thrown `Response` instances from your `loader`/`a [streaming]: ../../how-to/suspense [rendertopipeablestream]: https://react.dev/reference/react-dom/server/renderToPipeableStream [rendertoreadablestream]: https://react.dev/reference/react-dom/server/renderToReadableStream -[node-streaming-entry-server]: https://github.com/remix-run/react-router/blob/main/packages/react-router-dev/config/defaults/entry.server.node.tsx +[streaming-entry-server]: https://github.com/remix-run/react-router/blob/main/packages/react-router-dev/config/defaults/entry.server.tsx [templates-repo]: https://github.com/remix-run/react-router-templates diff --git a/integration/defer-test.ts b/integration/defer-test.ts index 945683bce3..a016b6abb6 100644 --- a/integration/defer-test.ts +++ b/integration/defer-test.ts @@ -35,7 +35,7 @@ function counterHtml(id: string, val: number) { return `

${val}

`; } -const deferredHTMLStartString = "