2022-09-14 18:38:58 -07:00
|
|
|
import React from "react";
|
2022-09-14 18:04:10 -07:00
|
|
|
import Head from "next/head";
|
|
|
|
import type { AppProps } from "next/app";
|
2022-09-14 19:15:48 -07:00
|
|
|
import type { NextPage } from "next";
|
2022-09-14 18:38:58 -07:00
|
|
|
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";
|
Fix /outfits/new init + add more SSR
Whew, setting up a cute GraphQL SSR system! I feel like it strikes a good balance of not having actually too many moving parts, though it's still a bit extensive for the problem we're solving 😅
Anyway, by doing SSR at _all_, we solve the problem where Next's "Automatic Static Optimization" was causing problems by setting the outfit state to the default at the start of the page load.
So I figured, why not try to SSR things _good_?
Now, when you navigate to the /outfits/new page, Next.js will go get the necessary GraphQL data to show the image before even putting the page into view. This makes the image show up all snappy-like! (when images.neopets.com is behaving :p)
We could do this with the stuff in the items panel too, but it's a tiny bit more annoying in the code right now, so I'm just gonna not worry about it and see how this performs in practice!
This change _doesn't_ include making the images actually show up before JS loads in, I assume because our JS code tries to validate that the images have loaded before fading them in on the page. Idk if we want to do something smarter there for the SSR case, to try to get them loading in faster!
2022-09-15 02:46:14 -07:00
|
|
|
import { ApolloProvider, NormalizedCacheObject } from "@apollo/client";
|
2022-09-14 18:38:58 -07:00
|
|
|
import { useAuth0 } from "@auth0/auth0-react";
|
|
|
|
import { mode } from "@chakra-ui/theme-tools";
|
|
|
|
|
|
|
|
import buildApolloClient from "../src/app/apolloClient";
|
2022-09-14 19:15:48 -07:00
|
|
|
import PageLayout from "../src/app/PageLayout";
|
|
|
|
|
|
|
|
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
[WIP] Refactor to renderWithLayout function
Okay, when I saw the recipe in the Next.js docs with `getLayout`, I was like "psh this API is so confusing, this should just be a component"
anyway now we see why it wasn't a component: the _whole point_ of it was to circumvent the usual React diffing algorithm's belief that two different components _can't_ ever share UI. But here we were, making different `layoutComponent`s that were meant to share UI, lol!
Anyway, if you just _return JSX in a function_, the React diffing algorithm never sees that it came from a different place, so it's generous when diffing them. Neat!
But I still changed the recipe's `getLayout` name to `renderWithLayout`, because it just confused me so much at first lol, I thought it was going to like, return a layout function? This is much clearer verbing to me imo
2022-09-14 22:50:56 -07:00
|
|
|
renderWithLayout?: (children: JSX.Element) => JSX.Element;
|
2022-09-14 19:15:48 -07:00
|
|
|
};
|
2022-09-14 18:38:58 -07:00
|
|
|
|
|
|
|
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",
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
});
|
[WIP] Run cra-to-next codemod to be on Nextjs
I'm interested in ejecting from Vercel, so I'm trying to get off their proprietary-ish create-react-app + Vercel API thing, and onto Nextjs, which is very similar in shape, but more portable.
I had to disable `craCompat` in `next.config.js` to stop us from crashing on their webpack config, see https://github.com/vercel/next.js/discussions/25858#discussioncomment-1573822
The frontend seems to work at a basic level, but network requests fail, and images don't seem to be working. I'll work on those next!
Note that this commit was forced through despite failing lint checks. We'll need to fix that up too!
Also, after the codemod, I moved `src/pages` to the more canonical location `pages`. Lint tooling seemed surprised to not find a `pages` directory, and I didn't see a config that was making it work correctly in the other location, so I figured it's that Next is willing to check `pages` or `src/pages`? But this is more canonical so yeah!
2021-11-01 21:48:09 -07:00
|
|
|
|
2022-09-14 19:15:48 -07:00
|
|
|
type AppPropsWithLayout = AppProps & { Component: NextPageWithLayout };
|
|
|
|
|
|
|
|
export default function DTIApp({ Component, pageProps }: AppPropsWithLayout) {
|
[WIP] Refactor to renderWithLayout function
Okay, when I saw the recipe in the Next.js docs with `getLayout`, I was like "psh this API is so confusing, this should just be a component"
anyway now we see why it wasn't a component: the _whole point_ of it was to circumvent the usual React diffing algorithm's belief that two different components _can't_ ever share UI. But here we were, making different `layoutComponent`s that were meant to share UI, lol!
Anyway, if you just _return JSX in a function_, the React diffing algorithm never sees that it came from a different place, so it's generous when diffing them. Neat!
But I still changed the recipe's `getLayout` name to `renderWithLayout`, because it just confused me so much at first lol, I thought it was going to like, return a layout function? This is much clearer verbing to me imo
2022-09-14 22:50:56 -07:00
|
|
|
const renderWithLayout =
|
|
|
|
Component.renderWithLayout ?? renderWithDefaultLayout;
|
2022-09-14 19:15:48 -07:00
|
|
|
|
2022-09-15 03:16:25 -07:00
|
|
|
// Store the *first* value of initialCacheState we get into our cache,
|
|
|
|
// because we don't want to rebuild our client and flush out everything else
|
|
|
|
// when the page changes. We set it in state here then never touch it again!
|
|
|
|
// TODO: Is there a clever way to *add* to our cache each time? The Apollo
|
|
|
|
// API suggests not really, but maybe there's a clever option...
|
|
|
|
const [initialCacheState, unusedSetInitialCacheState] = React.useState(
|
|
|
|
pageProps.graphqlState ?? {}
|
|
|
|
);
|
|
|
|
|
2022-09-14 18:38:58 -07:00
|
|
|
React.useEffect(() => setupLogging(), []);
|
|
|
|
|
[WIP] Run cra-to-next codemod to be on Nextjs
I'm interested in ejecting from Vercel, so I'm trying to get off their proprietary-ish create-react-app + Vercel API thing, and onto Nextjs, which is very similar in shape, but more portable.
I had to disable `craCompat` in `next.config.js` to stop us from crashing on their webpack config, see https://github.com/vercel/next.js/discussions/25858#discussioncomment-1573822
The frontend seems to work at a basic level, but network requests fail, and images don't seem to be working. I'll work on those next!
Note that this commit was forced through despite failing lint checks. We'll need to fix that up too!
Also, after the codemod, I moved `src/pages` to the more canonical location `pages`. Lint tooling seemed surprised to not find a `pages` directory, and I didn't see a config that was making it work correctly in the other location, so I figured it's that Next is willing to check `pages` or `src/pages`? But this is more canonical so yeah!
2021-11-01 21:48:09 -07:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Head>
|
|
|
|
<title>Dress to Impress</title>
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
</Head>
|
2022-09-14 18:04:10 -07:00
|
|
|
|
2022-09-14 18:38:58 -07:00
|
|
|
<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=""
|
|
|
|
>
|
2022-09-15 03:16:25 -07:00
|
|
|
<ApolloProviderWithAuth0 initialCacheState={initialCacheState}>
|
2022-09-14 18:38:58 -07:00
|
|
|
<ChakraProvider theme={theme}>
|
|
|
|
<CSSReset />
|
[WIP] Refactor to renderWithLayout function
Okay, when I saw the recipe in the Next.js docs with `getLayout`, I was like "psh this API is so confusing, this should just be a component"
anyway now we see why it wasn't a component: the _whole point_ of it was to circumvent the usual React diffing algorithm's belief that two different components _can't_ ever share UI. But here we were, making different `layoutComponent`s that were meant to share UI, lol!
Anyway, if you just _return JSX in a function_, the React diffing algorithm never sees that it came from a different place, so it's generous when diffing them. Neat!
But I still changed the recipe's `getLayout` name to `renderWithLayout`, because it just confused me so much at first lol, I thought it was going to like, return a layout function? This is much clearer verbing to me imo
2022-09-14 22:50:56 -07:00
|
|
|
{renderWithLayout(<Component {...pageProps} />)}
|
2022-09-14 18:38:58 -07:00
|
|
|
</ChakraProvider>
|
|
|
|
</ApolloProviderWithAuth0>
|
|
|
|
</Auth0Provider>
|
[WIP] Run cra-to-next codemod to be on Nextjs
I'm interested in ejecting from Vercel, so I'm trying to get off their proprietary-ish create-react-app + Vercel API thing, and onto Nextjs, which is very similar in shape, but more portable.
I had to disable `craCompat` in `next.config.js` to stop us from crashing on their webpack config, see https://github.com/vercel/next.js/discussions/25858#discussioncomment-1573822
The frontend seems to work at a basic level, but network requests fail, and images don't seem to be working. I'll work on those next!
Note that this commit was forced through despite failing lint checks. We'll need to fix that up too!
Also, after the codemod, I moved `src/pages` to the more canonical location `pages`. Lint tooling seemed surprised to not find a `pages` directory, and I didn't see a config that was making it work correctly in the other location, so I figured it's that Next is willing to check `pages` or `src/pages`? But this is more canonical so yeah!
2021-11-01 21:48:09 -07:00
|
|
|
</>
|
2022-09-14 18:04:10 -07:00
|
|
|
);
|
[WIP] Run cra-to-next codemod to be on Nextjs
I'm interested in ejecting from Vercel, so I'm trying to get off their proprietary-ish create-react-app + Vercel API thing, and onto Nextjs, which is very similar in shape, but more portable.
I had to disable `craCompat` in `next.config.js` to stop us from crashing on their webpack config, see https://github.com/vercel/next.js/discussions/25858#discussioncomment-1573822
The frontend seems to work at a basic level, but network requests fail, and images don't seem to be working. I'll work on those next!
Note that this commit was forced through despite failing lint checks. We'll need to fix that up too!
Also, after the codemod, I moved `src/pages` to the more canonical location `pages`. Lint tooling seemed surprised to not find a `pages` directory, and I didn't see a config that was making it work correctly in the other location, so I figured it's that Next is willing to check `pages` or `src/pages`? But this is more canonical so yeah!
2021-11-01 21:48:09 -07:00
|
|
|
}
|
2022-09-14 18:38:58 -07:00
|
|
|
|
[WIP] Refactor to renderWithLayout function
Okay, when I saw the recipe in the Next.js docs with `getLayout`, I was like "psh this API is so confusing, this should just be a component"
anyway now we see why it wasn't a component: the _whole point_ of it was to circumvent the usual React diffing algorithm's belief that two different components _can't_ ever share UI. But here we were, making different `layoutComponent`s that were meant to share UI, lol!
Anyway, if you just _return JSX in a function_, the React diffing algorithm never sees that it came from a different place, so it's generous when diffing them. Neat!
But I still changed the recipe's `getLayout` name to `renderWithLayout`, because it just confused me so much at first lol, I thought it was going to like, return a layout function? This is much clearer verbing to me imo
2022-09-14 22:50:56 -07:00
|
|
|
function renderWithDefaultLayout(children: JSX.Element) {
|
|
|
|
return <PageLayout>{children}</PageLayout>;
|
|
|
|
}
|
|
|
|
|
Fix /outfits/new init + add more SSR
Whew, setting up a cute GraphQL SSR system! I feel like it strikes a good balance of not having actually too many moving parts, though it's still a bit extensive for the problem we're solving 😅
Anyway, by doing SSR at _all_, we solve the problem where Next's "Automatic Static Optimization" was causing problems by setting the outfit state to the default at the start of the page load.
So I figured, why not try to SSR things _good_?
Now, when you navigate to the /outfits/new page, Next.js will go get the necessary GraphQL data to show the image before even putting the page into view. This makes the image show up all snappy-like! (when images.neopets.com is behaving :p)
We could do this with the stuff in the items panel too, but it's a tiny bit more annoying in the code right now, so I'm just gonna not worry about it and see how this performs in practice!
This change _doesn't_ include making the images actually show up before JS loads in, I assume because our JS code tries to validate that the images have loaded before fading them in on the page. Idk if we want to do something smarter there for the SSR case, to try to get them loading in faster!
2022-09-15 02:46:14 -07:00
|
|
|
function ApolloProviderWithAuth0({
|
|
|
|
children,
|
2022-09-15 03:16:25 -07:00
|
|
|
initialCacheState,
|
Fix /outfits/new init + add more SSR
Whew, setting up a cute GraphQL SSR system! I feel like it strikes a good balance of not having actually too many moving parts, though it's still a bit extensive for the problem we're solving 😅
Anyway, by doing SSR at _all_, we solve the problem where Next's "Automatic Static Optimization" was causing problems by setting the outfit state to the default at the start of the page load.
So I figured, why not try to SSR things _good_?
Now, when you navigate to the /outfits/new page, Next.js will go get the necessary GraphQL data to show the image before even putting the page into view. This makes the image show up all snappy-like! (when images.neopets.com is behaving :p)
We could do this with the stuff in the items panel too, but it's a tiny bit more annoying in the code right now, so I'm just gonna not worry about it and see how this performs in practice!
This change _doesn't_ include making the images actually show up before JS loads in, I assume because our JS code tries to validate that the images have loaded before fading them in on the page. Idk if we want to do something smarter there for the SSR case, to try to get them loading in faster!
2022-09-15 02:46:14 -07:00
|
|
|
}: {
|
|
|
|
children: React.ReactNode;
|
|
|
|
initialCacheState: NormalizedCacheObject;
|
|
|
|
}) {
|
2022-09-14 18:38:58 -07:00
|
|
|
const auth0 = useAuth0();
|
|
|
|
const auth0Ref = React.useRef(auth0);
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
auth0Ref.current = auth0;
|
|
|
|
}, [auth0]);
|
|
|
|
|
|
|
|
const client = React.useMemo(
|
Fix /outfits/new init + add more SSR
Whew, setting up a cute GraphQL SSR system! I feel like it strikes a good balance of not having actually too many moving parts, though it's still a bit extensive for the problem we're solving 😅
Anyway, by doing SSR at _all_, we solve the problem where Next's "Automatic Static Optimization" was causing problems by setting the outfit state to the default at the start of the page load.
So I figured, why not try to SSR things _good_?
Now, when you navigate to the /outfits/new page, Next.js will go get the necessary GraphQL data to show the image before even putting the page into view. This makes the image show up all snappy-like! (when images.neopets.com is behaving :p)
We could do this with the stuff in the items panel too, but it's a tiny bit more annoying in the code right now, so I'm just gonna not worry about it and see how this performs in practice!
This change _doesn't_ include making the images actually show up before JS loads in, I assume because our JS code tries to validate that the images have loaded before fading them in on the page. Idk if we want to do something smarter there for the SSR case, to try to get them loading in faster!
2022-09-15 02:46:14 -07:00
|
|
|
() =>
|
|
|
|
buildApolloClient({
|
|
|
|
getAuth0: () => auth0Ref.current,
|
|
|
|
initialCacheState,
|
|
|
|
}),
|
|
|
|
[initialCacheState]
|
2022-09-14 18:38:58 -07:00
|
|
|
);
|
|
|
|
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,
|
|
|
|
});
|
|
|
|
}
|