Skip to content

v1.9.0

Compare
Choose a tag to compare
@chaance chaance released this 16 Dec 22:12
· 2327 commits to main since this release

The New Stuff

Support for React Router's Optional Route Segments

We shipped the latest minor version of 6.5.0 with support for optional route segments, and now Remix supports them as well. To do this, we've introduced a new convention for file-system routes.

Route filenames surrounded by parenthesis will be converted into optional segments for React Router. For example /($lang)/about will be converted to /:lang?/about.

This means /($lang)/about would match:

/en/about
/fr/about
/about  <-- $lang is optional!

Another example: /(one)/($two)/(three).($four) route would match all of the following:

/
/one
/one/param1
/one/param1/three
/one/param1/three/param2

As with any of our conventions, you can escape the conversion by wrapping the route filename in square brackets. For example, /[(one)]/two would match the URL path /(one)/two.

Added Support for New TypeScript Syntax

The Remix compiler now supports new TypeScript 4.9 syntax (#4754). There were several cool features that landed in the latest TypeScript release, and we're stoked that you can grab them today! 🤓

One of our favorites is the satisfies keyword, which lets you validate that an expression matches a given type—without changing the resulting type of that expression.

// this example comes from the TypeScript 4.9 release notes
type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number];
const palette = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255]
//  ~~~~ The typo is now caught!
} satisfies Record<Colors, string | RGB>;
// Both of these methods are still accessible!
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();

For a closer look at all the new features available, check out the TypeScript release notes.

Perf Gains for Your Routes 💪

Sometimes you can get big wins out of tiny changes. We did that by making a tweak to a lookup algorithm in defineConventionalRoutes that resulted in some numbers we love to see.

In local runs of the production builds for a larger, realistic project (~700 routes):

  • Previously: 10-15s
  • Now: <1 second — >10x faster!

In addition to new features, we also squashed some nasty critters over the last week.

A Pesky Bug Squashed: Firefox and <LiveReload>

We fixed up a problem with <LiveReload> in Firefox that caused pages to infinitely reload after changes. This was no bueno!

The problem was:

  1. Firefox is calling ws.onclose immediately upon connecting (?!)
  2. Then we’re trying to reconnect, and upon reconnection, we reload the page
  3. Firefox then calls ws.onclose again after reconnecting and the loop starts over

This fix is to check for the proper event code (1006) before actually trying to reconnect and the reload the page. 1006 means the connection was closed abnormally, but in our case it means the server was shut down in local dev, and the socket can reconnect again when the server is back up.

Changes by Package

New Contributors


Full Changelog: v1.8.2...v1.9.0