Skip to content

Commit d6d0e5b

Browse files
committed
Merge branch 'main' into release-next
2 parents c863ab9 + 39ab0a8 commit d6d0e5b

23 files changed

+1980
-41
lines changed

DEVELOPMENT.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,19 @@ You may need to make changes to a pre-release prior to publishing a final stable
4141
- Commit the edited pre-release file along with any unpublished changesets, and push the `release-*` branch to GitHub.
4242
- Wait for the release workflow to finish. The Changesets action in the workflow will open a PR that will increment all versions and generate the changelogs for the stable release.
4343
- Review the updated `CHANGELOG` files and make any adjustments necessary.
44+
- `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;`
4445
- We should remove the changelogs for all pre-releases ahead of publishing the stable version.
4546
- [TODO: We should automate this]
4647
- Prepare the GitHub release notes
4748
- Copy the relevant changelog entries from all packages into the Release Notes and adjust accordingly, matching the format used by prior releases
4849
- Merge the PR into the `release-*` branch.
4950
- Once the PR is merged, the release workflow will publish the updated packages to npm.
5051
- Once the release is published:
51-
- merge the `release-*` branch into `main` and push it up to GitHub
52-
- merge the `release-*` branch into `dev` and push it up to GitHub
52+
- Pull the latest `release-*` branch containing the PR you just merged
53+
- Merge the `release-*` branch into `main` **using a non-fast-forward merge** and push it up to GitHub
54+
- `git checkout main; git merge --no-ff release-next`
55+
- Merge the `release-*` branch into `dev` **using a non-fast-forward merge** and push it up to GitHub
56+
- `git checkout dev; git merge --no-ff release-next`
5357
- Convert the `react-router@6.x.y` tag to a Release on GitHub with the name `v6.x.y`
5458

5559
### Hotfix releases

contributors.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- antonmontrezor
1919
- appden
2020
- arjunyel
21+
- arka1002
2122
- arnassavickas
2223
- aroyan
2324
- avipatel97
@@ -87,6 +88,7 @@
8788
- infoxicator
8889
- IsaiStormBlesed
8990
- Isammoc
91+
- istarkov
9092
- ivanjeremic
9193
- ivanjonas
9294
- Ivanrenes
@@ -120,6 +122,7 @@
120122
- koojaa
121123
- KostiantynPopovych
122124
- KutnerUri
125+
- kylegirard
123126
- landisdesign
124127
- latin-1
125128
- lequangdongg
@@ -160,6 +163,7 @@
160163
- ms10596
161164
- ned-park
162165
- nilubisan
166+
- Nismit
163167
- nnhjs
164168
- noisypigeon
165169
- Obi-Dann
@@ -180,6 +184,7 @@
180184
- ryanflorence
181185
- ryanhiebert
182186
- sanketshah19
187+
- sbolel
183188
- scarf005
184189
- senseibarni
185190
- sergiodxa
@@ -226,6 +231,5 @@
226231
- zheng-chuang
227232
- swalker326
228233
- smithki
229-
- istarkov
230234
- louis-young
231235
- robbtraister

docs/components/link.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ A relative `<Link to>` value (that does not begin with `/`) resolves relative to
6464

6565
## `relative`
6666

67-
By default, links are relative to the route hierarchy, so `..` will go up one `Route` level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you'd prefer to use relative _path_ routing. You can opt into this behavior with `relative`:
67+
By default, links are relative to the route hierarchy (`relative="route"`), so `..` will go up one `Route` level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you'd prefer to use relative _path_ routing. You can opt into this behavior with `relative="path"`:
6868

6969
```jsx
7070
// Contact and EditContact do not share additional UI layout

docs/components/nav-link.md

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,29 +84,17 @@ You can pass a render prop as children to customize the content of the `<NavLink
8484

8585
The `end` prop changes the matching logic for the `active` and `pending` states to only match to the "end" of the NavLink's `to` path. If the URL is longer than `to`, it will no longer be considered active.
8686

87-
Without the end prop, this link is always active because every URL matches `/`.
88-
89-
```tsx
90-
<NavLink to="/">Home</NavLink>
91-
```
92-
93-
To match the URL "to the end" of `to`, use `end`:
94-
95-
```tsx
96-
<NavLink to="/" end>
97-
Home
98-
</NavLink>
99-
```
100-
101-
Now this link will only be active at `"/"`. This works for paths with more segments as well:
102-
10387
| Link | URL | isActive |
10488
| ----------------------------- | ------------ | -------- |
10589
| `<NavLink to="/tasks" />` | `/tasks` | true |
10690
| `<NavLink to="/tasks" />` | `/tasks/123` | true |
10791
| `<NavLink to="/tasks" end />` | `/tasks` | true |
10892
| `<NavLink to="/tasks" end />` | `/tasks/123` | false |
10993

