NextJS SSG with dynamic route from Firebase [duplicate] - reactjs

I have a MERN app in which I have integrated NextJS. First time with NextJS so bear with me. I have initially used SSR everywhere (getServerSideProps).
Key points:
I have over 150,000 pages with static content that it's never going to change.
Every week I add around +100 new pages.
I guess the ideal situation here would be using getStaticProps and getStaticPaths and, after an initial build of those 150k pages, just build the new added pages every week and keep what I already have built as it is since it's never going to change.
How can I achieve this? Should I use revalidate here? I have been reading about it in the documentation but I don't completely understand it.

That can be achieved with getStaticProps/getStaticPaths. You'll have to use fallback: true or fallback: 'blocking' in getStaticPaths.
With fallback: true the paths not generated at build time will serve a fallback page on the first request while Next.js statically generates the page. When this is done the page will be swapped from the fallback page to the actual full page.
With fallback: 'blocking', the paths not generated at build time will wait for the HTML to be generated by Next.js, then serve the page once that's done. Unlike fallback: true, since there's no fallback the rendering gets blocked until the page is generated, similar to what happens during server-side rendering.
In both cases the page gets added to the list of pre-rendered pages. Subsequent requests to the same path will serve the pre-generated page.
Neither of these options is supported by next export, in case you depend on that.
Note that revalidate is used in getStaticProps for Incremental Static Regeneration - in cases where you'd want to update existing, generated pages. Since you mentioned generated pages will never change, then there's no need to use revalidate.

Related

Load order of javascript files listed in app.json

I've recently added jquery and I need to use it on some pages in my app that don't use ExtJS as well as within ExtJS. So I used the option "includeInBundle": false and made sure to list it above app.js. What I noticed is that when I bundle the app the first time and try to access, I get errors (screenshots from console below). What I can see is that app.js is loading before jquery-3.6.0.js, even though I have jquery listed before in my app.json. If I reload the page, it then loads fine (not sure if it's because it's then cached and gets loaded faster). How can I ensure that libraries always load in the correct order?

I have to build blog website again to update it after creating new blog [duplicate]

I have a MERN app in which I have integrated NextJS. First time with NextJS so bear with me. I have initially used SSR everywhere (getServerSideProps).
Key points:
I have over 150,000 pages with static content that it's never going to change.
Every week I add around +100 new pages.
I guess the ideal situation here would be using getStaticProps and getStaticPaths and, after an initial build of those 150k pages, just build the new added pages every week and keep what I already have built as it is since it's never going to change.
How can I achieve this? Should I use revalidate here? I have been reading about it in the documentation but I don't completely understand it.
That can be achieved with getStaticProps/getStaticPaths. You'll have to use fallback: true or fallback: 'blocking' in getStaticPaths.
With fallback: true the paths not generated at build time will serve a fallback page on the first request while Next.js statically generates the page. When this is done the page will be swapped from the fallback page to the actual full page.
With fallback: 'blocking', the paths not generated at build time will wait for the HTML to be generated by Next.js, then serve the page once that's done. Unlike fallback: true, since there's no fallback the rendering gets blocked until the page is generated, similar to what happens during server-side rendering.
In both cases the page gets added to the list of pre-rendered pages. Subsequent requests to the same path will serve the pre-generated page.
Neither of these options is supported by next export, in case you depend on that.
Note that revalidate is used in getStaticProps for Incremental Static Regeneration - in cases where you'd want to update existing, generated pages. Since you mentioned generated pages will never change, then there's no need to use revalidate.

Next.js getInitialProps() method not called when reloading static page

I’m building a static site in Next.js. As static sites produce pages with the .html extension, I’m using the as attribute on my Link elements, which allow my pages to be reloaded.
I have now introduced the use of query strings to my URL’s so that, when the pages are reloaded, they remember what content to display, by use of the getInitialProps() method.
So far, so good, BUT ONLY DURING DEVELOPMENT.
The problem I face is, when the site is exported out as the static version, Next.js fails to call the getInitialProps() method, hence, when the browser is refreshed, my pages no longer know what to display.
Can anybody help with any of the following:
Is there another way to allow static pages to be refreshed, without the use of the .html extension?
Is there a way to ensure that the getInitialProps() method is called when exporting a static site and when reloading a page?
Is there another way in which I can retrieve the query string from the browser URL, as Next.js doesn’t seem to have the ability to access even the top level window object?
getInitialProps is only available on server-side rendered apps. It runs during development because Next doesn't know if you want your pages to be static or SSR. But when you run next build && next export, they become static and getInitialProps no longer runs. I believe this is also why next switched to getServerSideProps and getStaticProps instead of getInitialProps (for everything but the _app.js page)
In response to your list of questions:
Next exports so that you don't have to use/show the HTML extension, but that also depends on your hosting setup. Exporting a static site exports .html files, but it's up to your hosting configuration to determine whether or not those are shown.
See above and no - there is no way to have getInitialProps run on a fully static, exported site. You'd need to switch to a server-side rendered site if you have to use getInitialProps.
Your static site can retrieve the query string, but it's not going to have it at build time. Instead, you'd need to check for it (usually in React.useEffect) when the window object is available. On a static site, that's not at buildtime but only at runtime. Check out this answer on how to get the query string in javascript - you can use this in your useEffect.

How is server-side rendering compatible with single-page applications?

