Move a lot of App.js stuff into Next's _app.tsx

Just sorta idly poking at what it would take to make our Next setup a bit more normal. To start, I'm putting things in more of the normal place, and eyeing what it would take to switch to Next's built-in routing! So now `App.js` is pretty much entirely a routing file, potentially to be deleted once we move 🤔
This commit is contained in:
Emi Matchu 2022-09-14 18:38:58 -07:00
parent 98c1034eff
commit 8cd45d7082
5 changed files with 184 additions and 181 deletions

View file

@ -1,4 +1,5 @@
module.exports = { module.exports = {
reactStrictMode: true,
env: { env: {
PUBLIC_URL: "", PUBLIC_URL: "",
}, },

View file

@ -1,4 +1,4 @@
// import NextIndexWrapper from '../src' // import App from '../src'
// next/dynamic is used to prevent breaking incompatibilities // next/dynamic is used to prevent breaking incompatibilities
// with SSR from window.SOME_VAR usage, if this is not used // with SSR from window.SOME_VAR usage, if this is not used
@ -8,8 +8,8 @@ import dynamic from "next/dynamic";
// try changing "ssr" to true below to test for incompatibilities, if // try changing "ssr" to true below to test for incompatibilities, if
// no errors occur the above static import can be used instead and the // no errors occur the above static import can be used instead and the
// below removed // below removed
const NextIndexWrapper = dynamic(() => import("../src"), { ssr: false }); const App = dynamic(() => import("../src/app/App"), { ssr: false });
export default function Page(props: any) { export default function Page(props: any) {
return <NextIndexWrapper {...props} />; return <App {...props} />;
} }

View file

@ -1,7 +1,37 @@
import React from "react";
import Head from "next/head"; import Head from "next/head";
import type { AppProps } from "next/app"; import type { AppProps } from "next/app";
import * as Sentry from "@sentry/react";
import { Integrations } from "@sentry/tracing";
import { Auth0Provider } from "@auth0/auth0-react";
import { CSSReset, ChakraProvider, extendTheme } from "@chakra-ui/react";
import { ApolloProvider } from "@apollo/client";
import { useAuth0 } from "@auth0/auth0-react";
import { mode } from "@chakra-ui/theme-tools";
import buildApolloClient from "../src/app/apolloClient";
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",
},
}),
},
});
export default function DTIApp({ Component, pageProps }: AppProps) { export default function DTIApp({ Component, pageProps }: AppProps) {
React.useEffect(() => setupLogging(), []);
return ( return (
<> <>
<Head> <Head>
@ -9,7 +39,81 @@ export default function DTIApp({ Component, pageProps }: AppProps) {
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
</Head> </Head>
<Component {...pageProps} /> <Auth0Provider
domain="openneo.us.auth0.com"
clientId="8LjFauVox7shDxVufQqnviUIywMuuC4r"
redirectUri={
process.env.NODE_ENV === "development"
? "http://localhost:3000"
: "https://impress-2020.openneo.net"
}
audience="https://impress-2020.openneo.net/api"
scope=""
>
<ApolloProviderWithAuth0>
<ChakraProvider theme={theme}>
<CSSReset />
<Component {...pageProps} />
</ChakraProvider>
</ApolloProviderWithAuth0>
</Auth0Provider>
</> </>
); );
} }
function ApolloProviderWithAuth0({ children }: { children: React.ReactNode }) {
const auth0 = useAuth0();
const auth0Ref = React.useRef(auth0);
React.useEffect(() => {
auth0Ref.current = auth0;
}, [auth0]);
const client = React.useMemo(
() => buildApolloClient(() => auth0Ref.current),
[]
);
return <ApolloProvider client={client}>{children}</ApolloProvider>;
}
function setupLogging() {
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,
}),
],
denyUrls: [
// Don't log errors that were probably triggered by extensions and not by
// our own app. (Apparently Sentry's setting to ignore browser extension
// errors doesn't do this anywhere near as consistently as I'd expect?)
//
// Adapted from https://gist.github.com/impressiver/5092952, as linked in
// https://docs.sentry.io/platforms/javascript/configuration/filtering/.
/^chrome-extension:\/\//,
/^moz-extension:\/\//,
],
// 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,
});
}

View file

