Skip to content

Releases: remix-run/remix

v1.19.1

21 Jul 21:08
ccb002b
Compare
Choose a tag to compare

Patch Changes

  • Add a heartbeat ping to prevent the WebSocket connection from being closed due to inactivity when using a proxy like Cloudflare (#6904, #6927)
  • Treeshake out HMR code from production builds (#6894)

Changes by Package 🔗


Full Changelog: 1.19.0...1.19.1

v1.19.0

19 Jul 18:01
a68dac2
Compare
Choose a tag to compare

New Features

Improved Networking Options

When using the new v2_dev server, the --scheme and --host options have been deprecated and replaced with the REMIX_DEV_ORIGIN environment variable. For more information, refer to the v2 dev server docs (#6724)

ESBuild metafiles

For bundle analysis, the esbuild metafiles are now written to your server build directory (build/ by default) and can be uploaded to https://esbuild.github.io/analyze/ for analysis (#6772):

  • metafile.css.json
  • metafile.js.json (browser JS)
  • metafile.server.json (server JS)

New serverNodeBuiltinsPolyfill Config Option

When building for non-Node.js server platforms, you can now control which polyfills are included (or disbale them entirely) by setting serverNodeBuiltinsPolyfill in remix.config.js (#6814, #6859, #6877).

// Disable all polyfills
exports.serverNodeBuiltinsPolyfill = { modules: {} };

// Enable specific polyfills
exports.serverNodeBuiltinsPolyfill = {
  modules: {
    crypto: true, // Provide a JSPM polyfill
    fs: "empty", // Provide an empty polyfill
  },
};

⚠️ Note that this behavior will be changing in v2. In v1, Remix will polyfill a certain set of modules for you if you do not specify serverNodeBuiltinsPolyfill. In v2, Remix will no longer include polyfills by default. You can prepare for your eventual migration by explicitly setting this config value in your v1 app.

Other Notable Changes

  • Exclude unimplemented polyfills from server build for non-Node.js server platforms (#6814)
  • Ignore missing react-dom/client for react 17 (#6725)
  • Warn if not using v2_dev (#6818)
    • Rename --no-restart to --manual to match intention and documentation
    • --no-restart remains an alias for --manual in v1 for backwards compatibility
  • Ignore errors when killing already dead processes (#6773)
  • Fix sourcemaps for v2_dev (#6762)
  • Do not clear screen when dev server starts (#6719)
    • On some terminal emulators, "clearing" only scrolls the next line to the top, while on others it erases the scrollback
    • Instead, let users call clear themselves (clear && remix dev) if they want to clear
  • Always rewrite css-derived assets during builds (#6837)
  • Fix router race condition for HMR (#6767)
  • Properly handle ?_data HTTP/Network errors that don't reach the Remix server and ensure they bubble to the ErrorBoundary (#6783)
  • Support proper hydration of Error subclasses such as ReferenceError/TypeError in development mode (#6675)
  • Properly return a 404 for a ?_data request that doesn't match any routes (#6820)
  • Narrowed the type of fetcher.formEncType to use FormEncType from react-router-dom instead of string (#6810)
  • Deferred promises that return undefined/void now surface a serialization error (#6793)
  • Avoid re-prefetching stylesheets for active routes during a revalidation (#6679)
  • Add generic type for useRouteLoaderData() (#5157)
  • Submitted empty file inputs are now correctly parsed out as empty File instances instead of being surfaced as an empty string via request.formData() (via @remix-run/web-fetch@4.3.5) (#6816)
  • Added some missing react-router-dom exports to @remix-run/react (createPath, matchPath, etc.) (#6856)
  • Updated React Router dependencies:

Changes by Package 🔗


Full Changelog: 1.18.1...1.19.0

v1.18.1

30 Jun 20:59
708f7db
Compare
Choose a tag to compare

Patch Changes

  • Ignore missing react-dom/client for React 17 (#6725)
  • Fix reload loops in scenarios where CDNs ignore search params (#6707)
  • Avoid circular references and infinite recursion in types (#6736)
    • "Pretty" or simplified Typescript types are evaluated by eagerly resolving types. For complex types with circular references, this can cause TS to recurse infinitely.
    • To fix this, pretty types are reverted as a built-in DX feature of useLoaderData, useActionData, etc...
  • Updated React Router dependencies:

Changes by Package 🔗


Full Changelog: 1.18.0...1.18.1

v1.18.0

26 Jun 17:30
d8f4034
Compare
Choose a tag to compare

New Features

Stable V2 Dev Server

Great news! 1.18.0 officially stabilizes the "New Dev Server" complete with HMR/HDR 🎉. If you've previously opted into the unstable_dev version, you'll need to update your remix.config.js flag name from future.unstable_dev -> future.v2_dev in 1.18.0. If you've not yet opted in, we now consider the new dev server stable (no more API changes) so feel free to upgrade anytime to make your eventual migration to v2 smoother! You can read up on the new dev server in the docs.

JSON/Text Submissions

If you're not a huge fan of FormData, Remix 1.18.0 updates to react-router-dom@6.14.0 which brings along support for opt-in application/json or text/plain encoding in useSubmit/fetcher.submit, and adds corresponding navigation.json/navigation.text and fetcher.json/fetcher.text fields containing the respective submissions. For details please check out the React Router release notes or the useSubmit docs. (#6570)

// Submit to your action using JSON
submit({ key: "value" }, { method: "post", encType: "application/json" });
// available in components via useNavigation().json and actions via request.json()
// Submit to your action using text
submit("plain text", { method: "post", encType: "text/plain" });
// available in components via useNavigation().text and actions via request.text()

Warning
Please be aware that useSubmit() and fetcher.submit() are not suitable for Progressive Enhancement, so switching to these to leverage JSON or Text submissions will break your app when JS is unable to load/execute. It's recommended to stick with normal FormData submissions for critical aspects of your application.

Default Behavior

Please also note that to avoid a breaking change, the default behavior will still encode a simple key/value JSON object into a FormData instance:

submit({ key: "value" }, { method: "post" });
// available in components via useNavigation().formData and actions via request.formData()
}

This behavior will likely change in the future when React Router releases v7, so it's best to make any JSON object submissions explicit with either encType: "application/x-www-form-urlencoded" or encType: "application/json" to ease your eventual v7 migration path.

Viewport-driven Prefetching

The Link component can now automatically prefetch your route data and JS modules when they enter the viewport via the new <Link prefetch="viewport"> prop value. Similar to intent this will add the relevant <link rel="prefetch"> tags to DOM when the link enters the viewport, and remove them when it exits (via an Intersection Observer). (#6433)

Updated ESLint Configurations

We've updated the @remix-run/eslint-config to inherit the recommended set of rules from @typescript-eslint/recommended instead of manually maintaining our own TS-related rules, so you may see some new lint warnings/errors (#6614)

Perf improvements 🏎️

We've invested heavily into performance the last couple weeks and are excited to share those speed gains with all of you 💪.

You could see modest improvement (~10% faster), but we've also personally witnessed build and rebuild times melt in some extreme cases. Here's a sample:

All of these numbers depend on your hardware, OS, and your app so take them with a grain of salt 🧂. That said, none of our optimizations were hardware or OS-specific so here's hoping 🤞 that your DX gets a speed boost!

Pro-tip: if your project uses a large component library like MUI or AntD you could get BIG perf gains if you avoid named imports.

Other notable Changes

  • Fix typing issues when using React 17 (#5713)
    • ⚠️ Note that because @remix/server-runtime doesn't actually do anything with React, the included CatchBoundaryComponent/ErrorBoundaryComponent/V2_ErrorBoundaryComponent types have been loosened to any and marked @deprecated. If you were using these types you should instead import them from the corresponding types in @remix-run/react.
  • Fix bug with pathless layout routes beneath nested path segments (#6649)
  • Properly pass <Scripts /> props (i.e., nonce) to inline script tags for deferred data (#6389)
  • Detect mismatches between the initially loaded URL and the URL at the time of hydration and trigger a hard reload if they don't match (#6409)
  • Show deprecation warning when using @remix-run/vercel, since Vercel now provides built-in support for Remix apps (#5964)
  • improved logging for remix build and remix dev (#6596)
  • fix remix dev -c: kill all descendant processes of specified command when restarting (#6663)
  • Updated React Router dependencies to the latest versions:

Changes by Package 🔗


Full Changelog: 1.17.1...1.18.0

v1.17.1

15 Jun 16:31
7c349aa
Compare
Choose a tag to compare

Patch Changes

  • Replace esbuild-plugin-polyfill-node with esbuild-plugins-node-modules-polyfill (#6562)
  • Lazily generate CSS bundle when import of @remix-run/css-bundle is detected (#6535)
  • Updated dependencies:

Changes by Package 🔗


Full Changelog: 1.17.0...1.17.1

v1.17.0

06 Jun 19:33
d8ca6b6
Compare
Choose a tag to compare

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

v1.16.1

17 May 17:19
c0aa857
Compare
Choose a tag to compare

Continuing the work to stabilize features for v2, this release brings improvements to unstable_dev as well as a bunch of bug fixes.

Dev server power-ups 🦾🤖

We've made two huge improvements to 🔥 Hot Data Revalidation 🔥 in 1.16.1! For anyone who needs a refresher on HDR, its like HMR but for your server code. In Remix, that primarily means tracking loader changes.

In 1.16.0, Remix would trigger HDR even if only UI code had changed. Now in 1.16.1, Remix only triggers HDR when loaders have changed. (#6278)

Also, in 1.16.1, Remix now detects code changes that affect your loader anywhere in your app code. You can modify the loader itself, or a function that the loader calls, or hardcoded data. Remix now only triggers HDR to fetch new data from routes with loader changes. For example, if you changed your /products/$id loader, but not your /products loader, Remix only refetches data for /products/$id. (#6299)

If you want to dive deeper into how it works and get a mental model for the new dev server with HDR, check out 🎥 Pedro's talk at Remix Conf.

Dev server bug fixes

Thank you to everyone who's tried unstable_dev ❤️ .
You've given us invaluable feedback that let us identify and fix the following bugs:

  • CSS-only changes now correctly trigger HMR (#6374)
  • Fixed a regression that caused the old dev server to hang on rebuilds (#6295)
  • Rebuilds no longer hang indefinitely for unstable_dev (#6294, #6295)
  • Fixed No loader for {.svg,.png, etc...} during HDR (#6396)
  • App server port no longer conflicts during rebuilds (#6289)
  • Windows: -c/--command option now has access to node_modules/.bin binaries (#6310)
  • Windows: App server process in no longer orphaned when dev server exits (#6395)
  • Windows: Changes in route files are now detected correctly for HMR/HDR (#6293)

Other notable changes

  • css: handle css imports in js files with jsx (#6309)
  • css: only process .css.{js,ts} if @vanilla-extract/css is installed (#6345)
  • lint: do not require display name in root route (#5450)
  • types: Typesafe destructuring of SessionStorage (#6330)
  • types: V2_MetaFunction can be undefined (#6231)
  • Remix commands no longer modify tsconfig (#6156)
  • re-export useMatch from react-router-dom (#5257)
  • Updated React Router dependencies to the latest versions:

Changes by Package 🔗


Full Changelog: 1.16.0...1.16.1

v1.16.0

01 May 19:51
6b9deca
Compare
Choose a tag to compare

Remix is full speed ahead preparing for our upcoming v2 release! 1.16.0 stabilizes a handful of CSS features, contains a major overhaul to the internals of the new remix dev server. and fixes a bunch of bugs.

Stabilized CSS Features

CSS Modules/Vanilla Extract/CSS Side-Effect Imports

Version 1.16.0 stabilizes built-in support for CSS Modules, Vanilla Extract and CSS side-effect imports, which were previously only available via future flags (future.unstable_cssModules, future.unstable_vanillaExtract, future.unstable_cssSideEffectImports). In order to use these features, check out our guide to CSS bundling in your project.

PostCSS

Version 1.16.0 stabilizes built-in PostCSS support via the new postcss option in remix.config.js. As a result, the future.unstable_postcss option has also been deprecated. The postcss option is false by default, but when set to true will enable processing of all CSS files using PostCSS if postcss.config.js is present. For more information on PostCSS support, check out the docs.

If you followed the original PostCSS setup guide for Remix, you may have a folder structure that looks like this, separating your source files from its processed output:

.
├── app
│   └── styles (processed files)
│       ├── app.css
│       └── routes
│           └── index.css
└── styles (source files)
    ├── app.css
    └── routes
        └── index.css

After you've enabled the new postcss option, you can delete the processed files from app/styles folder and move your source files from styles to app/styles:

.
├── app
│   └── styles (source files)
│       ├── app.css
│       └── routes
│           └── index.css

You should then remove app/styles from your .gitignore file since it now contains source files rather than processed output.

You can then update your package.json scripts to remove any usage of postcss since Remix handles this automatically. For example, if you had followed the original setup guide:

{
  "scripts": {
-    "dev:css": "postcss styles --base styles --dir app/styles -w",
-    "build:css": "postcss styles --base styles --dir app/styles --env production",
-    "dev": "concurrently \"npm run dev:css\" \"remix dev\""
+    "dev": "remix dev"
  }
}

Tailwind

Version 1.16.0 stabilizes built-in Tailwind support via the new tailwind option in remix.config.js. As a result, the future.unstable_tailwind option has also been deprecated. For more information on Tailwind support, check out the docs.

The tailwind option is false by default, but when set to true will enable built-in support for Tailwind functions and directives in your CSS files if tailwindcss is installed.

If you followed the original Tailwind setup guide for Remix and want to make use of this feature, you should first delete the generated app/tailwind.css.

Then, if you have a styles/tailwind.css file, you should move it to app/tailwind.css.

rm app/tailwind.css
mv styles/tailwind.css app/tailwind.css

Otherwise, if you don't already have an app/tailwind.css file, you should create one with the following contents:

@tailwind base;
@tailwind components;
@tailwind utilities;

You should then remove /app/tailwind.css from your .gitignore file since it now contains source code rather than processed output.

You can then update your package.json scripts to remove any usage of tailwindcss since Remix handles this automatically. For example, if you had followed the original setup guide:

{
  "scripts": {
-    "build": "run-s \"build:*\"",
+    "build": "remix build",
-    "build:css": "npm run generate:css -- --minify",
-    "build:remix": "remix build",
-    "dev": "run-p \"dev:*\"",
+    "dev": "remix dev",
-    "dev:css": "npm run generate:css -- --watch",
-    "dev:remix": "remix dev",
-    "generate:css": "npx tailwindcss -o ./app/tailwind.css"
  }
}

Dev Server Overhaul

🎥 Livestream of Pedro and Kent going over the new dev server

Version 1.16.0 contains a major overhaul to the new dev server, which can be enabled via the future.unstable_dev flag in remix.config.js. The Remix dev server now spins up your app server as a managed subprocess. This keeps your development environment as close to production as possible, and also means that the Remix dev server is compatible with any app server.

By default, the dev server will use the Remix App Server, but you opt to use your own app server by specifying the command to run it via the -c/--command flag:

remix dev # uses `remix-serve <serve build path>` as the app server
remix dev -c "node ./server.js" # uses your custom app server at `./server.js`

The dev server will:

  • force NODE_ENV=development and warn you if it was previously set to something else
  • rebuild your app whenever your Remix app code changes
  • restart your app server whenever rebuilds succeed
  • handle live reload and HMR + Hot Data Revalidation

App server coordination

In order to manage your app server, the dev server needs to be told what server build is currently being used by your app server. This works by having the app server send a "I'm ready!" message with the Remix server build hash as the payload.

This is handled automatically in Remix App Server and is set up for you via calls to broadcastDevReady or logDevReady in the official Remix templates.

If you are not using Remix App Server and your server doesn't call broadcastDevReady, you'll need to call it in your app server after it is up and running.

For example, in an Express server:

// server.js
// <other imports>
import { broadcastDevReady } from "@remix-run/node";

// Path to Remix's server build directory ('build/' by default)
const BUILD_DIR = path.join(process.cwd(), "build");

// <code setting up your express server>

app.listen(3000, () => {
  const build = require(BUILD_DIR);
  console.log("Ready: http://localhost:" + port);

  // in development, call `broadcastDevReady` _after_ your server is up and running
  if (process.env.NODE_ENV === "development") {
    broadcastDevReady(build);
  }
});

Cloudflare

For CF workers and pages, you'll need to use logDevReady instead of broadcastDevReady as the experimental CF runtime won't play nicely with fetch which is how broadcastDevReady is implemented.

For examples, here's a sneak peek 👀 of unstable_dev-enabled templates. Be sure to check out how logDevReady is called in the server.ts files for CF workers and for CF pages.

Options

Options priority order is: 1. flags, 2. config, 3. defaults.

Option flag config default
Command -c / --command command remix-serve <server build path>
HTTP(S) scheme --http-scheme httpScheme http
HTTP(S) host --http-host httpHost localhost
HTTP(S) port --http-port httpPort Dynamically chosen open port
Websocket port --websocket-port websocketPort Dynamically chosen open port
No restart --no-restart restart: false restart: true

🚨 The --http-* flags are only used for internal dev server <-> app server communication.
Your app will run on your app server's normal URL.

To set unstable_dev configuration, replace unstable_dev: true with unstable_dev: { <options> }.
For example, to set the HTTP(S) port statically:

// remix.config.js
module.exports = {
  future: {
    unstable_dev: {
      httpPort: 8001,
    },
  },
};

SSL and custom hosts

You should only need to use the --http-* flags and --websocket-port flag if you need fine-grain control of what scheme/host/port for the dev server. If you are setting up SSL or Docker networking, these are the flags you'll want to use.

🚨 Remix will not set up SSL and custom host for you.

The --http-scheme and --http-host flag are for you to tell Remix how you've set things up. It is your task to set up SSL certificates and host files if you want those features.

--no-restart and require cache purging

If you want to manage server changes yourself, you can use the --no-restart flag to tell the dev server to refrain from restarting your app server when builds succeed:

remix dev -c "node ./server.js" --no-restart

For example, you could purge the require cache of your app server to keep it running while picking up server changes. If you do so, you should watch the server build path (build/ by default) for changes and only purge the require cache when changes are detected.

🚨 If you use --no-restart, it is your responsibility to call broadcastDevReady when your app server has picked up server changes.

For example, with chokidar:

// server.dev.js
const BUILD_PATH = path.resolve(__dirname, "build");

const watcher = chokidar.watch(BUILD_PATH);

watcher.on("all", () => {
  // 1...
Read more

v1.15.0

31 Mar 17:47
7f70071
Compare
Choose a tag to compare

For the last few months we've been working hard on bringing new and improved APIs to Remix. We've introduced several major changes to prepare you for v2 via future flags, and we think v1.15.0 is our last big push to get you ready for the future of Remix.

It's important to note that nothing in your app will break if you do not opt-in to our future flags. 🥳 We are on a mission to provide the smoothest possible upgrade path so you can take it on before a new major release.

Let's get into it 🤓

Preparing for v2 Guide

While these release notes have some information about the APIs, the best way to prepare for v2 is to read the new guide in the docs:

Preparing for v2.

Future Flags

As of v1.15.0, we have deprecated all v1 APIs impacted by v2 future flags. When you run your app in development, we will show a one-time warning for deprecated APIs along with a link that explains how to incrementally migrate to the new APIs before v2 is released.

The v2 future flags include:

  • v2_errorBoundary: Removes the CatchBoundary component in favor of handling thrown Response objects in ErrorBoundary directly
  • v2_meta: Uses the new function signature for route meta functions and simplifies rendering in <Meta />
  • v2_routeConvention: Uses new "flat route" naming conventions
  • v2_normalizeFormMethod: useNavigation and useFetcher hooks returning an object with formMethod will uses uppercase method verbs ("GET", "POST", etc.) to align with fetch() behavior

For detailed information on how to use these flags and incrementally upgrade your app, please refer to Preparing for v2 in the Remix docs.

Changes to v2 meta

We have made a few changes to the API for route module meta functions when using the future.v2_meta flag.

  • V2_HtmlMetaDescriptor has been renamed to V2_MetaDescriptor
  • The meta function's arguments have been simplified
    • parentsData has been removed, as each route's loader data is available on the data property of its respective match object
      // before
      export function meta({ parentsData }) {
        return [{ title: parentsData["routes/parent"].title }];
      }
      // after
      export function meta({ matches }) {
        let parent = matches.find((match) => match.id === "routes/parent");
        return [{ title: parent.data.title }];
      }
    • The route property on route matches has been removed, as relevant match data is attached directly to the match object
      // before
      export function meta({ matches }) {
        let rootModule = matches.find((match) => match.route.id === "root");
      }
      // after
      export function meta({ matches }) {
        let rootModule = matches.find((match) => match.id === "root");
      }
  • We have added support for generating <script type='application/ld+json' /> and meta-related <link /> tags to document head via the route meta function

See the v2 meta docs for more information.

useTransition becomes useNavigation

We have deprecated the useTransition hook in favor of the new useNavigation. When we were designing early versions of Remix, the React team shipped their own [at the time] experimental hook called useTransition. To avoid confusion we plan to remove our useTransition hook in v2.

The signature for useNavigation is similar but makes a few key changes to note when upgrading:

import { useTransition } from "@remix-run/react";

function SomeComponent() {
  // before
  let {
    location,
    state,
    submission: { formAction, formData, formMethod },
    type,
  } = useTransition();

  // after
  let {
    // `submission` properties have been flattened
    formAction,
    formData,
    formMethod,
    location,
    state,
  } = useNavigation();
}

Notably, the type property has been removed. It can be derived from the state of a navigation alongside its other properties. See the v2 upgrade guide in our docs for more details.

Deprecated remix.config options

Other notable changes

  • The V2_HtmlMetaDescriptor type has been renamed to V2_MetaDescriptor
  • We now ensure that stack traces are removed from all server side errors in production
  • entry.client and entry.server files are now optional, making it simpler to start a new Remix app without a template or boilerplate
  • Bumped React Router dependencies to the latest version. See the release notes for more details.
  • Fixed issue to ensure changes to CSS inserted via @remix-run/css-bundle are picked up during HMR
  • Added experimental support for Vanilla Extract caching, which can be enabled by setting future.unstable_vanillaExtract: { cache: true } in remix.config. This is considered experimental due to the use of a brand new Vanilla Extract compiler under the hood. In order to use this feature, you must be using at least v1.10.0 of @vanilla-extract/css.

Changes by Package 🔗


Full Changelog: 1.14.3...1.15.0

v1.14.3

15 Mar 20:51
c268fde
Compare
Choose a tag to compare

Fix regression #5631 : dev server keeps running when browser or server builds fail (#5795)


Full Changelog: 1.14.2...1.14.3