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