Skip to content

Commit bdeb576

Browse files
committed
Merge branch 'release-next'
2 parents ddf8e16 + a36c505 commit bdeb576

File tree

93 files changed

+2485
-1218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+2485
-1218
lines changed

CHANGELOG.md

Lines changed: 147 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,45 @@ We manage release notes in this file instead of the paginated Github Releases Pa
1313
<summary>Table of Contents</summary>
1414

1515
- [React Router Releases](#react-router-releases)
16+
- [v7.6.1](#v761)
17+
- [Patch Changes](#patch-changes)
18+
- [Unstable Changes](#unstable-changes)
1619
- [v7.6.0](#v760)
1720
- [What's Changed](#whats-changed)
1821
- [`routeDiscovery` Config Option](#routediscovery-config-option)
1922
- [Automatic Types for Future Flags](#automatic-types-for-future-flags)
2023
- [Minor Changes](#minor-changes)
21-
- [Patch Changes](#patch-changes)
22-
- [Unstable Changes](#unstable-changes)
24+
- [Patch Changes](#patch-changes-1)
25+
- [Unstable Changes](#unstable-changes-1)
2326
- [Changes by Package](#changes-by-package)
2427
- [v7.5.3](#v753)
25-
- [Patch Changes](#patch-changes-1)
28+
- [Patch Changes](#patch-changes-2)
2629
- [v7.5.2](#v752)
2730
- [Security Notice](#security-notice)
28-
- [Patch Changes](#patch-changes-2)
29-
- [v7.5.1](#v751)
3031
- [Patch Changes](#patch-changes-3)
31-
- [Unstable Changes](#unstable-changes-1)
32+
- [v7.5.1](#v751)
33+
- [Patch Changes](#patch-changes-4)
34+
- [Unstable Changes](#unstable-changes-2)
3235
- [v7.5.0](#v750)
3336
- [What's Changed](#whats-changed-1)
3437
- [`route.lazy` Object API](#routelazy-object-api)
3538
- [Minor Changes](#minor-changes-1)
36-
- [Patch Changes](#patch-changes-4)
37-
- [Unstable Changes](#unstable-changes-2)
39+
- [Patch Changes](#patch-changes-5)
40+
- [Unstable Changes](#unstable-changes-3)
3841
- [Changes by Package](#changes-by-package-1)
3942
- [v7.4.1](#v741)
4043
- [Security Notice](#security-notice-1)
41-
- [Patch Changes](#patch-changes-5)
42-
- [Unstable Changes](#unstable-changes-3)
43-
- [v7.4.0](#v740)
44-
- [Minor Changes](#minor-changes-2)
4544
- [Patch Changes](#patch-changes-6)
4645
- [Unstable Changes](#unstable-changes-4)
46+
- [v7.4.0](#v740)
47+
- [Minor Changes](#minor-changes-2)
48+
- [Patch Changes](#patch-changes-7)
49+
- [Unstable Changes](#unstable-changes-5)
4750
- [Changes by Package](#changes-by-package-2)
4851
- [v7.3.0](#v730)
4952
- [Minor Changes](#minor-changes-3)
50-
- [Patch Changes](#patch-changes-7)
51-
- [Unstable Changes](#unstable-changes-5)
53+
- [Patch Changes](#patch-changes-8)
54+
- [Unstable Changes](#unstable-changes-6)
5255
- [Client-side `context` (unstable)](#client-side-context-unstable)
5356
- [Middleware (unstable)](#middleware-unstable)
5457
- [Middleware `context` parameter](#middleware-context-parameter)
@@ -60,28 +63,28 @@ We manage release notes in this file instead of the paginated Github Releases Pa
6063
- [Prerendering with a SPA Fallback](#prerendering-with-a-spa-fallback)
6164
- [Allow a root `loader` in SPA Mode](#allow-a-root-loader-in-spa-mode)
6265
- [Minor Changes](#minor-changes-4)
63-
- [Patch Changes](#patch-changes-8)
64-
- [Unstable Changes](#unstable-changes-6)
66+
- [Patch Changes](#patch-changes-9)
67+
- [Unstable Changes](#unstable-changes-7)
6568
- [Split Route Modules (unstable)](#split-route-modules-unstable)
6669
- [Changes by Package](#changes-by-package-4)
6770
- [v7.1.5](#v715)
68-
- [Patch Changes](#patch-changes-9)
69-
- [v7.1.4](#v714)
7071
- [Patch Changes](#patch-changes-10)
71-
- [v7.1.3](#v713)
72+
- [v7.1.4](#v714)
7273
- [Patch Changes](#patch-changes-11)
73-
- [v7.1.2](#v712)
74+
- [v7.1.3](#v713)
7475
- [Patch Changes](#patch-changes-12)
75-
- [v7.1.1](#v711)
76+
- [v7.1.2](#v712)
7677
- [Patch Changes](#patch-changes-13)
78+
- [v7.1.1](#v711)
79+
- [Patch Changes](#patch-changes-14)
7780
- [v7.1.0](#v710)
7881
- [Minor Changes](#minor-changes-5)
79-
- [Patch Changes](#patch-changes-14)
82+
- [Patch Changes](#patch-changes-15)
8083
- [Changes by Package](#changes-by-package-5)
8184
- [v7.0.2](#v702)
82-
- [Patch Changes](#patch-changes-15)
83-
- [v7.0.1](#v701)
8485
- [Patch Changes](#patch-changes-16)
86+
- [v7.0.1](#v701)
87+
- [Patch Changes](#patch-changes-17)
8588
- [v7.0.0](#v700)
8689
- [Breaking Changes](#breaking-changes)
8790
- [Package Restructuring](#package-restructuring)
@@ -98,7 +101,7 @@ We manage release notes in this file instead of the paginated Github Releases Pa
98101
- [Major Changes (`react-router`)](#major-changes-react-router)
99102
- [Major Changes (`@react-router/*`)](#major-changes-react-router-1)
100103
- [Minor Changes](#minor-changes-6)
101-
- [Patch Changes](#patch-changes-17)
104+
- [Patch Changes](#patch-changes-18)
102105
- [Changes by Package](#changes-by-package-6)
103106
- [React Router v6 Releases](#react-router-v6-releases)
104107
- [v6.30.1](#v6301)
@@ -334,6 +337,125 @@ Date: YYYY-MM-DD
334337
**Full Changelog**: [`v7.X.Y...v7.X.Y`](https://github.com/remix-run/react-router/compare/[email protected]@7.X.Y)
335338
-->
336339

340+
## v7.6.1
341+
342+
Date: 2025-05-25
343+
344+
### Patch Changes
345+
346+
- `react-router` - Partially revert optimization added in `7.1.4` to reduce calls to `matchRoutes` because it surfaced other issues ([#13562](https://github.com/remix-run/react-router/pull/13562))
347+
- `react-router` - Update `Route.MetaArgs` to reflect that `data` can be potentially `undefined` ([#13563](https://github.com/remix-run/react-router/pull/13563))
348+
- This is primarily for cases where a route `loader` threw an error to it's own `ErrorBoundary`, but it also arises in the case of a 404 which renders the root `ErrorBoundary`/`meta` but the root `loader` did not run because not routes matched
349+
- `react-router` - Avoid initial fetcher execution 404 error when Lazy Route Discovery is interrupted by a navigation ([#13564](https://github.com/remix-run/react-router/pull/13564))
350+
- `react-router` - Properly `href` replaces splats `*` ([#13593](https://github.com/remix-run/react-router/pull/13593))
351+
- `href("/products/*", { "*": "/1/edit" }); // -> /products/1/edit`
352+
- `@react-router/architect` - Update `@architect/functions` from `^5.2.0` to `^7.0.0` ([#13556](https://github.com/remix-run/react-router/pull/13556))
353+
- `@react-router/dev` - Prevent typegen with route files that are outside the `app/` directory ([#12996](https://github.com/remix-run/react-router/pull/12996))
354+
- `@react-router/dev` - Add additional logging to `build` command output when cleaning assets from server build ([#13547](https://github.com/remix-run/react-router/pull/13547))
355+
- `@react-router/dev` - Don't clean assets from server build when `build.ssrEmitAssets` has been enabled in Vite config ([#13547](https://github.com/remix-run/react-router/pull/13547))
356+
- `@react-router/dev` - Fix typegen when same route is used at multiple paths ([#13574](https://github.com/remix-run/react-router/pull/13574))
357+
358+
- For example, `routes/route.tsx` is used at 4 different paths here:
359+
360+
```ts
361+
import { type RouteConfig, route } from "@react-router/dev/routes";
362+
export default [
363+
route("base/:base", "routes/base.tsx", [
364+
route("home/:home", "routes/route.tsx", { id: "home" }),
365+
route("changelog/:changelog", "routes/route.tsx", { id: "changelog" }),
366+
route("splat/*", "routes/route.tsx", { id: "splat" }),
367+
]),
368+
route("other/:other", "routes/route.tsx", { id: "other" }),
369+
] satisfies RouteConfig;
370+
```
371+
372+
- Previously, typegen would arbitrarily pick one of these paths to be the "winner" and generate types for the route module based on that path
373+
- Now, typegen creates unions as necessary for alternate paths for the same route file
374+
375+
- `@react-router/dev` - Better types for `params` ([#13543](https://github.com/remix-run/react-router/pull/13543))
376+
377+
- For example:
378+
379+
```ts
380+
// routes.ts
381+
import { type RouteConfig, route } from "@react-router/dev/routes";
382+
383+
export default [
384+
route("parent/:p", "routes/parent.tsx", [
385+
route("route/:r", "routes/route.tsx", [
386+
route("child1/:c1a/:c1b", "routes/child1.tsx"),
387+
route("child2/:c2a/:c2b", "routes/child2.tsx"),
388+
]),
389+
]),
390+
] satisfies RouteConfig;
391+
```
392+
393+
- Previously, `params` for `routes/route` were calculated as `{ p: string, r: string }`.
394+
- This incorrectly ignores params that could come from child routes
395+
- If visiting `/parent/1/route/2/child1/3/4`, the actual params passed to `routes/route` will have a type of `{ p: string, r: string, c1a: string, c1b: string }`
396+
- Now, `params` are aware of child routes and autocompletion will include child params as optionals:
397+
398+
```ts
399+
params.|
400+
// ^ cursor is here and you ask for autocompletion
401+
// p: string
402+
// r: string
403+
// c1a?: string
404+
// c1b?: string
405+
// c2a?: string
406+
// c2b?: string
407+
```
408+
409+
- You can also narrow the types for `params` as it is implemented as a normalized union of params for each page that includes `routes/route`:
410+
411+
```ts
412+
if (typeof params.c1a === 'string') {
413+
params.|
414+
// ^ cursor is here and you ask for autocompletion
415+
// p: string
416+
// r: string
417+
// c1a: string
418+
// c1b: string
419+
}
420+
```
421+
422+
- `@react-router/dev` - Fix `href` for optional segments ([#13595](https://github.com/remix-run/react-router/pull/13595))
423+
424+
- Type generation now expands paths with optionals into their corresponding non-optional paths
425+
- For example, the path `/user/:id?` gets expanded into `/user` and `/user/:id` to more closely model visitable URLs
426+
- `href` then uses these expanded (non-optional) paths to construct type-safe paths for your app:
427+
428+
```ts
429+
// original: /user/:id?
430+
// expanded: /user & /user/:id
431+
href("/user"); // ✅
432+
href("/user/:id", { id: 1 }); // ✅
433+
```
434+
435+
- This becomes even more important for static optional paths where there wasn't a good way to indicate whether the optional should be included in the resulting path:
436+
437+
```ts
438+
// original: /products/:id/detail?
439+
440+
// before
441+
href("/products/:id/detail?"); // ❌ How can we tell `href` to include or omit `detail?` segment with a complex API?
442+
443+
// now
444+
// expanded: /products/:id & /products/:id/detail
445+
href("/product/:id"); // ✅
446+
href("/product/:id/detail"); // ✅
447+
```
448+
449+
### Unstable Changes
450+
451+
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
452+
453+
- `@react-router/dev` - Renamed internal `react-router/route-module` export to `react-router/internal` ([#13543](https://github.com/remix-run/react-router/pull/13543))
454+
- `@react-router/dev` - Removed `Info` export from generated `+types/*` files ([#13543](https://github.com/remix-run/react-router/pull/13543))
455+
- `@react-router/dev` - Normalize dirent entry path across node versions when generating SRI manifest ([#13591](https://github.com/remix-run/react-router/pull/13591))
456+
457+
**Full Changelog**: [`v7.6.0...v7.6.1`](https://github.com/remix-run/react-router/compare/[email protected]@7.6.1)
458+
337459
## v7.6.0
338460

339461
Date: 2025-05-08

contributors.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
- Brendonovich
5555
- briankb
5656
- BrianT1414
57+
- Bricklou
5758
- brockross
5859
- brookslybrand
5960
- brophdawg11
@@ -269,6 +270,7 @@
269270
- parveen232
270271
- paulsmithkc
271272
- pavsoldatov
273+
- pawelblaszczyk5
272274
- pcattori
273275
- penx
274276
- petersendidit
@@ -377,6 +379,7 @@
377379
- vonagam
378380
- WalkAlone0325
379381
- whxhlgy
382+
- wilcoxmd
380383
- willemarcel
381384
- williamsdyyz
382385
- willsawyerrrr

docs/start/framework/route-module.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,30 @@ export default function Root() {
311311

312312
Route meta defines meta tags to be rendered in the `<Meta />` component, usually placed in the `<head>`.
313313

314+
<docs-warning>
315+
316+
Since React 19, [using the built-in `<meta>` element](https://react.dev/reference/react-dom/components/meta) is recommended over the use of the route module's `meta` export.
317+
318+
Here is an example of how to use it and the `<title>` element:
319+
320+
```tsx
321+
export default function MyRoute() {
322+
return (
323+
<div>
324+
<title>Very cool app</title>
325+
<meta property="og:title" content="Very cool app" />
326+
<meta
327+
name="description"
328+
content="This app is the best"
329+
/>
330+
{/* The rest of your route content... */}
331+
</div>
332+
);
333+
}
334+
```
335+
336+
</docs-warning>
337+
314338
```tsx filename=app/product.tsx
315339
export function meta() {
316340
return [

0 commit comments

Comments
 (0)