Skip to content

v1.8.0

Compare
Choose a tag to compare
@chaance chaance released this 01 Dec 14:47
· 2897 commits to main since this release

What's Changed

Lots of goodies to dig in this week, so let's get right to it 💪

React-Routering Remix

We released React Router 6.4 a few weeks back. This update introduced many of Remix's data APIs and moved all of the core routing logic to a framework-agnostic @remix-run/router package. As a result, we needed to rebuild the Remix implementation to take advantage of these changes.

1.8.0 includes the first big step in that process, and Remix now performs all server-side data fetches and mutations through the new framework agnostic router. This is an implementation detail and doesn't change much for you today, but completing this work will open the door for Remix to support other frameworks in the future. 🤯

Our guy @brophdawg11 published React-Routering Remix to dive into the details, so we encourage you to check it out to get a better glimpse of things to come!

A more robust meta API

Each Remix route can export a meta function that will render <meta> elements in the head of the route's document. The existing meta API was designed to simplify some of the inconsistencies of various meta tag attributes, but in turn it made some meta tags more difficult—if not impossible—to use correctly.

We also automatically merged all meta tags in nested route trees. While this is desirable in many cases, it's not a decision we should make for you in the cases where a leaf route's meta should omit its parent's tags.

As a result, we are rolling out a new, lower-level API for meta. Now you will return an array of objects that map directly to the <meta> tag's attributes, exactly as we do for links. You also get access to the route matches with meta and data available so you can decide how you want to handle merging meta tags.

export function meta({ data, matches }) {
  // Want to snag some meta from a matched route? No problem!
  let rootModule = matches.find((match) => match.route.id === "root");

  // Only want to merge its og: tags? Easy breezy!
  let rootOgTags = rootModule.meta.filter((meta) =>
    meta.property?.startsWith("og:")
  );

  // Merge what you want, where you want. No more magic!
  return [
    ...rootOgTags,
    { title: "All Downhill from Here" },
    { property: "og:type", content: "music.song" },
    { property: "music:musician", content: "https://www.newfoundglory.com/" },
    { property: "music:duration", content: 192 },
    {
      property: "music:album",
      content: "https://open.spotify.com/album/1Igrcji3zf5aC61saylDE1",
    },
  ];
}

While this is a new API, the change is completely opt-in via the new future option in remix.config.js and it will become the default behavior in version 2.0. No breaking changes for you, but a clear and early upgrade path should you choose to take it! To opt in, add the following to your Remix config file:

module.exports = {
  future: {
    v2_meta: true,
  },
};

For more details on how we got here, check out the original RFC.

Making thrown Response objects less ambiguous

Previously there was some ambiguity around "thrown Responses go to the CatchBoundary". The CatchBoundary exists to give the user a place to handle non-happy path code flows such that they can throw Response instances from their own code and handle them in a CatchBoundary. However, there are a handful of framework-internal errors that make sense to have a non-500 status code, and the fact that these were being thrown as Response instances was causing them to go into the CatchBoundary, even though they were not thrown by the user.

With this change, anything thrown by the framework itself (Error or Response) will go to the ErrorBoundary, and any user-thrown Response instance will go to the CatchBoundary. There is one exception to this rule, which is that framework-detected 404 responses will continue to go to the CatchBoundary since users should have one single location to handle 404 displays.

The primary affected use cases are scenarios such as:

  • HTTP OPTIONS requests (405 Unsupported Method )
  • GET requests to routes without loaders (400 Bad Request)
  • POST requests to routes without actions (405 Method Not Allowed)
  • Missing route id in _data parameters (403 Forbidden)
  • Non-matching route id included in _data parameters (403 Forbidden)

For more information on this change, check out the PR in which it was introduced.

Other Changes

  • Add support for importing .wasm files (#3299)
  • Update @remix-run/web-fetch. This addresses two bugs: (#4644)
    • It fixes a memory leak caused by unregistered listeners
    • It adds support for custom "credentials" values (Remix does nothing with these at the moment, but they pass through for the consumer of the request to access if needed)
  • Ensure route modules are loaded even in failure cases
    • This addresses a long standing issue where you would end up in your root catch boundary if a form transition to another route threw. This no longer occurs, and you end up in the contextual boundary you'd expect. (#4611)

Changes by package

New Contributors


Full Changelog: v1.7.6...v1.8.0