router icon indicating copy to clipboard operation
router copied to clipboard

Application crash on Safari Version 15.1 (17612.2.9.1.20)

Open FranzFlueckiger opened this issue 1 year ago • 1 comments

Describe the bug

We've encountered an issue which is reproducible by following the quick start guide on the tanstack router page.

  • @tanstack/react-router has version 1.1.4
  • Safari has Version 15.1 (17612.2.9.1.20)
  • macOS Monterey 12.0.1 (21A559)
import {
  Outlet,
  RouterProvider,
  Link,
  Router,
  Route,
  RootRoute,
} from "@tanstack/react-router";

const rootRoute = new RootRoute({
  component: () => (
    <>
      <div className="p-2 flex gap-2">
        <Link to="/" className="[&.active]:font-bold">
          Home
        </Link>{" "}
        <Link to="/about" className="[&.active]:font-bold">
          About
        </Link>
      </div>
      <hr />
      <Outlet />
    </>
  ),
});

const indexRoute = new Route({
  getParentRoute: () => rootRoute,
  path: "/",
  component: function Index() {
    return (
      <div className="p-2">
        <h3>Welcome Home!</h3>
      </div>
    );
  },
});

const aboutRoute = new Route({
  getParentRoute: () => rootRoute,
  path: "/about",
  component: function About() {
    return <div className="p-2">Hello from About!</div>;
  },
});

const routeTree = rootRoute.addChildren([indexRoute, aboutRoute]);

const router = new Router({ routeTree });

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

export const App = () => <RouterProvider router={router}></RouterProvider>;

Error that we encountered is

TypeError: (this.state.pendingMatches || this.state.matches).at is not a function. (In '(this.state.pendingMatches || this.state.matches).at(-1)', '(this.state.pendingMatches || this.state.matches).at' is undefined)

Note: we tested it on a newer Safari 16.1 on macOS Sonoma and there it worked fine.

Your Example Website or App

https://github.com/FranzFlueckiger/tanstack-router-safari-issue

Steps to Reproduce the Bug or Issue

npm i npm run dev open localhost with safari with specified version expect error Bildschirmfoto 2024-01-04 um 20 46 36

Expected behavior

App runs without crashing

Screenshots or Videos

No response

Platform

  • OS: macOS Monterey 12.0.1 (21A559)
  • Browser: Safari
  • Version: 15.1 (17612.2.9.1.20)

Additional context

No response

FranzFlueckiger avatar Jan 04 '24 19:01 FranzFlueckiger

FYI: I could not reproduce on Safari Version 15.6 (17613.3.9.1.5) on macOS 12.5.

schiller-manuel avatar Jan 04 '24 20:01 schiller-manuel

This is Array.prototype.at() which is introduced in chrome 92 and safari 15.4

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at#browser_compatibility

szmazhr avatar Jan 13 '24 21:01 szmazhr

Yeah I was able to reproduce in an old chrome version.

schiller-manuel avatar Jan 13 '24 21:01 schiller-manuel

I tried adding bable to transpile the code. But don't why not working.

Then I added two things for the temporary fix. 1st tell user that he is using older version. 2nd added support for at(). below is the code.

Informing user that he is using older version of browser.

const supportedBrowsers = {
  Chrome: 92,
  Edge: 92,
  Firefox: 90,
  Opera: 78,
  Safari: 15.4,
};

const userAgent = navigator.userAgent;

for (const browser in supportedBrowsers) {
  const version = supportedBrowsers[browser as keyof typeof supportedBrowsers];
  const regex = new RegExp(`${browser}\\/([\\d.]+)`);

  if (regex.test(userAgent)) {
    const match = userAgent.match(regex);
    if (!match || parseFloat(match[1]) < version) {
      alert(
        `Your are using an outdated version of ${browser}. Please update to latest version otherwise some features may not work properly.`
      );
      break; // Stop checking other browsers once one is not supported
    }
  }
}

Polyfill for Array.prototype.at

if (!Array.prototype.at) {
  Array.prototype.at = function (index) {
    if (index >= this.length || index < -this.length) {
      return undefined;
    }

    if (index < 0) {
      index += this.length;
    }
    return this[index];
  };
}

szmazhr avatar Jan 13 '24 23:01 szmazhr