github remix-run/remix remix@1.17.0
v1.17.0

latest releases: v0.0.0-nightly-6eb6acf3f-20240511, remix@2.9.2, @remix-run/testing@2.9.2...
11 months ago

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 contains plugins: { tailwindcss: {} } and remix.config.js contains both tailwind: true and postcss: 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 🔗


Full Changelog: 1.16.1...1.17.0

Don't miss a new remix release

NewReleases is sending notifications on new releases.