Even after reading through multiple articles explaining the differences between static and SSR rendering I still don’t understand how dynamic API calls work in these different modes.
I know that Nuxt has the fetch
and asyncData
hooks which are only called once during static generation, but what if I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?
I’m making a site that shows user generated content on most pages, so I have to make GET requests everytime one of those pages is visited to keep the content up to date. Can I do that with a static site or do I have to use SSR / something else? I don’t want to use client side rendering (SPA mode) because it’s slow and bad for SEO. So what is my best option?
2
Answers
The short answer to this question is that yes, it does work. In fact you can have http requests in any life cycle hooks or methods in your code, and they all work fine with static mode too.
Static site generation and ssr mode in Nuxt.js are tools to help you with SEO issues and I will explain the difference with an example.
Imagine you have a blog post page at a url like
coolsite.com/blogs
with some posts that are coming from a database.SPA
In this mode, when a user visits the said URL server basically responds with a .js file, then in the client this .js file will be rendered. A Vue instance gets created and when the app reaches the code for the
get posts
request for example in thecreated
hook, it makes an API call, gets the result and renders the posts to the DOM.This is not cool for SEO since at the first app load there isn’t any content and all search engine web crawlers are better at understanding content as html rather than js.
SSR
In this mode if you use the asyncData hook, when the user requests for the said URL, the server runs the code in the asyncData hook in which you should have your API call for the blog posts. It gets the result, renders it as an html page and sends that back to the user with the content already inside it (the Vue instance still gets created in the client). There is no need for any further request from client to server. Of course you still can have api calls in other methods or hooks.
The drawback here is that you need a certain way for deployment for this to work since the code must run on the server. For example you need node.js web hosting to run your app on the server.
STATIC
This mode is actually a compromise between the last two. It means you can have static web hosting but still make your app better for SEO.
The way it works is simple. You use asyncData again but here, when you are generating your app in your local machine it runs the code inside asyncData, gets the posts, and then renders the proper html for each of your app routes. So when you deploy and the user requests that URL, she/he will get a rendered page just like the one in SSR mode.
But the drawback here is that if you add a post to your database, you need to generate your app in your local machine, and update the required file(s) on your server with newly generated files in order for the user to get the latest content.
Apart from this, any other API call will work just fine since the code required for this is already shipped to the client.
Side note: I used asyncData in my example since this is the hook you should use in page level but fetch is also a Nuxt.js hook that works more or less the same for the component level.
There is actually no difference between either
asyncData()
orfetch()
hooks when you do usetarget: static
(SSG) ortarget: server
(default, SSR).At least, not in your use-case.
They are used mainly by your hydrated app.
As a reminder, when using either SSG or SSR, your static page will be hydrated and will become an SPA with all the dynamic functionality that we love. This combo of
SSG + SPA
orSSR + SPA
is called an universal app (or isomorphic app).Both
asyncData()
andfetch()
will be called upon navigation within your client side SPA.There are also some things happening on the server side, like
fetch
being called (by default) when you request the server for an SSR built app.Or the fact that when you generate your app (if using SSG), you can reach some API and generate dynamic routes (useful in the case of a headless CMS + blog combo for example).
For performance reasons and to have a quick build time, you may pass a
payload
and use it in anasyncData
hook in the dynamic route, as explained hereStill, a static Nuxt app, is basically just an
app built ahead of time, with no need for a Node.js server
, hence why an SSG app can be hosted on Netlify for free (CDN) but and SSR one needs to be hosted on something like Heroku (on a paid VPS).The main questions to ask yourself here are:
If none of those are relevant, you can totally go SSG.
If one of those is important to you, you may consider SSR.
I do recommend trying all of them:
ssr: true
+target: server
) withyarn build && yarn start
ssr: true
+target: static
) withyarn generate && yarn start
ssr: false
+ eithertarget: static
,target: server
also work but who wants to pay for an SPA?!) withyarn generate && yarn start
Try to host it on some platforms too, if you want to be sure to understand the differences beyond your local build.
You can use this kind of extension to also double-check the behavior of having JS enabled or not.
I will probably recommend to take the SSG path. Even tho, if your content is always changing you will probably not benefit much from SEO (eg:
Twitter
orFacebook
).This github answer could maybe help you understand things a bit better (it does have some videos from Atinux).
PS: I did a video about this on the latest Nuxtnation that you can find here.