@ -1,19 +1,12 @@
import React from "react"; import React from "react";
import { ApolloProvider } from "@apollo/client"; import { Box } from "@chakra-ui/react";
import { Auth0Provider } from "@auth0/auth0-react";
import { CSSReset, ChakraProvider, extendTheme, Box } from "@chakra-ui/react";
import { mode } from "@chakra-ui/theme-tools";
import { import {
BrowserRouter as Router, BrowserRouter as Router,
Switch, Switch,
Route, Route,
useLocation, useLocation,
} from "react-router-dom"; } from "react-router-dom";
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 PageLayout from "./PageLayout";
import WardrobePageLayout from "./WardrobePage/WardrobePageLayout"; import WardrobePageLayout from "./WardrobePage/WardrobePageLayout";
import { loadable } from "./util"; import { loadable } from "./util";
@ -56,64 +49,6 @@ const ItemSearchPageToolbar = loadable(
{ fallback: <Box height="40px" /> } { fallback: <Box height="40px" /> }
); );
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,
}),
],
denyUrls: [
// Don't log errors that were probably triggered by extensions and not by
// our own app. (Apparently Sentry's setting to ignore browser extension
// errors doesn't do this anywhere near as consistently as I'd expect?)
//
// Adapted from https://gist.github.com/impressiver/5092952, as linked in
// https://docs.sentry.io/platforms/javascript/configuration/filtering/.
/^chrome-extension:\/\//,
/^moz-extension:\/\//,
],
// 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 * 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! * stuff happening here, mostly just setting up some globals and theming!
@ -124,92 +59,80 @@ function App() {
return ( return (
<Router> <Router>
<ScrollToTop /> <ScrollToTop />
<Auth0Provider
domain="openneo.us.auth0.com" <Switch>
clientId="8LjFauVox7shDxVufQqnviUIywMuuC4r" <Route path="/items/search/:query?">
redirectUri={window.location.origin} <PageLayout>
audience="https://impress-2020.openneo.net/api" <ItemSearchPageToolbar marginBottom="6" />
scope="" <ItemSearchPage />
> </PageLayout>
<ApolloProviderWithAuth0> </Route>
<ChakraProvider theme={theme}> <Route path="/items/:itemId/trades/offering">
<CSSReset /> <PageLayout>
<Switch> <ItemTradesOfferingPage />
<Route path="/items/search/:query?"> </PageLayout>
<PageLayout> </Route>
<ItemSearchPageToolbar marginBottom="6" /> <Route path="/items/:itemId/trades/seeking">
<ItemSearchPage /> <PageLayout>
</PageLayout> <ItemTradesSeekingPage />
</Route> </PageLayout>
<Route path="/items/:itemId/trades/offering"> </Route>
<PageLayout> <Route path="/items/:itemId">
<ItemTradesOfferingPage /> <PageLayout>
</PageLayout> <ItemSearchPageToolbar marginBottom="8" />
</Route> <ItemPage />
<Route path="/items/:itemId/trades/seeking"> </PageLayout>
<PageLayout> </Route>
<ItemTradesSeekingPage /> <Route path="/outfits/new">
</PageLayout> <WardrobePage />
</Route> </Route>
<Route path="/items/:itemId"> <Route path="/outfits/:id">
<PageLayout> <WardrobePage />
<ItemSearchPageToolbar marginBottom="8" /> </Route>
<ItemPage /> <Route path="/user/:userId/lists/:ownsOrWants(owns|wants)/:listId">
</PageLayout> <PageLayout>
</Route> <UserItemListPage />
<Route path="/outfits/new"> </PageLayout>
<WardrobePage /> </Route>
</Route> <Route path="/user/:userId/lists">
<Route path="/outfits/:id"> <PageLayout>
<WardrobePage /> <UserItemListsIndexPage />
</Route> </PageLayout>
<Route path="/user/:userId/lists/:ownsOrWants(owns|wants)/:listId"> </Route>
<PageLayout> <Route path="/your-outfits">
<UserItemListPage /> <PageLayout>
</PageLayout> <UserOutfitsPage />
</Route> </PageLayout>
<Route path="/user/:userId/lists"> </Route>
<PageLayout> <Route path="/modeling">
<UserItemListsIndexPage /> <PageLayout>
</PageLayout> <ModelingPage />
</Route> </PageLayout>
<Route path="/your-outfits"> </Route>
<PageLayout> <Route path="/privacy">
<UserOutfitsPage /> <PageLayout>
</PageLayout> <PrivacyPolicyPage />
</Route> </PageLayout>
<Route path="/modeling"> </Route>
<PageLayout> <Route path="/conversion">
<ModelingPage /> <PageLayout>
</PageLayout> <ConversionPage />
</Route> </PageLayout>
<Route path="/privacy"> </Route>
<PageLayout> <Route path="/support/petAppearances">
<PrivacyPolicyPage /> <PageLayout>
</PageLayout> <SupportPetAppearancesPage />
</Route> </PageLayout>
<Route path="/conversion"> </Route>
<PageLayout> <Route path="/internal/assetImage">
<ConversionPage /> <InternalAssetImagePage />
</PageLayout> </Route>
</Route> <Route path="/">
<Route path="/support/petAppearances"> <PageLayout hideHomeLink>
<PageLayout> <HomePage />
<SupportPetAppearancesPage /> </PageLayout>
</PageLayout> </Route>
</Route> </Switch>
<Route path="/internal/assetImage">
<InternalAssetImagePage />
</Route>
<Route path="/">
<PageLayout hideHomeLink>
<HomePage />
</PageLayout>
</Route>
</Switch>
</ChakraProvider>
</ApolloProviderWithAuth0>
</Auth0Provider>
</Router> </Router>
); );
} }
@ -224,19 +147,4 @@ function ScrollToTop() {
return null; 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 <ApolloProvider client={client}>{children}</ApolloProvider>;
}
export default App; export default App;

View file

@ -1,10 +0,0 @@
import React from "react";
import App from "./app/App";
export default function NextIndexWrapper() {
return (
<React.StrictMode>
<App />
</React.StrictMode>
);
}