April 18, 2022
Since Next.js v9.3, getInitialProps
used for data fetching has been divided into getStaticProps
and getServerSideProps
. According to the Next.js official documentation regarding custom App, using getInitialProps
in _app.tsx
disables the feature of Automatic Static Optimization and is discouraged.
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
// // calls page's `getInitialProps` and fills `appProps.pageProps`
// const appProps = await App.getInitialProps(appContext);
//
// return { ...appProps }
// }
export default MyApp
Automatic Static Optimization refers to Next.js recognizing pages without getInitialProps
or getServerSideProps
as static pages during build time, rendering them as HTML files. This pre-rendering process enables users to quickly view the pages without requiring server-side rendering upon each request.
Example of Next.js build output
.next/server/static/about.html
Conversely, if getInitialProps
or getServerSideProps
exists, Next.js generates .js
files instead of .html
during build. When a user makes a request, Next.js then performs server-side rendering to fetch necessary data before returning the completed HTML.
Example of Next.js build output
.next/server/static/about.js
Thus, including getInitialProps
in _app.tsx
prevents any page from being recognized as a static page during build, thereby disabling Automatic Static Optimization.
In my case, to implement a dynamic web application, I was invoking getServerSideProps
across all pages. This setup prevented any static pages from being created, disabling Automatic Static Optimization and resulting in repetitive code and complex logic. To address this, I decided to use getInitialProps
in _app.tsx
.
Here’s the Server-Side Cycle for loading pages:
getInitialProps
in _app.tsx
if defined.getInitialProps
in the Page Component if defined, fetching pageProps
.getInitialProps
in _document.js
if defined, fetching pageProps
._app.js
> Page Component._document.js
, outputting the HTML format.In this process, if both _app.tsx
and page.tsx
define getInitialProps
or getServerSideProps
, the pageProps
fetched from page.tsx
will overwrite those from _app.tsx
. Therefore, _app.tsx
’s getInitialProps
needs to be customized accordingly.
import type { AppContext } from 'next/app'
function MyApp({ Component, pageProps }: AppProps): ReactElement {
const queryClient = new QueryClient()
const { theme } = pageProps as { theme: Theme }
return (
...
)
}
MyApp.getInitialProps = async ({ Component, ctx }: AppContext) => {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
const theme = await fetchTheme(ctx.req?.headers.referer)
pageProps = { ...pageProps, theme }
return { pageProps }
}
export default MyApp
As shown above, {...pageProps, data}
combines the pageProps
received from fetching page.tsx
with the theme data fetched from _app.tsx
, ensuring they are passed together.
https://velog.io/@cyranocoding/Next-js-%EA%B5%AC%EB%8F%99%EB%B0%A9%EC%8B%9D-%EA%B3%BC-getInitialProps https://nextjs.org/docs/advanced-features/custom-app https://simsimjae.medium.com/next-js-automatic-static-optimization-b56ba8febea8