My problem is that I'm unable to understand how server-side rendering single-page application frameworks like Next.js receive prerendered, full HTML on the front end without having to rewrite the entire page. For example, the nextjs website states the following:
By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
I understand how this bolsters the responsiveness of an SPA on first page load. But after that first load, what makes server-side rendering compatible with SPAs? I think this arises from a fundamental misunderstanding that I can't catch, so here are some further questions I have that might help you to catch it:
Do SSR SPAs always respond with full prerendered HTML, or only for first page loads?
If the former is true, then on subsequent responses, how does the client efficiently render only the difference rather than rewriting the whole page?
Otherwise, if the latter is true, then how does an SSR SPA backend tell when it's responding to a first request, when the response should be the whole HTML, versus a subsequent request, when the bulk of the page is already there and all that needs to be sent is some relatively minimal information?
What am I misunderstanding about what makes SSR compatible with SPAs?
Many thanks in advance to everyone who tackles this question!
Welcome to Stackoverflow :)
Usually SSR is used for initial rendering of the page, so for the first question - for the first page load
This is necessary, so the SPA will be more SEO-compatible (there also might be some performance improvements with this, but it's usually secondary goal) and Search Engine bots will be able to parse pages without the need for JS
The SSR usually has several important steps:
Server render
Sending of rendered data to browser
Hydration. Hydration - is a ReactJS (since we're talking about next.js here) 'function' that binds the server-rendered HTML to the React on the Frontend. So basically binds server-rendered DOM to virtualDOM
After the hydration step you basically have a fully-functional normal SPA, which has it's own routing and able to fetch data on itself.
Usually you have different endpoint on the BE to fetch the data and to render the page. So basically the rendering process on the BE is somewhat similar to what you have on the FE - your application backend fetches the data from separate endpoints, applies all of the logic and renders the app.
Btw, to ensure that SSR works properly, there is a principle called 'Isomorphic code' - i.e. if you're using a library for data fetching, it has to support both node.js and browser APIs. That's why, for example, you'd have to use Next.js own Router when you have a Next.js application - it just works on both FE and BE unlike react-router, which would require some additional steps to achieve that

When exactly is Next.js “build-time” happening?

I'm reading Next.js fetching data part of the documentation and one question came to my mind.
Next.js can fetch data with getStaticProps, getStaticPaths, getInitialProps and getServerSideProps, right?
But some happens on Build-time as I quote:
getStaticProps (Static Generation): Fetch data at build-time
When is this Build-time happening?
Is it when we run npm run build? (To build the production build)
Or when the user accesses our Next.js app? (On each request)
Build time happens when you're building the app for production (next build). Runtime happens when the app is running in production (next start).
getInitialProps (gIP) runs on both the client and the server during runtime for every page request. Most common use case is retrieving some sort of shared data (like a session that lets the client and server know if a user is navigating to a specific page) before the requested page loads. This always runs before getServerSideProps. While its usage is technically discouraged, sometimes it absolutely necessary to do some logic on both the client and server.
getServerSideProps (gSSP) only runs on the server during runtime for every page request. Most common use case would be to retrieve up-to-date, page-specific data (like a product's pricing and displaying how much of it is in stock) from a database before a page loads. This is important when you want a page to be search engine optimized (SEO), where the search engine indexes the most up-to-date site data (we wouldn't want our product to show "In stock - 100 units," when it's actually a discontinued product!).
getStaticProps (gSProps) only runs during build-time (sort of). It's great for sites whose data and pages don't update that often. The advantage of this approach is the page is statically generated, so if a user requests the page, they'll download an optimized page where the dynamic data is already baked into it. Most common use case would be a blog or some sort of large shopping catalog of products that may not change that often.
getStaticPaths (gSPaths) only runs during build-time (sort of). It's great for pre-rendering similar paths (like a /blog/:id) that require dynamic data to be used at build-time. When used in conjunction with gSProps, it generates the dynamic pages from a database/flat file/some sort of data structure, which Next can then statically serve. An example use case would be a blog that has many blog posts which share the same page layout and similar page URL structure, but require the content to be dynamically baked into the page when the app is being built.
Why are gSProps and gSPaths sort of ran during build-time? Well, Next introduced revalidate with fallback options that allows these two Nextjs functions to be ran during runtime after a timeout in seconds. This is useful if you want your page to be statically regenerated, but it should only be regenerated every n amount of seconds. The upside is that the page doesn't need to request dynamic data when navigated to, but the downside is that the page may initially show stale data. A page won't be regenerated until a user visits it (to trigger the revalidation), and then the same user (or another user) visits the same page to see the most up-to-date version of it. This has the unavoidable consequence of User A seeing stale data while user B sees accurate data. For some apps, this is no big deal, for others it's unacceptable(†).
† If you're using a version of Next v12.2.0+, you can use On-demand Revalidation to mitigate a stale static page from being shown to users if/when its data has been updated.
And lastly, there's client-side rendering (CSR) which are assets requested at run-time on the client (the browser) which aren't vital for SEO or can't be run on the server-side (like attaching an Event Listener to the document; this can't be done because server's don't have DOMs). Most common use case would be a user-specific dashboard page that is only relevant to that user and therefore doesn't need to be indexed by a search engine or some sort of JavaScript that manipulates the DOM and therefore can't be run on the server.
Other things of note: gIP and gSSP are render blocking. Meaning, the page won't load until their code resolves/returns props. This has the unavoidable consequence of showing a blank page before the page loads. This also means slower page response times where: Page is requested, gIP/gSSP runs code that blocks page from loading, gIP/gSSP code resolves, assets are then downloaded, page begins to load the JavaScript on the client while the HTML is being loaded into the DOM, JavaScript is done running, page is then rehydrated and then it becomes interactive. In summation, this results in a slower TTI.

Resources