Skip to content

Commit

Permalink
Merge branch 'main' into release-next
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Aug 9, 2023
2 parents c863ab9 + 39ab0a8 commit d6d0e5b
Show file tree
Hide file tree
Showing 23 changed files with 1,980 additions and 41 deletions.
8 changes: 6 additions & 2 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,19 @@ You may need to make changes to a pre-release prior to publishing a final stable
- Commit the edited pre-release file along with any unpublished changesets, and push the `release-*` branch to GitHub.
- 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.
- Review the updated `CHANGELOG` files and make any adjustments necessary.
- `find packages -name 'CHANGELOG.md' -mindepth 2 -maxdepth 2 -exec code {} \;`
- We should remove the changelogs for all pre-releases ahead of publishing the stable version.
- [TODO: We should automate this]
- Prepare the GitHub release notes
- Copy the relevant changelog entries from all packages into the Release Notes and adjust accordingly, matching the format used by prior releases
- Merge the PR into the `release-*` branch.
- Once the PR is merged, the release workflow will publish the updated packages to npm.
- Once the release is published:
- merge the `release-*` branch into `main` and push it up to GitHub
- merge the `release-*` branch into `dev` and push it up to GitHub
- Pull the latest `release-*` branch containing the PR you just merged
- Merge the `release-*` branch into `main` **using a non-fast-forward merge** and push it up to GitHub
- `git checkout main; git merge --no-ff release-next`
- Merge the `release-*` branch into `dev` **using a non-fast-forward merge** and push it up to GitHub
- `git checkout dev; git merge --no-ff release-next`
- Convert the `react-router@6.x.y` tag to a Release on GitHub with the name `v6.x.y`

### Hotfix releases
Expand Down
6 changes: 5 additions & 1 deletion contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- antonmontrezor
- appden
- arjunyel
- arka1002
- arnassavickas
- aroyan
- avipatel97
Expand Down Expand Up @@ -87,6 +88,7 @@
- infoxicator
- IsaiStormBlesed
- Isammoc
- istarkov
- ivanjeremic
- ivanjonas
- Ivanrenes
Expand Down Expand Up @@ -120,6 +122,7 @@
- koojaa
- KostiantynPopovych
- KutnerUri
- kylegirard
- landisdesign
- latin-1
- lequangdongg
Expand Down Expand Up @@ -160,6 +163,7 @@
- ms10596
- ned-park
- nilubisan
- Nismit
- nnhjs
- noisypigeon
- Obi-Dann
Expand All @@ -180,6 +184,7 @@
- ryanflorence
- ryanhiebert
- sanketshah19
- sbolel
- scarf005
- senseibarni
- sergiodxa
Expand Down Expand Up @@ -226,6 +231,5 @@
- zheng-chuang
- swalker326
- smithki
- istarkov
- louis-young
- robbtraister
2 changes: 1 addition & 1 deletion docs/components/link.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ A relative `<Link to>` value (that does not begin with `/`) resolves relative to

## `relative`

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`:
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"`:

```jsx
// Contact and EditContact do not share additional UI layout
Expand Down
20 changes: 4 additions & 16 deletions docs/components/nav-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,17 @@ You can pass a render prop as children to customize the content of the `<NavLink

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.

Without the end prop, this link is always active because every URL matches `/`.

```tsx
<NavLink to="/">Home</NavLink>
```

To match the URL "to the end" of `to`, use `end`:

```tsx
<NavLink to="/" end>
Home
</NavLink>
```

Now this link will only be active at `"/"`. This works for paths with more segments as well:

| Link | URL | isActive |
| ----------------------------- | ------------ | -------- |
| `<NavLink to="/tasks" />` | `/tasks` | true |
| `<NavLink to="/tasks" />` | `/tasks/123` | true |
| `<NavLink to="/tasks" end />` | `/tasks` | true |
| `<NavLink to="/tasks" end />` | `/tasks/123` | false |

**A note on links to the root route**

`<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.

## `caseSensitive`

Adding the `caseSensitive` prop changes the matching logic to make it case sensitive.
Expand Down
77 changes: 58 additions & 19 deletions docs/hooks/use-navigate.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@ title: useNavigate

# `useNavigate`

<details>
<summary>Type declaration</summary>

```tsx
declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
(to: To, options?: NavigateOptions): void;
(delta: number): void;
}

interface NavigateOptions {
replace?: boolean;
state?: any;
preventScrollReset?: boolean;
relative?: RelativeRoutingType;
}

