DreaMinder / nuxt-payload-extractor

Nuxt.js module that makes `nuxt generate` command to store html and payload separately.
MIT License
145 stars 18 forks source link

Questions about window.__NUXT__ access #18

Closed astagi closed 4 years ago

astagi commented 4 years ago

This is not an issue, it's just a question. This plugin saved my life to port an entire Wordpress multi language blog to Nuxt.js. I needed to statically render the entire blog and I used nuxt generate, anyway I don't know why asyncData inside my page got called anytime I navigated the site, forcing me to keep the Wordpress server API (they're inside a docker network). With your plugin I just load the payload from .json and everything is ok! I wonder why if I can do something like this to statically render my blog:

  async asyncData (context) {
    if (context.payload) {
      return { post: context.payload }
    } else {
      return { post: window.__NUXT__.data[0].posts[0] }
    }
  }

It looks a dirty solution but it works! I really don't understand why Vue uses window.__NUXT__ to hydrate the component when I go directly to the page and needs to fetch data again if I arrive on the page from a nuxt-link πŸ€”

Thanks in advance

DreaMinder commented 4 years ago

I'm glad it helped you! πŸ‘

Are you sure it works? As far as I can see, your example would only work without client-side navigation. You can still use it as long as you don't use instead of .

Look, this block if (context.payload) { will be called during nuxt generate (and will never be called when using a website itself), you can remove else block and it will work the same. else block will be called only on client-side navigation, and what you are doing here is basically feeding the same data from the current page to your next page. Yes, if you have the same data for each page, with every single post inside (even for single-post-pages), it will work, but it's rather a rare use-case.

lihbr commented 4 years ago

Just like @DreaMinder I don't see your "hack" working correctly because when navigating on client side to another page window.__NUXT__.data[0].posts[0] will still be a reference to the current (previous) page window.__NUXT__ object instead of the new one.

Basically here's the flow that happens when your generated app (nuxt generate) is served over a CDN (or any Apache server just serving files...):

  1. User request a page, let's say / ;
  2. CDN gives back /index.html content with markup ready ;
  3. Client hydrates everything with values from window.__NUXT__ (payload) ;
  4. User then navigate to /blog ;
  5. Client fetch /blog JavaScript (may already be fetched thanks to the nuxt-link "prefetch" feature, see here) ;
  6. Client run /blog page's asyncData hook to get data to fill new page with and eventually makes several calls to the API when not using nuxt-payload-extractor module.

So in this scenario as you can see client never download /blog/index.html file content which includes the said page payload.

This is quite confusing at first (and it took me ages to get it right back when I started working with Nuxt) though in the upcoming release Nuxt will introduce options.target which will allow full static generation, see the related RFC and the ongoing pull request.

astagi commented 4 years ago

Thanks for the clarification @DreaMinder @lihbr I didn't know that window.__NUXT__ is referenced to the current page! I've just taken a deeper look into payload-extractor implementation to see how things work. Regarding nuxt-link yes, it intercepts the click event so that the browser doesn't try to reload the page. I'll close the issue, thanks again ☺️