94+
**A note on links to the root route**
95+
96+
`<NavLink to="/">` is an exceptional case because _every_ URL matches `/`. To avoid this matching every single route by default, it effectively ignores the `end` prop and only matches when you're at the root route.
97+
11098
## `caseSensitive`
11199

112100
Adding the `caseSensitive` prop changes the matching logic to make it case sensitive.

docs/hooks/use-navigate.md

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@ title: useNavigate
44

55
# `useNavigate`
66

7+
<details>
8+
<summary>Type declaration</summary>
9+
10+
```tsx
11+
declare function useNavigate(): NavigateFunction;
12+
13+
interface NavigateFunction {
14+
(to: To, options?: NavigateOptions): void;
15+
(delta: number): void;
16+
}
17+
18+
interface NavigateOptions {
19+
replace?: boolean;
20+
state?: any;
21+
preventScrollReset?: boolean;
22+
relative?: RelativeRoutingType;
23+
}
24+
25+
type RelativeRoutingType = "route" | "path";
26+
```
27+
28+
</details>
29+
730
<docs-warning>It's usually better to use [`redirect`][redirect] in [`loaders`][loaders] and [`actions`][actions] than this hook</docs-warning>
831

932
The `useNavigate` hook returns a function that lets you navigate programmatically, for example in an effect:
@@ -24,31 +47,47 @@ function useLogoutTimer() {
2447
}
2548
```
2649

27-
## Type Declaration
50+
The `navigate` function has two signatures:
2851

29-
```tsx
30-
declare function useNavigate(): NavigateFunction;
52+
- Either pass a `To` value (same type as `<Link to>`) with an optional second `options` argument (similar to the props you can pass to [`<Link>`][link]), or
53+
- Pass the delta you want to go in the history stack. For example, `navigate(-1)` is equivalent to hitting the back button
3154

32-
interface NavigateFunction {
33-
(
34-
to: To,
35-
options?: {
36-
replace?: boolean;
37-
state?: any;
38-
relative?: RelativeRoutingType;
39-
}
40-
): void;
41-
(delta: number): void;
42-
}
43-
```
55+
## `options.replace`
4456

45-
The `navigate` function has two signatures:
57+
Specifying `replace: true` will cause the navigation will replace the current entry in the history stack instead of adding a new one.
58+
59+
## `options.state`
4660

47-
- Either pass a `To` value (same type as `<Link to>`) with an optional second `{ replace, state }` arg or
48-
- Pass the delta you want to go in the history stack. For example, `navigate(-1)` is equivalent to hitting the back button.
61+
You may include an optional state value in to store in [history state][history-state]
4962

50-
If using `replace: true`, the navigation will replace the current entry in the history stack instead of adding a new one.
63+
## `options.preventScrollReset`
64+
65+
When using the [`<ScrollRestoration>`][scrollrestoration] component, you can disable resetting the scroll to the top of the page via `options.preventScrollReset`
66+
67+
## `options.relative`
68+
69+
By default, navigation is relative to the route hierarchy (`relative: "route"`), so `..` will go up one `Route` level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you'd prefer to use relative _path_ routing. You can opt into this behavior with `relative: "path"`:
70+
71+
```jsx
72+
// Contact and EditContact do not share additional UI layout
73+
<Route path="/" element={<Layout />}>
74+
<Route path="contacts/:id" element={<Contact />} />
75+
<Route
76+
path="contacts/:id/edit"
77+
element={<EditContact />}
78+
/>
79+
</Route>;
80+
81+
function EditContact() {
82+
// Since Contact is not a parent of EditContact we need to go up one level
83+
// in the path, instead of one level in the Route hierarchy
84+
navigate("..", { relative: "path" });
85+
}
86+
```
5187

88+
[link]: ../components/link
5289
[redirect]: ../fetch/redirect
5390
[loaders]: ../route/loader
5491
[actions]: ../route/action
92+
[history-state]: https://developer.mozilla.org/en-US/docs/Web/API/History/state
93+
[scrollrestoration]: ../components/scroll-restoration

docs/hooks/use-outlet-context.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function Child() {
3636

3737
If you're using TypeScript, we recommend the parent component provide a custom hook for accessing the context value. This makes it easier for consumers to get nice typings, control consumers, and know who's consuming the context value. Here's a more realistic example:
3838

39-
```tsx filename=src/routes/dashboard.tsx lines=[13, 19]
39+
```tsx filename=src/routes/dashboard.tsx lines=[13,19]
4040
import * as React from "react";
4141
import type { User } from "./types";
4242
import { Outlet, useOutletContext } from "react-router-dom";

docs/hooks/use-submit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,4 @@ submit(null, {
153153
Because submissions are navigations, the options may also contain the other navigation related props from [`<Form>`][form] such as `replace`, `state`, `preventScrollReset`, `relative`, etc.
154154

155155
[pickingarouter]: ../routers/picking-a-router
156-
[form]: ../components/form.md
156+
[form]: ../components/form

docs/routers/create-browser-router.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ This is the recommended router for all React Router web projects. It uses the [D
99

1010
It also enables the v6.4 data APIs like [loaders][loader], [actions][action], [fetchers][fetcher] and more.
1111

12+
<docs-info>Due to the decoupling of fetching and rendering in the design of the data APIs, you should create your router outside of the React tree with a statically defined set of routes. For more information on this design, please see the [Remixing React Router][remixing-react-router] blog post and the [When to Fetch][when-to-fetch] conference talk.</docs-info>
13+
1214
```tsx lines=[4,11-24]
1315
import * as React from "react";
1416
import * as ReactDOM from "react-dom";
@@ -125,3 +127,5 @@ Useful for environments like browser devtool plugins or testing to use a differe
125127
[routes]: ../components/routes
126128
[historyapi]: https://developer.mozilla.org/en-US/docs/Web/API/History
127129
[api-development-strategy]: ../guides/api-development-strategy
130+
[remixing-react-router]: https://remix.run/blog/remixing-react-router
131+
[when-to-fetch]: https://www.youtube.com/watch?v=95B8mnhzoCM

