Skip to content

Releases: remix-run/remix

v1.7.4

27 Oct 19:21
Compare
Choose a tag to compare

What Changed

Patch Changes

  • You can now infer the type of the .data property of fetchers from your action and loader functions. This works similarly to our type inference of useLoaderData by providing the type of the action or loader function at the useFetcher call site.

    export async function loader(args: LoaderArgs) {
      return json({
        user: {
          name: "Chance",
          twitter: "@chancethedev",
          age: 36,
        },
      });
    }
    
    function SomeComponent() {
      let fetcher = useFetcher<typeof loader>();
      if (fetcher.data) {
        let userName = fetcher.data.user.name; // string
        let userAge = fetcher.data.user.age; // number
      }
    }
  • Fixed a bug in <Form> that prevented the correct method from being called with non-POST submissions

Changes by package

New Contributors


Full Changelog: v1.7.3...v1.7.4

v1.7.3

20 Oct 17:23
Compare
Choose a tag to compare

What Changed

Patch Changes

  • <Form /> now respects the formMethod attribute set on the submitter element (#4053)

    <Form>
      <button type="submit">GET request</button>
      <button type="submit" formMethod="post">
        POST request
      </button>
    </Form>
  • Assets referenced in CSS files are now hashed and copied to the assetsBuildDirectory (#4130).

    Before this change, a CSS declaration like background: url('./relative-path/image.png') that references the file ./relative-path/image.png will not copy that file to the build directory. This can be a problem if you use a custom build directory, or when dealing with third-party stylesheets in node_modules that reference their own relative files.

  • We updated the @remix-run/web-fetch dependency for @remix-run/node (#4277). This fixes issues with {Request | Response}.clone() throwing when body is null. This update also adds additional Node.js-specific types to fetch() to support the use of agent from http and https.

  • Added support for setting moduleResolution to node, node16 or nodenext in tsconfig.json (#4034)

  • Added resources imported only by resource routes to assetsBuildDirectory (#3841)

Changes by package

New Contributors


Full Changelog: v1.7.2...v1.7.3

v1.7.2

21 Sep 21:25
Compare
Choose a tag to compare

What's Changed

Bug Fixes

  • Preserve ?index for fetcher get submissions to index routes (#4238)
  • Fix dependency conflicts with type-fest (87642b71b)
  • Update ESLint and plugin dependencies (e4ec81c77)
  • Flush Node streams to address issues with libraries like compression that rely on chunk flushing (#4235)

Changes by package


Full Changelog: v1.7.1...v1.7.2

v1.7.1

16 Sep 16:10
Compare
Choose a tag to compare

What's Changed

Bug fixes 🐛

  • Ensured that requests are properly aborted on closing of a Response instead of Request in all Node adapters (#3626)
  • Locked the dependency on react-router-dom to version 6.3.0 instead of using a semver range (#4203), as installing react-router-dom@6.4.0 will cause compatibility issues
  • Fixed a bug with GET form submissions to ensure they replace the current search params, which tracks with the browser's behavior (#4046)

Changes by package

New Contributors


Full Changelog: v1.7.0...v1.7.1

v1.7.0

25 Aug 19:09
Compare
Choose a tag to compare

What's Changed

✨ Features

  • We removed our compiler's React shim in favor of esbuild's new automatic JSX transformation.

    There are no code changes required on your end, but by using the new transform we can prevent duplicate React imports from appearing in your build.

    The automatic JSX transform was introduced in React 17, and it allows you to write your JSX code without ever needing to import React. This means that compilers need to map JSX to React.createElement for you.

    Because esbuild previously didn't support this feature, we implemented a "shim" for the import to get the same affect. This unfortunately has caused problems with some external libraries, resulting in React being declared multiple times. (#2987)

    You still need to import modules from React that you use directly in your code (useState, useEffect, etc.). But if your component only needs the React import for JSX, you can safely omit it without worrying about duplicate imports.

  • The MetaFunction type can now infer data and parentsData types from route loaders.

    For example, if this meta function is exported from app/routes/sales/customers/$customerId:

    const meta: MetaFunction<
      typeof loader, // this will infer our type for `data`
      {
        root: RootLoader; // exported from the root route
        "routes/sales": SalesLoader; // exported from the sales route
        "routes/sales/customers": CustomersLoader; // exported from the sales/customers route
      }
    > = ({ data, parentsData }) => {
      ///
    };

    The meta function can be strongly typed by exposing each parent route's loader type:

    // app/root.tsx
    const loader = () => {
      return json({ hello: "world" } as const);
    };
    export type Loader = typeof loader;
    
    // app/routes/sales.tsx
    const loader = () => {
      return json({ salesCount: 1074 });
    };
    export type Loader = typeof loader;
    
    // app/routes/sales/customers.tsx
    const loader = () => {
      return json({ customerCount: 74 });
    };
    export type Loader = typeof loader;
    
    // app/routes/sales/customers/$customersId.tsx
    import type { Loader as RootLoader } from "~/root";
    import type { Loader as SalesLoader } from "~/routes/sales";
    import type { Loader as CustomersLoader } from "~/routes/sales/customers";
    
    const loader = () => {
      return json({ name: "Customer name" });
    };
    
    const meta: MetaFunction<
      typeof loader,
      {
        root: RootLoader;
        "routes/sales": SalesLoader;
        "routes/sales/customers": CustomersLoader;
      }
    > = ({ data, parentsData }) => {
      const { name } = data;
      //      ^? string
      const { customerCount } = parentsData["routes/sales/customers"];
      //      ^? number
      const { salesCount } = parentsData["routes/sales"];
      //      ^? number
      const { hello } = parentsData["root"];
      //      ^? "world"
    };
  • Each runtime package now exports a new type: SerializeFrom. This is used to infer the JSON-serialized return type of loaders and actions.

    type MyLoaderData = SerializeFrom<typeof loader>;
    type MyActionData = SerializeFrom<typeof action>;

Changes by package

New Contributors


Full Changelog: v1.6.8...v1.7.0

v1.6.8

12 Aug 15:38
1a194e5
Compare
Choose a tag to compare

What's Changed

💅 Enhancements

  • You can now use .mjs or .cjs file extensions for remix.config (#3675)
  • We added support for importing .sql files as text content (#3190)
  • We made some optimizations in our compiler to make MDX builds deterministic (and a little faster!) (#3966)
  • Your load context is now type safe! The AppLoadContext type is now an an interface mapping string to unknown (#1876). This allows you to extend it via module augmentation:
    declare module "@remix-run/server-runtime" {
      interface AppLoadContext {
        // add custom properties here!
      }
    }
  • We added a subscribe method to the transition manager, which allows subscribing and unsubscribing for React 18 strict mode compliance (#3964)

🐛 Bug fixes

  • Previously, if an action was omitted from <Form> or useFormAction, the action value would default to ".". This is incorrect, as "." should resolve based on the current path, but an empty action resolves relative to the current URL (including the search and hash values). We've fixed this to differentiate between the two, meaning that the resolved action will preserve the full URL. (#3697)
  • Fixed a few types to work more seamlessly with changes in @types/react@18 (#3917)

Changes by package

New Contributors


Full Changelog: v1.6.7...v1.6.8

v1.6.7

30 Jul 16:31
5a6978f
Compare
Choose a tag to compare

What's Changed

  • Patched a syntax error in @remix-run/dev to ensure create-remix runs smoothly on Node 14

  • Fix inferred types for useLoaderData and useActionData to preserve null value types in @remix-run/react.

    Previously, null types were being replaced by never due to our usage of NonNullable in UndefinedOptionals. Properties that aren't unions with undefined are now kept as-is, while properties that do include undefined are still made optional, but only remove undefined from the property type whereas NonNullable also removed null types.

Changes by package


Full Changelog: v1.6.6...v1.6.7

v1.6.6

29 Jul 19:58
834e077
Compare
Choose a tag to compare

What's Changed

  • We've added support for exporting a links function from .mdx routes (#3801). This is leveraging the fact that MDX (which we use to parse your markdown routes) allows you to declare and export anything:

    ---
    meta:
      title: Welcome to the site
      description: Hello, World!
    ---
    
    export const links = () => [
      {
        rel: "stylesheet",
        href: "/welcome.css",
        media: "(prefers-reduced-motion: no-preference)",
      },
    ];
    
    # My Page
    
    This is **markdown** with links 🎉
  • Fixed a few type-related bugs in @remix-run/react.

Changes by package

New Contributors


Full Changelog: v1.6.5...v1.6.6

v1.6.5

14 Jul 17:22
ee394a0
Compare
Choose a tag to compare

What's Changed

Enhanced types to allow inference of loader / action data

We enhanced the type signatures of loader/action and useLoaderData/useActionData to make it possible to infer the data type from return type of its related server function.

To enable this feature, you will need to use the LoaderArgs type from your Remix runtime package instead of typing the function directly:

- import type { LoaderFunction } from "@remix-run/[runtime]";
+ import type { LoaderArgs } from "@remix-run/[runtime]";

- export const loader: LoaderFunction = async (args) => {
-   return json<LoaderData>(data);
- }
+ export async function loader(args: LoaderArgs) {
+   return json(data);
+ }

Then you can infer the loader data by using typeof loader as the type variable in useLoaderData:

- let data = useLoaderData() as LoaderData;
+ let data = useLoaderData<typeof loader>();

The API above is exactly the same for your route action and useActionData via the ActionArgs type.

With this change you no longer need to manually define a LoaderData type (huge time and typo saver!), and we serialize all values so that useLoaderData can't return types that are impossible over the network, such as Date objects or functions.

See the discussions in #1254 and #3276 for more context.

All changes by package

New Contributors


Full Changelog: v1.6.4...v1.6.5

v1.6.4

07 Jul 20:44
Compare
Choose a tag to compare

What's Changed

🐛 Bug fixes

  • Fixed a regression with Node v18.3 by making the detection of IPv4 addresses more durable in @remix-run/serve and @remix-run/dev (#3602)
  • Fix Yarn PnP resolution for empty modules (#3633)

💅 Enhancements

  • Add watchPaths option for remix.config. This allows you to define custom directories to watch while running remix dev (#3188).

New Contributors

Full Changelog: v1.6.3...v1.6.4