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 -installThen 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 localhostSee 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.pemor 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_devenabled (#6506) - Fix Tailwind performance issue when
postcss.config.jscontainsplugins: { tailwindcss: {} }andremix.config.jscontains bothtailwind: trueandpostcss: true(#6468) - Faster server export removal for routes when
unstable_devis enabled (#6455) - Better error message when
remix-serveis 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
HeadersArgstype (#6247) - Properly handle thrown
ErrorResponseinstances 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 Requestreturning 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