type RelativeRoutingType = "route" | "path";
```

</details>

<docs-warning>It's usually better to use [`redirect`][redirect] in [`loaders`][loaders] and [`actions`][actions] than this hook</docs-warning>

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

## Type Declaration
The `navigate` function has two signatures:

```tsx
declare function useNavigate(): NavigateFunction;
- 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
- Pass the delta you want to go in the history stack. For example, `navigate(-1)` is equivalent to hitting the back button

interface NavigateFunction {
(
to: To,
options?: {
replace?: boolean;
state?: any;
relative?: RelativeRoutingType;
}
): void;
(delta: number): void;
}
```
## `options.replace`

The `navigate` function has two signatures:
Specifying `replace: true` will cause the navigation will replace the current entry in the history stack instead of adding a new one.

## `options.state`

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

If using `replace: true`, the navigation will replace the current entry in the history stack instead of adding a new one.
## `options.preventScrollReset`

When using the [`<ScrollRestoration>`][scrollrestoration] component, you can disable resetting the scroll to the top of the page via `options.preventScrollReset`

## `options.relative`

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"`:

```jsx
// Contact and EditContact do not share additional UI layout
<Route path="/" element={<Layout />}>
<Route path="contacts/:id" element={<Contact />} />
<Route
path="contacts/:id/edit"
element={<EditContact />}
/>
</Route>;

function EditContact() {
// Since Contact is not a parent of EditContact we need to go up one level
// in the path, instead of one level in the Route hierarchy
navigate("..", { relative: "path" });
}
```

[link]: ../components/link
[redirect]: ../fetch/redirect
[loaders]: ../route/loader
[actions]: ../route/action
[history-state]: https://developer.mozilla.org/en-US/docs/Web/API/History/state
[scrollrestoration]: ../components/scroll-restoration
2 changes: 1 addition & 1 deletion docs/hooks/use-outlet-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function Child() {

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:

```tsx filename=src/routes/dashboard.tsx lines=[13, 19]
```tsx filename=src/routes/dashboard.tsx lines=[13,19]
import * as React from "react";
import type { User } from "./types";
import { Outlet, useOutletContext } from "react-router-dom";
Expand Down
2 changes: 1 addition & 1 deletion docs/hooks/use-submit.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,4 @@ submit(null, {
Because submissions are navigations, the options may also contain the other navigation related props from [`<Form>`][form] such as `replace`, `state`, `preventScrollReset`, `relative`, etc.

[pickingarouter]: ../routers/picking-a-router
[form]: ../components/form.md
[form]: ../components/form
4 changes: 4 additions & 0 deletions docs/routers/create-browser-router.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ This is the recommended router for all React Router web projects. It uses the [D

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

<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>

```tsx lines=[4,11-24]
import * as React from "react";
import * as ReactDOM from "react-dom";
Expand Down Expand Up @@ -125,3 +127,5 @@ Useful for environments like browser devtool plugins or testing to use a differe
[routes]: ../components/routes
[historyapi]: https://developer.mozilla.org/en-US/docs/Web/API/History
[api-development-strategy]: ../guides/api-development-strategy
[remixing-react-router]: https://remix.run/blog/remixing-react-router
[when-to-fetch]: https://www.youtube.com/watch?v=95B8mnhzoCM
4 changes: 4 additions & 0 deletions docs/routers/router-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ interface RouterProviderProps {

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

<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>

```jsx lines=[24]
import {
createBrowserRouter,
Expand Down Expand Up @@ -83,3 +85,5 @@ function App() {

[picking-a-router]: ./picking-a-router
[api-development-strategy]: ../guides/api-development-strategy
[remixing-react-router]: https://remix.run/blog/remixing-react-router
[when-to-fetch]: https://www.youtube.com/watch?v=95B8mnhzoCM
5 changes: 5 additions & 0 deletions examples/auth-router-provider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
4 changes: 4 additions & 0 deletions examples/auth-router-provider/.stackblitzrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"installDependencies": true,
"startCommand": "npm run dev"
}
28 changes: 28 additions & 0 deletions examples/auth-router-provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: Authentication (using RouterProvider)
toc: false
---

# Auth Example (using RouterProvider)

This example demonstrates how to restrict access to routes to authenticated users when using `<RouterProvider>`.

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.

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.

Be sure to pay attention to the following features in this example:

- The use of a standalone object _outside of the React tree_ that manages our authentication state
- The use of `loader` functions to check for user authentication
- The use of `redirect` from the `/protected` `loader` when the user is not logged in
- The use of a `<Form>` and an `action` to perform the login
- 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
- 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
- The use of a `<fetcher.Form>` and an `action` to perform the logout

## Preview

Open this example on [StackBlitz](https://stackblitz.com):

[![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)
12 changes: 12 additions & 0 deletions examples/auth-router-provider/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Router - Auth Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading

0 comments on commit d6d0e5b

Please sign in to comment.