Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from remix-run:main #17

Merged
merged 44 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c8fd138
docs: adjusted READMEs for the api docs generator
ryanflorence Nov 19, 2024
f664ea8
docs: update remix AppLoadContext migration (#12313)
pcattori Nov 19, 2024
6819a73
Update basic template to 7.0.0-pre.6 (#12316)
markdalgleish Nov 19, 2024
50d8bf1
docs: added SPA how-to
ryanflorence Nov 19, 2024
2f45fd1
typo
ryanflorence Nov 19, 2024
1259f9c
wordsmith
ryanflorence Nov 19, 2024
618da2c
docs updates
ryanflorence Nov 19, 2024
5142108
docs docs docs
ryanflorence Nov 20, 2024
7f0ef8f
docs wordsmithing
ryanflorence Nov 20, 2024
06e98c3
typegen: headers (#12318)
pcattori Nov 20, 2024
f41e9d8
docs: bit more on headers
ryanflorence Nov 20, 2024
eadc804
Framework adoption guides (#12317)
brookslybrand Nov 20, 2024
3963006
widen descendant route matching warning (#12324)
ryanflorence Nov 20, 2024
f79bf3d
docs: remove old routing conventions from file uploads doc (#12323)
brookslybrand Nov 20, 2024
20899a0
docs: remove warning from component-routes.md
brookslybrand Nov 20, 2024
8117606
move ssr: true from vite.config to react-router.config in basic template
brookslybrand Nov 20, 2024
11ae512
docs: error boundaries
ryanflorence Nov 20, 2024
43c5387
docs: added error reporting
ryanflorence Nov 20, 2024
846800a
Add decision doc for `react-router.config.ts` (#12330)
markdalgleish Nov 21, 2024
af0acf1
Rename `compiler` playgrounds to `framework` (#12329)
markdalgleish Nov 21, 2024
10a1eff
Update `RouteConfig` type description (#12333)
markdalgleish Nov 21, 2024
d0ac7ba
Fix typegen watcher leak on dev restart (#12331)
markdalgleish Nov 21, 2024
9272911
fix: pass route error to errorboundary as a prop (#12338)
pcattori Nov 21, 2024
3f102fc
docs: cleanup small grammar mistakes and make how-tos more similar
brookslybrand Nov 21, 2024
530d7b5
docs: fix broken links (#12336)
vdusart Nov 21, 2024
0fb15a6
docs: Framework Adoption from RouterProvider (#12339)
brookslybrand Nov 21, 2024
65c0e3b
poop!
ryanflorence Nov 21, 2024
a02996d
docs: bring your own bundler
ryanflorence Nov 21, 2024
845fb13
Add `dev/config` entry to TypeDoc config (#12332)
markdalgleish Nov 21, 2024
b98209d
docs: special files (#12340)
brookslybrand Nov 21, 2024
f763fd2
Update default create-react-router template (#12342)
markdalgleish Nov 22, 2024
d7dc44a
Merge branch 'release-next' into dev
mjackson Nov 22, 2024
fd6c297
chore: format
remix-run-bot Nov 22, 2024
27de8e2
fix broken link in the home page of dev branch (#12343)
ytori Nov 22, 2024
acf3f77
Merge branch 'main' into release-next
pcattori Nov 22, 2024
10cd35e
Enter prerelease mode
pcattori Nov 22, 2024
32b0a84
exit pre-release mode (v7.0.1)
pcattori Nov 22, 2024
202825c
chore: Update version for release (#12347)
github-actions[bot] Nov 22, 2024
b5f2e29
Merge branch 'release-next'
pcattori Nov 22, 2024
c0e5b16
chore: format
remix-run-bot Nov 22, 2024
6c87e2b
remove references to obsoleted typescript plugin
pcattori Nov 22, 2024
4fa0d2d
remove TOC references to non-existent sections
pcattori Nov 22, 2024
6ba3738
replace vite plugin config w/ react-router.config.ts
pcattori Nov 22, 2024
2a20ec3
docs: fix some broken links and prerelease references
brookslybrand Nov 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ body:
Before you ask a question, here are some resources to get help first:

- Read the docs: https://reactrouter.com
- Check out the list of frequently asked questions: https://reactrouter.com/start/faq
- Explore examples: https://reactrouter.com/start/examples
- Check out the list of frequently asked questions: https://reactrouter.com/main/start/faq
- Explore examples: https://reactrouter.com/main/start/examples
- Ask in chat: https://rmx.as/discord
- Look for/ask questions on Stack Overflow: https://stackoverflow.com/questions/tagged/react-router

Expand Down
156 changes: 13 additions & 143 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ We manage release notes in this file instead of the paginated Github Releases Pa
- [Other Notable Changes](#other-notable-changes)
- [`routes.ts`](#routests)
- [Typesafety improvements](#typesafety-improvements)
- [Setup](#setup)
- [`typegen` command](#typegen-command)
- [TypeScript plugin](#typescript-plugin)
- [VSCode](#vscode)
- [Troubleshooting](#troubleshooting)
- [Prerendering](#prerendering)
- [Major Changes (`react-router`)](#major-changes-react-router)
- [Major Changes (`@react-router/*`)](#major-changes-react-router-1)
Expand Down Expand Up @@ -334,29 +329,26 @@ For Remix consumers migrating to React Router, the `vitePlugin` and `cloudflareD
+import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare";
```

**Removed Vite Plugin `manifest` option**
**Removed `manifest` option**

For Remix consumers migrating to React Router, the Vite plugin's `manifest` option has been removed. The `manifest` option been superseded by the more powerful `buildEnd` hook since it's passed the `buildManifest` argument. You can still write the build manifest to disk if needed, but you'll most likely find it more convenient to write any logic depending on the build manifest within the `buildEnd` hook itself. ([#11573](https://github.com/remix-run/react-router/pull/11573))

If you were using the `manifest` option, you can replace it with a `buildEnd` hook that writes the manifest to disk like this:

```js
import { reactRouter } from "@react-router/dev/vite";
// react-router.config.ts
import { type Config } from "@react-router/dev/config";
import { writeFile } from "node:fs/promises";

export default {
plugins: [
reactRouter({
async buildEnd({ buildManifest }) {
await writeFile(
"build/manifest.json",
JSON.stringify(buildManifest, null, 2),
"utf-8"
);
},
}),
],
};
async buildEnd({ buildManifest }) {
await writeFile(
"build/manifest.json",
JSON.stringify(buildManifest, null, 2),
"utf-8"
);
},
} satisfies Config;
```

#### Exposed Router Promises
Expand Down Expand Up @@ -470,131 +462,9 @@ Also note that, if you were using Remix's `routes` option to define config-based

#### Typesafety improvements

React Router now generates types for each of your route modules and passes typed props to route module component exports ([#11961](https://github.com/remix-run/react-router/pull/11961), [#12019](https://github.com/remix-run/react-router/pull/12019)). You can access those types by importing them from `./+types.<route filename without extension>`.

For example:

```ts
// app/routes/product.tsx
import type * as Route from "./+types.product";

export function loader({ params }: Route.LoaderArgs) {}

export default function Component({ loaderData }: Route.ComponentProps) {}
```

This initial implementation targets type inference for:

- `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
- `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
- `ActionData` : Action data from `action` and/or `clientAction` within your route module

These types are then used to create types for route export args and props:

- `LoaderArgs`
- `ClientLoaderArgs`
- `ActionArgs`
- `ClientActionArgs`
- `HydrateFallbackProps`
- `ComponentProps` (for the `default` export)
- `ErrorBoundaryProps`

In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc.

We also plan to generate types for typesafe `Link`s:

```tsx
<Link to="/products/:id" params={{ id: 1 }} />
// ^^^^^^^^^^^^^ ^^^^^^^^^
// typesafe `to` and `params` based on the available routes in your app
```

##### Setup

React Router will generate types into a `.react-router/` directory at the root of your app. This directory is fully managed by React Router and is derived based on your route config (`routes.ts`).

👉 **Add `.react-router/` to `.gitignore`**

```txt
.react-router
```

You should also ensure that generated types for routes are always present before running typechecking, especially for running typechecking in CI.

👉 **Add `react-router typegen` to your `typecheck` command in `package.json`**

```json
{
"scripts": {
"typecheck": "react-router typegen && tsc"
}
}
```

To get TypeScript to use those generated types, you'll need to add them to `include` in `tsconfig.json`. And to be able to import them as if they files next to your route modules, you'll also need to configure `rootDirs`.

👉 **Configure `tsconfig.json` for generated types**

```json
{
"include": [".react-router/types/**/*"],
"compilerOptions": {
"rootDirs": [".", "./.react-router/types"]
}
}
```

##### `typegen` command

You can manually generate types with the new `typegen` command:

```sh
react-router typegen
```

However, manual type generation is tedious and types can get out of sync quickly if you ever forget to run `typegen`. Instead, we recommend that you setup our new TypeScript plugin which will automatically generate fresh types whenever routes change. That way, you'll always have up-to-date types.

##### TypeScript plugin

To get automatic type generation, you can use our new TypeScript plugin.

👉 **Add the TypeScript plugin to `tsconfig.json`**

```json
{
"compilerOptions": {
"plugins": [{ "name": "@react-router/dev" }]
}
}
```

We plan to add some other goodies to our TypeScript plugin soon, including:

- Automatic `jsdoc` for route exports that include links to official docs
- Autocomplete for route exports
- Warnings for non-HMR compliant exports

###### VSCode

TypeScript looks for plugins registered in `tsconfig.json` in the local `node_modules/`,
but VSCode ships with its own copy of TypeScript that is installed outside of your project.
For TypeScript plugins to work, you'll need to tell VSCode to use the local workspace version of TypeScript.

👉 **Ensure that VSCode is using the workspace version of TypeScript**

This should already be set up for you by a `.vscode/settings.json`:

```json
{
"typescript.tsdk": "node_modules/typescript/lib"
}
```

Alternatively, you can open up any TypeScript file and use <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>P</kbd> to find `Select TypeScript Version` and then select `Use Workspace Version`. You may need to quit VSCode and reopen it for this setting to take effect.

###### Troubleshooting
React Router now generates types for each of your route modules and passes typed props to route module component exports ([#11961](https://github.com/remix-run/react-router/pull/11961), [#12019](https://github.com/remix-run/react-router/pull/12019)). You can access those types by importing them from `./+types/<route filename without extension>`.

In VSCode, open up any TypeScript file in your project and then use <kbd>CMD</kbd>+<kbd>SHIFT</kbd>+<kbd>P</kbd> to select `Open TS Server log`. There should be a log for `[react-router] setup` that indicates that the plugin was resolved correctly. Then look for any errors in the log.
See [_How To > Route Module Type Safety_](https://reactrouter.com/dev/how-to/route-module-type-safety) and [_Explanations > Type Safety_](https://reactrouter.com/dev/explanation/type-safety) for more details.

#### Prerendering

Expand Down
47 changes: 16 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,28 @@
# Welcome to React Router &middot; [![npm package][npm-badge]][npm] [![build][build-badge]][build]
[![npm package][npm-badge]][npm] [![build][build-badge]][build]

[npm-badge]: https://img.shields.io/npm/v/react-router-dom.svg?style=flat-square
[npm]: https://www.npmjs.org/package/react-router-dom
[build-badge]: https://img.shields.io/github/actions/workflow/status/remix-run/react-router/test.yml?branch=dev&style=square
[build]: https://github.com/remix-run/react-router/actions/workflows/test.yml

React Router is a lightweight, fully-featured routing library for the [React](https://reactjs.org) JavaScript library. React Router runs anywhere React runs; on the web, on the server with node.js, or on any other Javascript platform that supports the [Web Fetch API][fetch-api].
React Router is a multi-strategy router for React bridging the gap from React 18 to React 19. You can use it maximally as a React framework or minimally as a library with your own architecture.

If you're new to React Router, we recommend you start with [the tutorial](https://reactrouter.com/en/main/start/tutorial).

If you're migrating to v6 from v5 (or v4, which is the same as v5), check out [the migration guide](/docs/upgrading/v5.md). If you're migrating from Reach Router, check out [the migration guide for Reach Router](/docs/upgrading/reach.md). If you need to find the code for v5, [it is on the `v5` branch](https://github.com/remix-run/react-router/tree/v5).

Documentation for v6 can be found [on our website](https://reactrouter.com/).

## Contributing

There are many different ways to contribute to React Router's development. If you're interested, check out [our contributing guidelines](CONTRIBUTING.md) to learn how you can get involved.
- [Getting Started - Framework](https://reactrouter.com/start/framework/installation)
- [Getting Started - Library](https://reactrouter.com/start/library/installation)
- [Upgrade from v6](https://reactrouter.com/upgrading/v6)
- [Upgrade from Remix](https://reactrouter.com/upgrading/remix)
- [Changelog](https://github.com/remix-run/react-router/blob/main/CHANGELOG.md)

## Packages

This repository is a monorepo containing the following packages:

- [`@react-router/dev`](/packages/react-router-dev)
- [`@react-router/express`](/packages/react-router-express)
- [`@react-router/node`](/packages/react-router-node)
- [`@react-router/serve`](/packages/react-router-serve)
- [`react-router`](/packages/react-router)
- [`react-router-dom`](/packages/react-router-dom)

## Changes

Detailed release notes for a given version can be found [on our releases page](https://github.com/remix-run/react-router/releases).

## Funding

You may provide financial support for this project by donating [via Open Collective](https://opencollective.com/react-router). Thank you for your support!

## About
- [react-router](./modules/react_router)
- [@react-router/dev](./modules/_react_router_dev)
- [@react-router/node](./modules/_react_router_node)
- [@react-router/cloudflare](./modules/_react_router_cloudflare)
- [@react-router/serve](./modules/_react_router_serve)
- [@react-router/fs-routes](./modules/_react_router_fs_routes)

React Router is developed and maintained by [Remix Software](https://remix.run) and many [amazing contributors](https://github.com/remix-run/react-router/graphs/contributors).
## Previous Versions

[fetch-api]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
- [v6](https://reactrouter.com/v6)
- [v5](https://v5.reactrouter.com/)
2 changes: 2 additions & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
- underager
- valerii15298
- ValiantCat
- vdusart
- vijaypushkin
- vikingviolinist
- vishwast03
Expand All @@ -297,6 +298,7 @@
- xcsnowcity
- yionr
- yracnet
- ytori
- yuleicul
- zeromask1337
- zheng-chuang
64 changes: 64 additions & 0 deletions decisions/0013-react-router-config-ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# `react-router.config.ts`

Date: 2024-11-21

Status: accepted

## Context

Previously in Remix and earlier pre-releases of React Router, framework config was passed directly to the Vite plugin as an options object. While this has worked well so far when limited to Vite-specific use cases or simple CLI commands, we've started to run into some limitations as our `react-router` CLI has become more advanced.

Some key issues with the current approach:

1. **Tight coupling with Vite**

Our CLI commands (`react-router routes` and `react-router typegen`) need access to framework config but have nothing to do with Vite. We previously worked around this by using Vite to resolve `vite.config.ts` and then extracting our React Router config from the resolved Vite config object, but this approach proved to be difficult as we added more features to our CLI.

2. **Limited config watching capabilities**

The introduction of `react-router typegen --watch` in particular highlighted the limitations of our Vite-coupled approach. We needed to not only resolve our config but also watch for changes. Having this tied to the Vite config made implementing this functionality unnecessarily complex.

3. **Heavy-handed config updates**

Changes to Vite plugin options are treated like any other change to the Vite config, triggering a full reload of the dev server. This takes away any ability for us to handle config updates more gracefully.

4. **Difficulty with config documentation**

Documentation of our config options was difficult since we either had to show a complete Vite config file with a lot of extra noise, or only show a call to the `reactRouter` plugin which looked a bit confusing since it was labelled as a `vite.config.ts` file. Neither approach was ideal for clearly explaining our config options while keeping code snippets to a minimum.

## Goals

1. Decouple framework config from Vite
2. Enable granular config watching for tools like `react-router typegen --watch`
3. Avoid unnecessary dev server reloads when config changes
4. Improve documentation by separating framework config from Vite config

## Decisions

### Introduce dedicated `react-router.config.ts` in the root of the project

We will introduce a dedicated config file, `react-router.config.ts/js`.

### Config is provided via a default export

To maintain consistency with other JS build tool configuration patterns, we will export the config object as the default export of the `react-router.config.ts` file.

### Change `app/routes.ts` API to use a default export rather than a named `routes` export

Now that we have multiple config files (`react-router.config.ts` and `app/routes.ts`), we should be internally consistent and use default exports for all of our config files. Now is a good time to make this change since the `routes.ts` API hasn't yet had a stable release.

### Any config APIs should be exported from `@react-router/dev/config`

The exported config object should satisfy the `Config` type from `@react-router/dev/config`. This follows our established pattern of using `@react-router/dev/*` namespaces for dev-time APIs that are scoped to particular files, e.g. `@react-router/dev/routes` and `@react-router/dev/vite`.

### Config file is optional but recommended

While the lack of a config file won't be treated as an error, we should include a blank config file in all official templates to make the config options more discoverable and self-documenting.

### Remove options from Vite plugin

The Vite plugin will no longer accept config options. All framework options will be handled through the dedicated config file.

### Improved config update handling

Config changes should no longer trigger full dev server reloads. We may re-introduce this behavior in certain cases where it makes sense.
4 changes: 2 additions & 2 deletions docs/explanation/race-conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ React Router's handling of network concurrency is heavily inspired by the behavi
Consider clicking a link to a new document, and then clicking a different link before the new page has finished loading. The browser will:

1. cancel the first request
2. immediately processes the new navigation
2. immediately process the new navigation

This behavior includes form submissions. When a pending form submission is interrupted by a new one, the first is canceled and the new submission is immediately processed.
The same behavior applies to form submissions. When a pending form submission is interrupted by a new one, the first is canceled and the new submission is immediately processed.

## React Router Behavior

Expand Down
Loading