I've been using NextJS for a while, but don't fully get how its SSR process really works.
I've put a console.log inside some components return method, and I see that those are executed on the client side. Shouldn't these be displayed on the server's console instead because SSR is being used?
Also, when I try to console.log the window object, NextJS throws an error saying that window is not defined. That left me more confused, because according to my previous test, console.log is running on the client side, but according to this error, it is running on the server.
If you've set up React components to render on the server (which you should for non static sites), when code executes on the server in NodeJS, there is no window object. That only exists in the browser. You need to account for that in SSR components.
There are features of Next to control when components are available to the client or server only, like dynamic imports.
In the end, on the server, Next is mostly doing renderToString, and serving the HTML from the server, no different than any other webserver serving HTML.
Once in the client, React "hydrates" the rendered DOM, as in it re-runs React over the HTML created by the server. It doesn't change the DOM, but it does add things like interactivity, click handlers, etc, that you've defined for your app.
Server side nextjs generates .js in your .next directory if it is GetServerSideProps. If it is ISR (GetStaticProps + revalidate), then it generates .html, .json, and .js files in the .next directory for that page (or those pages if dynamic). If using GetStaticProps sans revalidate, it generates .html and .json in the .next directory. If using no server side rendering method (e.g., GetStaticProps or GetServerSideProps) then it only generates .html at build time (automatic static optimization).
There is more to it, but this is what I've noticed from inspecting the contents of the output pages in the .next directory
Related
I know that it is not possible to serve a react app, using live server. In other words, even though the js is bundled and linked to the HTML file, if you open the file statically, the react code will not render.
I read about static and dynamic servers, but since React happens all on client side, I cannot understand why serving the app using webpack, vite or even a simple express server works, but it cannot be served through a server like live server, or opened manually and work.
What is the difference?
The difference is in how the JavaScript code is executed in the browser. When you serve your React app through a webpack dev server, an express server, or any other kind of server, the JavaScript code is executed in the context of a web page, with access to the DOM and all the Web APIs.
But when you open an HTML file statically, the JavaScript code is executed in an isolated environment, with limited access to the Web API. This is why React code that relies on the DOM and Web API will not work when opened manually.
Webpack, vite, and express provide a dynamic environment with all the necessary APIs and services that React needs to run properly. This is done by serving the app as a web page over HTTP, which the browser then loads and executes.
I was trying out the new features from Next.js 13 and I can't explain to myself, why Client Components still use SSR. I thought that using Client Components would result in Components that are only rendered on the client.
Can anyone explain, how that exactly works?
Thanks
Server-side rendering basically means fetching the data on the server. So when the server sends the html to the browser, it already populates the HTML, so the search crawler will see HTML with populated data so your page will be indexed higher. Once the HTML is sent down to the browser, the browser will parse the HTML and your page will have javascript interactivity, onClick, mouseOver etc. All the client components in next.js uses ssr.
But the server component is a different concept. Entire HTML is rendered on the server so any dependency used on the server will stay on the server. So your browser will not have to parse HTML and go through all javascript. so client bundle size will decrease and your app performance will increase.
We created a react js application.
Problem: Not able to hit react URL from the postman to run component's function.
local URL: http://localhost:3000/rules/routine
Note: Above URL can be reached without login.
When we are calling a url from browser it's working however when we hit from a postman then it always returns public/index.html page but not the expected response.
So it is not calling the proper url http://localhost:3000/rules/routine.
Please find attached screenshots on below links
browser hit: https://prnt.sc/73gDWh4PiHgu
Postman hit: https://prnt.sc/fhVL78yaiATP
It's technically possible, and working it seems, but I suspect your expectations are a little skewed in what you think Postman will do or is capable of.
Keep in mind that all React apps are effectively a single page app, even when they use a routing/navigation package like react-router. react-router is only manipulating the URL in the address bar in the browser window, the app is still running from the single location on a server where it's hosted, i.e. public/index.html.
The servers hosting the app are configured to route all page requests, i.e. "http://localhost:3000/rules/routine" to the root index file, i.e. "http://localhost:3000/index.html" so the React app is loaded and can handle the "/rules/routine" internally.
So from what I see here, the response from Postman is absolutely correct and what I'd expect to see. It made a request to the development server for a nested directory "/rules/routing" and the server responded with the root index.html file. When the browser makes this request to the development server and gets a HTML file back it loads and renders it, and in this case, it's your React app.
Postman isn't a browser so it's not going to load the HTML response and do anything with it.
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.
I am using webpack to bundle a react app in a js file which I want add to client site. So I end up with a app.js and I can provide a url for where the file is hosted to clients https://example.mysite.com/apps/app.js and this can be included via a script tag on client site. Simple enough.
The issue I might run into here is browser side caching. I can't use version tags here because asking a client to continuously update code on their site is not a realistic expectation.
Webpack hashing is also not an option because this would mean updating the file on the client side, which again is something I would like to work around.
Is there a way to prevent my app.js file from being cached and fetching a new version of the file every time the app.js file has changed?