docs/routers/router-provider.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ interface RouterProviderProps {
2424

2525
All [data router][picking-a-router] objects are passed to this component to render your app and enable the rest of the data APIs.
2626

27+
<docs-info>Due to the decoupling of fetching and rendering in the design of the data APIs, you should create your router outside of the React tree with a statically defined set of routes. For more information on this design, please see the [Remixing React Router][remixing-react-router] blog post and the [When to Fetch][when-to-fetch] conference talk.</docs-info>
28+
2729
```jsx lines=[24]
2830
import {
2931
createBrowserRouter,
@@ -83,3 +85,5 @@ function App() {
8385

8486
[picking-a-router]: ./picking-a-router
8587
[api-development-strategy]: ../guides/api-development-strategy
88+
[remixing-react-router]: https://remix.run/blog/remixing-react-router
89+
[when-to-fetch]: https://www.youtube.com/watch?v=95B8mnhzoCM
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"installDependencies": true,
3+
"startCommand": "npm run dev"
4+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
title: Authentication (using RouterProvider)
3+
toc: false
4+
---
5+
6+
# Auth Example (using RouterProvider)
7+
8+
This example demonstrates how to restrict access to routes to authenticated users when using `<RouterProvider>`.
9+
10+
The primary difference compared to how authentication was handled in `BrowserRouter` is that since `RouterProvider` decouples fetching from rendering, we can no longer rely on React context and/or hooks to get our user authentication status. We need access to this information outside of the React tree so we can use it in our route `loader` and `action` functions.
11+
12+
For some background information on this design choice, please check out the [Remixing React Router](https://remix.run/blog/remixing-react-router) blog post and Ryan's [When to Fetch](https://www.youtube.com/watch?v=95B8mnhzoCM) talk from Reactathon.
13+
14+
Be sure to pay attention to the following features in this example:
15+
16+
- The use of a standalone object _outside of the React tree_ that manages our authentication state
17+
- The use of `loader` functions to check for user authentication
18+
- The use of `redirect` from the `/protected` `loader` when the user is not logged in
19+
- The use of a `<Form>` and an `action` to perform the login
20+
- The use of a `from` search param and a `redirectTo` hidden input to preserve the previous location so you can send the user there after they authenticate
21+
- The use of `<Form replace>` to replace the `/login` route in the history stack so the user doesn't return to the login page when clicking the back button after logging in
22+
- The use of a `<fetcher.Form>` and an `action` to perform the logout
23+
24+
## Preview
25+
26+
Open this example on [StackBlitz](https://stackblitz.com):
27+
28+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/remix-run/react-router/tree/main/examples/auth-router-provider?file=src/App.tsx)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>React Router - Auth Example</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)