As a Vue developer, you may have heard the term server-side rendering (SSR). Even if you are not using a framework like Nuxt.js or an SSR-plugin, it is important to know how to write universal components, or to put it in simpler words, components that can be interpreted from the server and the client.
If you ever want to switch to an SSR-based approach or share your component with people who do, this knowledge will definitely make your life easier! As a library/plugin author, this is a must in my opinion. And guess what, it isn’t even hard!
There are three very common and very problematic caveats that developers should think about when writing universal components. We’ll go through all of them one by one, showing examples of wrong and right implementations!
We will use this CodeSandBox for the examples.
When the component is processed on the server-side, no dynamic updates will occur. That’s why only two lifecycle hooks will be executed on the server:
But on the server-side, there is no
This is by far the most common problem with “normal” components or 3rd party libraries in a server-side-rendered environment.
Rule of thumb: Don’t call browser-specific APIs in
export default {
created () {
if (typeof window !== 'undefined') {
window.scroll(/*...*/)
}
}
}
But in most situations, it is completely fine to call them in
Also, you can sometimes leverage
An example component of correct usage can be found under
Speaking of lifecycle hooks! There is another thing you should think about:
To avoid memory leaks, you do not want to have side-effects in your
Rule of thumb: Don’t use code with
The examples can be found under
But when will it be server-side rendered? The answer is: every time a user enters the app over the
Because the first page-request to the app will be server-side-rendered and all subsequent requests (through page navigation, on-page redirects and so on) will be rendered by the client. Page refreshes and other external redirects to the app count as “entry points” and will be server-side rendered.
This is usually no big problem but it’s not bad to mention it anyway. There is no reactivity between the values on the server-side and on the client side.
If you manipulate your
Custom Vue directives are often used to manipulate the DOM (eg. revealing elements on scroll or make them stick to a specific position). This won’t work on the server-side as we now know. But what can be done there?
Well, the easiest way is: Don’t use directives as the abstraction, use components. I did this with components like VueNextLevelScroll or vue-if-bot because it is way easier to make them universally usable and they can be code-split as well! You don’t lose anything by choosing components as an abstraction.
If you really want to use directives, you can add a server-side equivalent of this directive. In Nuxt, this is possible by setting up a
Attention: Be aware to pass in your directives in This has been fixed in Vue 2.5.19!
The matching example will show you why you definitely should use components or server-side directives. Do you notice the flickering for the client-side-only directive example? It will be noticeable for all users that use this page as an entry point.
Alright, let’s wrap it up, folks! If you want to go through the example code line by line, please take a look into the CodeSandBox.
If you want further reading, I suggest reading the official vue-ssr-docs!
Still have questions? No problem, tweet me at @TheAlexLichter, reach out on the Vue/Nuxt Discord or write me a mail (blog at lichter dot io)
I hope you enjoyed that article and are now a bit more aware of server-side-rendering compatibilities! If this is the case, I’d gladly ask you to spread the word!

I'm Alex, a German web engineering consultant and content creator. Helping companies with my experience in TypeScript, Vue.js, and Nuxt.js is my daily business.
More about meRecently I stumbled upon a very interesting code sample which I had to review. As I'm a huge clean code advocate, I'll dissect the small code piece with you and explain several techniques that help to write clean, human-readable and maintainable code.
SSR is amazing but also comes with errors you might have not seen before. Especially one problem still boggles lots of minds: When Vue Hydration fails. In this article we will take a look at possible reasons, explain what the error means and how to fix it.