Skip to content

Commit

Permalink
Merge branch 'release-next' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Apr 24, 2024
2 parents c53eb7d + f72d268 commit 05b4dad
Show file tree
Hide file tree
Showing 58 changed files with 244 additions and 495 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,22 @@ Date: YYYY-MM-DD
-->

## v2.9.1

Date: 2024-04-24

### Patch Changes

- `@remix-run/dev` - Fix issue where consumers who had added Remix packages to Vite's `ssr.noExternal` option were being overridden by the Remix Vite plugin adding Remix packages to Vite's `ssr.external` option ([#9301](https://github.com/remix-run/remix/pull/9301))
- `@remix-run/react` - Ignore `future/*.d.ts` files from TS build ([#9299](https://github.com/remix-run/remix/pull/9299))

### Changes by Package

- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.9.1/packages/remix-dev/CHANGELOG.md#291)
- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.9.1/packages/remix-react/CHANGELOG.md#291)

**Full Changelog**: [`v2.9.0...v2.9.1`](https://github.com/remix-run/remix/compare/remix@2.9.0...remix@2.9.1)

## v2.9.0

Date: 2024-04-23
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ You may need to make changes to a pre-release prior to publishing a final stable
- Create a new changeset: `pnpm changeset`
- **IMPORTANT:** This is required even if you ultimately don't want to include these changes in the logs
- Remember, changelogs can be edited prior to publishing, but the Changeset version script needs to see new changesets in order to create a new version
- Commit the changesets and push the the `release-*` branch to GitHub
- Commit the changesets and push the `release-*` branch to GitHub
- Wait for the release workflow to finish and the Changesets action to open its PR that will increment all versions
- Review the PR, make any adjustments necessary, and merge it into the `release-*` branch
- Once the PR is merged, the release workflow will publish the updated packages to npm
Expand Down
6 changes: 6 additions & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- achinchen
- adamwathan
- adicuco
- AdiRishi
- ahabhgk
- ahbruns
- ahmedeldessouki
Expand All @@ -30,6 +31,7 @@
- alireza-bonab
- alisd23
- ally1002
- alongdate
- AltanS
- alvinthen
- amir-ziaei
Expand Down Expand Up @@ -175,6 +177,7 @@
- emzoumpo
- enbonnet
- eps1lon
- eric-burel
- ericchernuka
- esamattis
- evanwinter
Expand Down Expand Up @@ -455,6 +458,7 @@
- msutkowski
- mthenw
- mtt87
- muhammadjalabi
- mush159
- n8agrin
- na2hiro
Expand Down Expand Up @@ -621,6 +625,7 @@
- twhitbeck
- tylerbrostrom
- udasitharani
- uerkw
- uhoh-itsmaciek
- unhackit
- UsamaHameed
Expand All @@ -645,6 +650,7 @@
- wilcoschoneveld
- willhack
- willin
- willowcheng
- wizardlyhel
- wKovacs64
- wladiston
Expand Down
2 changes: 1 addition & 1 deletion decisions/0007-remix-on-react-router-6-4-0.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ We can also split this into iterative approaches on the server too, and do `hand
5. `handleDocumentRequest`
1. This is the big one. It simplifies down pretty far, but has the biggest surface area where some things don't quite match up
2. We need to map query "errors" to Remix's definition of error/catch and bubble them upwards accordingly.
1. For example, in a URL like `/a/b/c`, if C exports a a `CatchBoundary` but not an `ErrorBoundary`, then it'll be represented in the `DataRouteObject` with `hasErrorBoundary=true` since the `@remix-run/router` doesn't distinguish
1. For example, in a URL like `/a/b/c`, if C exports a `CatchBoundary` but not an `ErrorBoundary`, then it'll be represented in the `DataRouteObject` with `hasErrorBoundary=true` since the `@remix-run/router` doesn't distinguish
2. If C's loader throws an error, the router will "catch" that at C's `errorElement`, but we then need to re-bubble that upwards to the nearest `ErrorBoundary`
3. See `differentiateCatchVersusErrorBoundaries` in the `brophdawg11/rrr` branch
3. New `RemixContext`
Expand Down
2 changes: 1 addition & 1 deletion docs/discussion/server-vs-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export const PostPreview = ({ title, description }) => {
[file_convention_server]: ../file-conventions/-server
[window_global]: https://developer.mozilla.org/en-US/docs/Web/API/Window/window
[server-bundles]: ../guides/server-bundles
[vite-config]: ../file-conventions/vite-configuration
[vite-config]: ../file-conventions/vite-config
[vite-env-only]: https://github.com/pcattori/vite-env-only
[classic-remix-compiler]: ../guides/vite#classic-remix-compiler-vs-remix-vite
[remix-vite]: ../guides/vite
4 changes: 2 additions & 2 deletions docs/file-conventions/remix-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ There are a few conventions that Remix uses you should be aware of.
[browser-node-builtins-polyfill]: #browsernodebuiltinspolyfill
[server-node-builtins-polyfill]: #servernodebuiltinspolyfill
[future-flags]: ../start/future-flags
[current-future-flags]: ../start/future-flags#current-future-flags
[classic-remix-compiler]: ../guides/vite#classic-remix-compiler-vs-remix-vite
[remix-vite]: ../guides/vite
[vite-config]: ./vite-configuration
[current-future-flags]: ../start/future-flags#current-future-flags
[vite-config]: ./vite-config
2 changes: 1 addition & 1 deletion docs/guides/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function ErrorBoundary() {
}
```

If you need to log these errors or report then to a third-party service such as [BugSnag][bugsnag] or [Sentry][sentry], then you can do this through a [`handleError`][handle-error] export in your [`app/entry.server.js`][entry-server]. This method receives the un-sanitized versions of the error since it is also running on the server.
If you need to log these errors or report them to a third-party service such as [BugSnag][bugsnag] or [Sentry][sentry], then you can do this through a [`handleError`][handle-error] export in your [`app/entry.server.js`][entry-server]. This method receives the un-sanitized versions of the error since it is also running on the server.

If you want to trigger an error boundary and display a specific message or data in the browser, then you can throw a `Response` from a `action`/`loader` with that data instead:

Expand Down
55 changes: 54 additions & 1 deletion docs/guides/single-fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,44 @@ Now that Remix is streaming internally, we can cancel the `turbo-stream` process

You can control this by exporting a `streamTimeout` numeric value from your `entry.server.tsx` and Remix will use that as the number of milliseconds after which to reject any outstanding Promises from `loader`/`action`'s. It's recommended to decouple this value from the timeout in which you abort the React renderer - and you should always set the React timeout to a higher value so it has time to stream down the underlying rejections from your `streamTimeout`.

```tsx filename=app/entry.server.tsx lines=[1-2,32-33]
// Reject all pending promises from handler functions after 5 seconds
export const streamTimeout = 5000;

// ...

function handleBrowserRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
return new Promise((resolve, reject) => {
const { pipe, abort } = renderToPipeableStream(
<RemixServer
context={remixContext}
url={request.url}
abortDelay={ABORT_DELAY}
/>,
{
onShellReady() {
/* ... */
},
onShellError(error: unknown) {
/* ... */
},
onError(error: unknown) {
/* ... */
},
}
);

// Automatically timeout the react renderer after 10 seconds
setTimeout(abort, 10000);
});
}
```

### Type Inference

Without Single Fetch, any plain Javascript object returned from a `loader` or `action` is automatically serialized into a JSON response (as if you returned it via `json`). The type inference assumes this is the case and infer naked object returns as if they were JSON serialized.
Expand Down Expand Up @@ -119,7 +157,9 @@ export default function Component() {

Previously, Remix would always revalidate all active loaders after _any_ action submission, regardless of the result of the action. You could opt-out of revalidation on a per-route basis via [`shouldRevalidate`][should-revalidate].

With Single Fetch, if an `action` returns or throws a `Response` with a `4xx/5xx` status code, Remix will _not revalidate_ loaders by default. You can then opt-into revalidation on a per-route basis. If an `action` returns or throws anything that is not a 4xx/5xx Response, then the revalidation behavior is unchanged. The reasoning here is that in most cases, if you return a `4xx`/`5xx` Response, you didn't actually mutate any data so there is no need to reload data.
With Single Fetch, if an `action` returns or throws a `Response` with a `4xx/5xx` status code, Remix will _not revalidate_ loaders by default. If an `action` returns or throws anything that is not a 4xx/5xx Response, then the revalidation behavior is unchanged. The reasoning here is that in most cases, if you return a `4xx`/`5xx` Response, you didn't actually mutate any data so there is no need to reload data.

If you _want_ to continue revalidating one or more loaders after a 4xx/5xx action response, you can opt-into revalidation on a per-route basis by returning `true` from your [`shouldRevalidate`][should-revalidate] function. There is also a new `unstable_actionStatus` parameter passed to the function that you can use if you need to decide based on the action status code.

Revalidation is handled via a `?_routes` query string parameter on the single fetch HTTP call which limits the loaders being called. This means that when you are doing fine-grained revalidation, you will have cache enumerations based on the routes being requested - but all of the information is in the URL so you should not need any special CDN configurations (as opposed to if this was done via a custom header that required your CDN to respect the `Vary` header).

Expand Down Expand Up @@ -158,6 +198,19 @@ export async function action({
}
```

You can also throw these response stubs to short circuit the flow of your loaders and actions:

```tsx
export async function loader({ request, response }) {
if (shouldRedirectToHome(request)) {
response.status = 302;
response.headers.set("Location", "/");
throw response;
}
// ...
}
```

Each `loader`/`action` receives it's own unique `response` instance so you cannot see what other `loader`/`action` functions have set (which would be subject to race conditions). The resulting HTTP Response status and headers are determined as follows:

- Status Code
Expand Down
4 changes: 3 additions & 1 deletion docs/hooks/use-params.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ function SomeComponent() {
}
```

Assuming a route like `routes/posts/$postId.tsx` is matched by `/posts/123` then `params.postId` will be `"123"`.
Assuming a route like `routes/posts/$postId.tsx` is matched by `/posts/123` then `params.postId` will be `"123"`. Params for [splat routes][splat-routes] are available as `params["*"]`.

[splat-routes]: ../file-conventions/routes#splat-routes
2 changes: 1 addition & 1 deletion docs/route/headers.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ If a user is looking at `/users/123/profile` and `users.$userId.profile.tsx` doe

If all three define `headers`, the deepest module wins, in this case `users.$userId.profile.tsx`. However, if your `users.$userId.profile.tsx`'s `loader` threw and bubbled to a boundary in `users.userId.tsx` - then `users.userId.tsx`'s `headers` function would be used as it is the leaf rendered route.

We don't want surprise headers in your responses, so it's your job to merge them if you'd like. Remix passes in the `parentHeaders` to your `headers` function. So `users.$userId.users.tsx` headers get passed to `users.$userId.tsx`, and then `users.$userId.tsx`'s `headers` are passed to `users.$userId.profile.tsx`'s `headers`.
We don't want surprise headers in your responses, so it's your job to merge them if you'd like. Remix passes in the `parentHeaders` to your `headers` function. So `users.tsx` headers get passed to `users.$userId.tsx`, and then `users.$userId.tsx`'s `headers` are passed to `users.$userId.profile.tsx`'s `headers`.

That is all to say that Remix has given you a very large gun with which to shoot your foot. You need to be careful not to send a `Cache-Control` from a child route module that is more aggressive than a parent route. Here's some code that picks the least aggressive caching in these cases:

Expand Down
10 changes: 5 additions & 5 deletions integration/error-sanitization-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ test.describe("Error Sanitization", () => {
expect(html).toMatch("Defer Route");
expect(html).toMatch("RESOLVED");
expect(html).not.toMatch("MESSAGE:");
// Defer errors are not not part of the JSON blob but rather rejected
// Defer errors are not part of the JSON blob but rather rejected
// against a pending promise and therefore are inlined JS.
expect(html).not.toMatch("x.stack=e.stack;");
});
Expand All @@ -218,7 +218,7 @@ test.describe("Error Sanitization", () => {
expect(html).toMatch("Defer Error");
expect(html).not.toMatch("RESOLVED");
expect(html).toMatch('{"message":"Unexpected Server Error"}');
// Defer errors are not not part of the JSON blob but rather rejected
// Defer errors are not part of the JSON blob but rather rejected
// against a pending promise and therefore are inlined JS.
expect(html).toMatch("x.stack=undefined;");
// defer errors are not logged to the server console since the request
Expand Down Expand Up @@ -374,7 +374,7 @@ test.describe("Error Sanitization", () => {
let html = await response.text();
expect(html).toMatch("Defer Error");
expect(html).not.toMatch("RESOLVED");
// Defer errors are not not part of the JSON blob but rather rejected
// Defer errors are not part of the JSON blob but rather rejected
// against a pending promise and therefore are inlined JS.
expect(html).toMatch("x.stack=e.stack;");
// defer errors are not logged to the server console since the request
Expand Down Expand Up @@ -565,7 +565,7 @@ test.describe("Error Sanitization", () => {
expect(html).toMatch("Defer Route");
expect(html).toMatch("RESOLVED");
expect(html).not.toMatch("MESSAGE:");
// Defer errors are not not part of the JSON blob but rather rejected
// Defer errors are not part of the JSON blob but rather rejected
// against a pending promise and therefore are inlined JS.
expect(html).not.toMatch("x.stack=e.stack;");
});
Expand All @@ -576,7 +576,7 @@ test.describe("Error Sanitization", () => {
expect(html).toMatch("Defer Error");
expect(html).not.toMatch("RESOLVED");
expect(html).toMatch('{"message":"Unexpected Server Error"}');
// Defer errors are not not part of the JSON blob but rather rejected
// Defer errors are not part of the JSON blob but rather rejected
// against a pending promise and therefore are inlined JS.
expect(html).toMatch("x.stack=undefined;");
// defer errors are not logged to the server console since the request
Expand Down
6 changes: 3 additions & 3 deletions integration/helpers/vite-cloudflare-template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"typecheck": "tsc"
},
"dependencies": {
"@remix-run/cloudflare": "2.9.0",
"@remix-run/cloudflare-pages": "2.9.0",
"@remix-run/react": "2.9.0",
"@remix-run/cloudflare": "2.9.1",
"@remix-run/cloudflare-pages": "2.9.1",
"@remix-run/react": "2.9.1",
"isbot": "^4.1.0",
"miniflare": "^3.20231030.4",
"react": "^18.2.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/create-remix/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# `create-remix`

## 2.9.1

No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.9.1.

## 2.9.0

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/create-remix/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-remix",
"version": "2.9.0",
"version": "2.9.1",
"description": "Create a new Remix app",
"homepage": "https://remix.run",
"bugs": {
Expand Down
7 changes: 7 additions & 0 deletions packages/remix-architect/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# `@remix-run/architect`

## 2.9.1

### Patch Changes

- Updated dependencies:
- `@remix-run/node@2.9.1`

## 2.9.0

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-architect/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/architect",
"version": "2.9.0",
"version": "2.9.1",
"description": "Architect server request handler for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand Down
7 changes: 7 additions & 0 deletions packages/remix-cloudflare-pages/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# `@remix-run/cloudflare-pages`

## 2.9.1

### Patch Changes

- Updated dependencies:
- `@remix-run/cloudflare@2.9.1`

## 2.9.0

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-cloudflare-pages/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/cloudflare-pages",
"version": "2.9.0",
"version": "2.9.1",
"description": "Cloudflare Pages request handler for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand Down
7 changes: 7 additions & 0 deletions packages/remix-cloudflare-workers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# `@remix-run/cloudflare-workers`

## 2.9.1

### Patch Changes

- Updated dependencies:
- `@remix-run/cloudflare@2.9.1`

## 2.9.0

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-cloudflare-workers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/cloudflare-workers",
"version": "2.9.0",
"version": "2.9.1",
"description": "Cloudflare worker request handler for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand Down
7 changes: 7 additions & 0 deletions packages/remix-cloudflare/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# `@remix-run/cloudflare`

## 2.9.1

### Patch Changes

- Updated dependencies:
- `@remix-run/server-runtime@2.9.1`

## 2.9.0

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/cloudflare",
"version": "2.9.0",
"version": "2.9.1",
"description": "Cloudflare platform abstractions for Remix",
"bugs": {
"url": "https://github.com/remix-run/remix/issues"
Expand Down
4 changes: 4 additions & 0 deletions packages/remix-css-bundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# @remix-run/css-bundle

## 2.9.1

No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.9.1.

## 2.9.0

No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.9.0.
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-css-bundle/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@remix-run/css-bundle",
"version": "2.9.0",
"version": "2.9.1",
"description": "CSS bundle href when using CSS bundling features in Remix",
"homepage": "https://remix.run",
"bugs": {
Expand Down
Loading

0 comments on commit 05b4dad

Please sign in to comment.