import React from "react"; import { ApolloProvider } from "@apollo/client"; import { Auth0Provider } from "@auth0/auth0-react"; import { CSSReset, ChakraProvider, extendTheme } from "@chakra-ui/react"; import { mode } from "@chakra-ui/theme-tools"; import { BrowserRouter as Router, Switch, Route, useLocation, } from "react-router-dom"; import loadable from "@loadable/component"; import * as Sentry from "@sentry/react"; import { Integrations } from "@sentry/tracing"; import { useAuth0 } from "@auth0/auth0-react"; import buildApolloClient from "./apolloClient"; import PageLayout from "./PageLayout"; import WardrobePageLayout from "./WardrobePage/WardrobePageLayout"; // Loading the page will often fail after a deploy, because Vercel doesn't keep // old JS chunks on the CDN. Recover by reloading! const tryLoadable = (load, options) => loadable( () => load().catch((e) => { console.error("Error loading page, reloading", e); window.location.reload(); }), options ); const ConversionPage = tryLoadable(() => import("./ConversionPage")); const HomePage = tryLoadable(() => import("./HomePage")); const ItemSearchPage = tryLoadable(() => import("./ItemSearchPage")); const ItemPage = tryLoadable(() => import("./ItemPage")); const ItemTradesOfferingPage = tryLoadable(() => import("./ItemTradesPage").then((m) => m.ItemTradesOfferingPage) ); const ItemTradesSeekingPage = tryLoadable(() => import("./ItemTradesPage").then((m) => m.ItemTradesSeekingPage) ); const ModelingPage = tryLoadable(() => import("./ModelingPage")); const PrivacyPolicyPage = tryLoadable(() => import("./PrivacyPolicyPage")); const UserItemsPage = tryLoadable(() => import("./UserItemsPage")); const UserOutfitsPage = tryLoadable(() => import("./UserOutfitsPage")); const WardrobePage = tryLoadable(() => import("./WardrobePage"), { fallback: , }); const theme = extendTheme({ styles: { global: (props) => ({ html: { // HACK: Chakra sets body as the relative position element, which is // fine, except its `min-height: 100%` doesn't actually work // unless paired with height on the root element too! height: "100%", }, body: { background: mode("gray.50", "gray.800")(props), color: mode("green.800", "green.50")(props), transition: "all 0.25s", }, }), }, }); Sentry.init({ dsn: "https://c55875c3b0904264a1a99e5b741a221e@o506079.ingest.sentry.io/5595379", autoSessionTracking: true, integrations: [ new Integrations.BrowserTracing({ beforeNavigate: (context) => ({ ...context, // Assume any path segment starting with a digit is an ID, and replace // it with `:id`. This will help group related routes in Sentry stats. // NOTE: I'm a bit uncertain about the timing on this for tracking // client-side navs... but we now only track first-time // pageloads, and it definitely works correctly for them! name: window.location.pathname.replaceAll(/\/[0-9][^/]*/g, "/:id"), }), // We have a _lot_ of location changes that don't actually signify useful // navigations, like in the wardrobe page. It could be useful to trace // them with better filtering someday, but frankly we don't use the perf // features besides Web Vitals right now, and those only get tracked on // first-time pageloads, anyway. So, don't track client-side navs! startTransactionOnLocationChange: false, }), ], // Since we're only tracking first-page loads and not navigations, 100% // sampling isn't actually so much! Tune down if it becomes a problem, tho. tracesSampleRate: 1.0, }); /** * App is the entry point of our application. There's not a ton of exciting * stuff happening here, mostly just setting up some globals and theming! * * To really dive into the code, try going down into a page component! */ function App() { return ( ); } /** * ScrollToTop scrolls to the top of the page when you navigate. * Copied from https://reactrouter.com/web/guides/scroll-restoration/scroll-to-top. */ function ScrollToTop() { const { pathname } = useLocation(); React.useEffect(() => window.scrollTo(0, 0), [pathname]); return null; } function ApolloProviderWithAuth0({ children }) { const auth0 = useAuth0(); const auth0Ref = React.useRef(auth0); React.useEffect(() => { auth0Ref.current = auth0; }, [auth0]); const client = React.useMemo( () => buildApolloClient(() => auth0Ref.current), [] ); return {children}; } export default App;