Wiki

Third Party Issues

This documents problems we encounter during development where third party dependencies don't behave as expected.

Remix doesn't always report build errors during npm run dev

When integrating sanity studio into the website, we had a problem where the dev build failed, but there was no indication in the terminal. Only during the production build (npm run build), an error was logged (in this case a missing dependency).

Login to sanity studio issues

Login to the sanity studio that is embedded into the main remix app has issues. You have to log in and out of sanity.io/manage first, then login via the website. You'll get an error after logging and that disappears after a page reload.

The problem also exists with the semi official sanity remix template (https://github.com/SimeonGriggs/remix-sanity-studio-v3/).

Type inference doesn't work correctly with union types

We encountered the following type inference problem:

export function loader() {
    if (Math.random() > 0.5) {
      return json({ a: true })
    }
    return json({ a: false, b: 1 })
}

export default function Page() {
    const data = useLoaderData<typeof loader>()
    if (data.a) {
        return <>...</>
    } else {
        return <>{data.b}</> <!-- here, typescript will complain that b does not exist on data -->
    }
}

This is not actually a bug but just the way type inference works. The way to make this work is to add as const to the returned values.

export function loader() {
  if (Math.random() > 0.5) {
    return json({ a: true } as const);
  }
  return json({ a: false, b: 1 } as const);
}

Mock service worker breaks sanity fetch

We encountered an issue where fetches to sanity would fail in development when mock service worker is active. In detail, the request for some sanity document would fail if the response contained more than approx. 1000 characters.

We disabled mock service worker for now because we are not using it.

Note that this was tested with a version of msw that is now quite old, it is very possible this is no longer a problem.

Missing packages during fly deploy

We encountered an issues with trying to deploy to fly.io. the react-is and rxjs package were missing. We fixed the issue by explicitely adding the packages to package.json.

Scroll restoration matches param doesn't always include route handles

We want to be able change how scroll restoration works on some routes. This can be done by the getKey function of the ScrollRestoration component (see ScrollRestoration.getKey) A good way to do this would be allow routes to indicate how scroll restoration should work when matched by adding a handle to the route with a flag:

// some route module
export const {
  scrollRestorationByPath: true
}

// root.tsx
// ...
  <ScrollRestoration getKey={(location, matches) => {
    const { handle } = matches[matches.length - 1];
    if (
      handle &&
      typeof handle === "object" &&
      "scrollRestorationByPath" in handle &&
      handle.scrollRestorationByPath
    ) {
      return location.pathname;
    }
    return location.key;
  }}>
// ...

This works on reload of a page, but on normal navigation through the app, the handle on the matches entry is undefined.

VSCode Tailwind extension cannot preview complex selectors

The rule works correctly, but is displayed weirdly:

Screenshot of VS Code Tailwind extension showing a preview window for a complex tailwind expression

@testing-library/jest-dom adds global functions

Both playwright and vitest tests use functions like test, or expect. It is common to have these defined globally. However, when writing tests with globals, typescript won't know if a particular file references the version from playwright or vitest. It is simpler to import those functions explicitely.

This would be fine as is, however the library @testing-library/jest-dom includes a type definition file that defines those common testing functions as global. So there is no error when not importing explicitely. We work around this with a ESLint rule that errors if the global functions are used. It would be nicer if no globals were defined at all, then typescript would error anyway and you could quick fix import the functions when necessary.