I am trying to understand why Next.js is building some of my pages as SSG and some of them as Static, when they all are using getStaticProps.
Let's take my 404 page that uses getStaticProps to fetch data from prismic with graphql. It is being rendered as a Static website when in my opinion it should be rendered as SSG (because it uses getStaticProps).
I am doing the EXACT same thing in my 500 page, but with a different graphql query and it is being rendered (in my opinion correctly) as SSG.
Why is that?
404 page:
const NotFound = ({ data: { page } }) => {
return (
<div className={'not-found'}>
<p className={'not-found__description'}>{RichText.asText(page.description)}</p>
</div>
);
};
export const getStaticProps = async (context) => {
const currentLanguage = getCurrentLocale(context);
const response = await apolloClient.query({
query: gql`
query {
}
`
};
return {
props: {
data: {
page: response
}
}
}
});
export default NotFound;
500 page:
const InternalServerError = ({ data: { page } }) => {
return (
<div className={'internal-server-error'}>
<p className={'internal-server-error__description'}>{RichText.asText(page.description)}</p>
</div>
);
};
export const getStaticProps = async (context) => {
const currentLanguage = getCurrentLocale(context);
const response = await apolloClient.query({
query: gql`
query {
}
`
});
return {
props: {
data: {
page: response
}
}
}
};
The 404.tsx or 404.js page in Next.js is unique in that it does not rely on the server and is always Static -- relying solely on static html (no json) at build time -- even when using
GetStaticProps
in the file.The 404 page is simply a catch all
funnel
route that users are redirected to when navigating to paths that do not exist with your site as the base URL. So, it doesn't rely on the server on initial build. It's the fallback for paths not existing, and nothing else. The 500 page, on the other hand, handles an internal error in your application so it does rely on both.html
and.json
file types to pinpoint the nature of the error.Interestingly, if you examine the contents of your
.next
directory locally, you'll notice that all pages usingGetStaticProps
have.json
and.html
files statically generated. Pages usingGetStaticProps
withrevalidate
returned ===Incremental Static Regeneration
, orISR
.ISR
is an ideal hybrid ofSSG
andSSR
, having background functions scanning for incoming changes/updates in production (the number you specify being the amount of time in seconds between possible updates). So, pages withGetStaticProps
+ISR
generate three file types in the.next
directory --.html
,.json
, and.js
. That said, Pages usingGetServerSideProps
orGetInitialProps
have only.js
files generated in the.next
directory. Lastly, pages that are purelyStatic
, using none of the aforementioned methods, have only.html
files generated.The idea behind the 404 page and its Static nature is to enhance UX by expediting the rendering (or more correctly prerendering) of a custom
oops! that path doesn't exist
page so that a user can return to the actual application asap.For example, I have the following in my
404.tsx
page, but it still renders as Statichtml
at build time.Interestingly, because I do use
GetStaticProps
andrevalidate
forISR
in my404.tsx
page, the contents of the.next
directory reflects this as all three file types are present for404
(.js, .json, .html
). If you usegetInitialProps
in your custom_app.tsx
or_app.js
file, then automatic static optimization (the prerendering of static pages) will be disabled across the entirety of your app. Give it a try if you're curious, it should cause the 404 page to have a lambda next to it in your build log. However, since you already haveGetStaticProps
that should override the app-wide static deoptimization caused by your rootapp
page usingGetInitialProps
For example, I used
GetInitialProps
in_app.tsx
prior to creating a custom404.tsx
page some time back. I decided to pull the build logs and took an accompanying screen shot.