v1.17.0
New Features
Suspense Support
Remix 1.17.0 updates to React Router 6.12.0 which wraps internal router state updates in React.startTransition
so you can better handle async/suspenseful components within your Remix app.
Error Reporting
If you want better control over your server-side error logging and the ability to report unhandled errors to an external service, you may now export a handleError
function from your entry.server.tsx
file and take full control over the logging and reporting of server-side errors. (#6495, #6524)
// entry.server.tsx
export function handleError(
error: unknown,
{ request, params, context }: DataFunctionArgs
): void {
if (error instanceof Error) {
sendErrorToBugReportingService(error);
console.error(formatError(error));
} else {
let unknownError = new Error("Unknown Server Error");
sendErrorToBugReportingService(unknownError);
console.error(unknownError);
}
}
future.v2_headers
flag
Previously, Remix relied on each leaf route to export it's own headers
function to generate headers for document requests. This was a bit tedious and easy to forget to include on new routes, and prohibited child routes from inheriting the headers
logic of any ancestor routes. We plan to change this behavior in v2 and have introduced the new behavior behind a future.v2_headers
flag. With this new flag enabled, Remix will now return the headers from the deepest headers
function found in the matched routes, which allows you to better inherit parent route headers
function implementations. If an error boundary is being rendered, the "matched" routes will only contain routes up to and including the error boundary route, but not below. (#6431)
Enhanced Header Management for Errored Document Requests
When rendering a CatchBoundary
(or v2 ErrorBoundary
) due to a thrown Response
from a loader
/action
, the headers
function now has a new errorHeaders
parameter that contains any headers from the thrown Response
. This allows you to include headers from bubbled responses in your document request response. If the throwing route contains the boundary, then errorHeaders
will be the same object as loaderHeaders
/actionHeaders
for that route. (#6425, #6475)
Dev server updates (future.unstable_dev
)
Built-in TLS Support
The new dev server now has built-in TLS support via 2 new CLI options (#6483):
--tls-key
/tlsKey
: TLS key--tls-cert
/tlsCert
: TLS Certificate
If both TLS options are set, scheme
defaults to https
.
Example
Install mkcert and create a local CA:
brew install mkcert
mkcert -install
Then make sure you inform node
about your CA certs:
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
👆 You'll probably want to put that env var in your scripts or .bashrc
/.zshrc
Now create key.pem
and cert.pem
:
mkcert -key-file key.pem -cert-file cert.pem localhost
See mkcert
docs for more details.
Finally, pass in the paths to the key and cert via flags:
remix dev --tls-key=key.pem --tls-cert=cert.pem
or via config:
module.exports = {
future: {
unstable_dev: {
tlsKey: "key.pem",
tlsCert: "cert.pem",
},
},
};
That's all that's needed to set up the Remix Dev Server with TLS.
🚨 Make sure to update your app server for TLS as well.
For example, with express
:
import express from "express";
import https from "node:https";
import fs from "node:fs";
let app = express();
// ...code setting up your express app...
let appServer = https.createServer(
{
key: fs.readFileSync("key.pem"),
cert: fs.readFileSync("cert.pem"),
},
app
);
appServer.listen(3000, () => {
console.log("Ready on https://localhost:3000");
});
Known limitations
remix-serve
does not yet support TLS. That means this only works for custom app server using the -c
flag for now.
Port Management
The new dev server will now reuse the dev server port for the WebSocket (Live Reload, HMR, HDR) (#6476). As a result the webSocketPort
/--websocket-port
option has been obsoleted. Additionally, scheme/host/port options for the dev server have been renamed.
Available options are:
Option | flag | config | default |
---|---|---|---|
Command | -c / --command |
command |
remix-serve <server build path> |
Scheme | --scheme |
scheme |
http |
Host | --host |
host |
localhost |
Port | --port |
port |
Dynamically chosen open port |
No restart | --no-restart |
restart: false |
restart: true |
Note that scheme/host/port options are for the dev server, not your app server.
You probably don't need to use scheme/host/port option if you aren't configuring networking (e.g. for Docker or SSL).
Other notable changes
- Force Typescript to simplify type produced by
Serialize
(#6449) - Fix warnings when importing CSS files with
future.unstable_dev
enabled (#6506) - Fix Tailwind performance issue when
postcss.config.js
containsplugins: { tailwindcss: {} }
andremix.config.js
contains bothtailwind: true
andpostcss: true
(#6468) - Faster server export removal for routes when
unstable_dev
is enabled (#6455) - Better error message when
remix-serve
is not found (#6477) - Restore color for app server output (#6485)
- Support sibling pathless layout routes (#4421)
- Fix route ranking bug with pathless layout route next to a sibling index route (#4421)
- Fix dev server crashes caused by ungraceful HDR error handling (#6467)
- Add caching to PostCSS for regular stylesheets (#6505)
- Export
HeadersArgs
type (#6247) - Properly handle thrown
ErrorResponse
instances inside resource routes (#6320) - Ensure unsanitized server errors are logged on the server during document requests (#6495)
- Retry HDR revalidations in development mode to aid in 3rd party server race conditions (#6287)
- Fix
request.clone() instanceof Request
returning false (#6512) - Updated React Router dependencies to the latest versions:
Changes by Package 🔗
@remix-run/cloudflare
@remix-run/css-bundle
@remix-run/deno
@remix-run/dev
@remix-run/eslint-config
@remix-run/node
@remix-run/react
@remix-run/server-runtime
@remix-run/testing
Full Changelog: 1.16.1...1.17.0