If you already have a subscription, you can sign in.
Enjoy free content straight from your inbox 💌
00:00
A common request for advanced use cases is the ability to detect if your next JS application code is executing on a server or a client environment. We know that once deployed our next JS application first executes on the server and then after it sends the initial response to the client, react hydrates a user interface and starts executing it on the browser while it's executing on the server. You might access some data using a database driver, but when you are executing the same code on the client, you would need to access that information using an HTP call to an API. So essentially you can abstract this behind a utility
00:33
that might choose to do different things based on the environment it is currently executing in. Fortunately, it's not that hard to detect the runtime environment. A simple way to achieve this is by checking the presence of some global feature that is only present on the server or only present on the client. A common one that people use is the global window variable, which is something that is only present on the browser. So if window is not undefined, then we are guaranteed to be on the client. Let's build a simple component that uses this variable to render a different text message on the client and a different one on the server.
01:04
To demonstrate that this functions correctly, we will render it in a server environment and then in a client only environment to demonstrate it in a server environment, we import it into a server page and within our page function, we simply render out this component as we've demonstrated in our server versus client component lessons. This code will actually only ever execute on the server. Now let's create another page and render this component in a client only fashion. And as we've demonstrated in our lesson on client only components, we need to do two things. We need to be within the context of the use client directive and we need to import the component using Next Genna
01:38
and ensure that we turn server side rendering or SSR to false with our component successfully imported in a client only fashion, we simply render it out within the page with our server and our client pages created. Let's play around with this application within the browser and first step we visit our server page and you can see that our component has successfully detected the server side environment and rendered the text server side. Similarly, if you visit our client page, the same component renders the text client side. This proves that we can use global variables to detect if we are running our code on the server or on the client. However, this approach is not ideal
02:11
as it can result in hydration errors. What this means is that the content we render on the server might not match what is rendered on the client. To demonstrate this, instead of rendering our component in client only mode, we render it in a standard client component. We know from our previous lessons that client components actually run twice. They are initially rendered on the server and then they are hydrated on the client. So if you visit this particular page on the browser, you'll initially see the text server side and then once it is hydrated on the client, it swaps to the text client side. And this is something that will make React life difficult because it won't be able to reconcile which element rendered
02:46
on the server corresponds to which element rendered on the dorm, and therefore it would struggle to attach things like event handlers to the correct elements. And this issue is being highlighted by the next GS developer tools. You can see the message that hydration failed because the Server rendered HTML didn't match the client. Note that this will only happen if the final rendered result doesn't match. If we take different execution parts based on the environment but return the same content, then that would not be an issue. But what if you want to render something different once a code has been successfully bootstrapped on the client? For that, you can execute your logic on the component mounted event.
03:18
We know from our reactors that reacts built-in hook for this purpose is called use effect. To demonstrate this, we will build a new component that will uplift itself once it has successfully rendered on the client and decide to render something different to detect on Component mount. We bring in use effect and to modify what we are rendering after that event. We bring in use state within our component. We start off by assuming that we are initially running on the server, which is why we set this is client state variable to false, then we wait for a use effect to get called. And within that we know
03:49
that we will only execute on the client. So we modify that is client bullion to True? And finally, depending upon that is client bullion. We render different text messages. The key thing to focus over here is that you can utilize the use effect component did mount pattern to place code that will only execute on the client. Let's demonstrate this by rendering this component within a simple page. The component that we've created will render the same content on the server and during hydration, but once it is mounted, it swaps to a different message and if you just blink your eyes, you might have missed it. So I'll refresh this page a few times
04:22
so you can see the swap. This pattern of utilizing use effect prevents hydration errors because React is okay for you to make modifications to the dorm after the component is mounted.