content icon indicating copy to clipboard operation
content copied to clipboard

The fetch() hook is no longer called on the client-side in production/universal mode

Open nicodotcomputer opened this issue 5 years ago • 14 comments

Hey!

First of all thanks for the nice work :)

I encountered something really strange and I'm not too sure about it but it looks like that the new fetch() hook of nuxt is not called on the client-side when in production mode:

Version

@nuxt/content: ^1.6.0 nuxt: 2.14.0

Steps to reproduce

Create a dynamic page component with a fetch() hook (example: pages/projects/_slug.vue).

export default {
  fetch() {
    console.log('fetch');
  }
}

What is Expected?

Fetch to be called when navigation occurs and a project is shown on the client side.

What is actually happening?

Fetch is only called on the client side when in development mode. In production mode, it is never called (only on the server).

nicodotcomputer avatar Aug 10 '20 21:08 nicodotcomputer

Edit: it looks like an error on my side, closing the issue.

nicodotcomputer avatar Aug 10 '20 21:08 nicodotcomputer

Actually reopening the issue!

I managed to recreate it:

It appears that calling again fetch() in another component will override the fetch() in my first component.

Is @nuxt/content overriding the nuxt fetch hook?

nicodotcomputer avatar Aug 10 '20 21:08 nicodotcomputer

Hi, it's not a bug 🙂 Fetch running on client and server side. When you first opening page(or reloading) fetch() running on server side. When you clicking on nuxt-link you doing client transition and fetch() running on client side. I think it's normal behawior.

cogor avatar Aug 11 '20 08:08 cogor

Hey,

Yes what you describe is the expected behaviour, but in reality it doesn't happen and calling fetch() inside one component will override a fetch() in another component

nicodotcomputer avatar Aug 12 '20 10:08 nicodotcomputer

Same here. Several routes are using fetch(). It works when browsing from root. But when reloading a certain route, content is not showing up.

designchapnl avatar Aug 28 '20 07:08 designchapnl

I have the same issue, fetch is not being called for me in production. I have a child component on a page with the fetch hook. When I run nuxt generate the fetch hook is being called, but when I navigate to the page in production fetch is not called.

Update: Hmm, for me, it appears to be that fetch isn't called for components in markdown. If I put the component on a page it works as expected.

drevantonder avatar Aug 30 '20 04:08 drevantonder

Yes what you describe is the expected behaviour, but in reality it doesn't happen and calling fetch() inside one component will override a fetch() in another component

I have the same issue. I was using fetch in layout and then inside a component. Component's fetch was called on client side. I had to move the layout fetch to vuex.

msdsk avatar Oct 06 '20 18:10 msdsk

Hi :)

Do you mind creating a reproduction with CodeSandBox so we can look at it?

You can fork this template: https://codesandbox.io/s/nuxt-content-playground-l164h?from-embed

atinux avatar Nov 19 '20 17:11 atinux

In full static mode, fetch is mocked by the generated data, why do you need it to be called?

atinux avatar Jan 14 '21 22:01 atinux

In full static mode, fetch is mocked by the generated data, why do you need it to be called?

If the content would show up on client-side navigation, I would agree with you. Since it doesn't we have to call $fetch() by hand again.

We use a component in pages/index.vue that fetches stories written in *.md-files with Nuxt-content (<slug>-<locale>.md). Each md-file has yaml vars up top for title, description etc. and locale.

  • $ npm run generate and $ npm run start shows the stories on initial load, which makes sense, because the stories are hardcoded into dist/index.html.
  • When you now navigate to another site, then back without refreshing, the stories are still there.
  • When you now navigate to another site, then refresh, then click on the logo to go to / again, the stories are not there.

That must mean fetch()-hook is not called or the "caching" that Nuxt uses under the hood doesn't really work with Nuxt-Content.

Here is our component:

export default {
  name: 'StoriesAboutTonaly',

  data() {
    return {
      stories: null,
      maxStories: 10,
    };
  },

  async fetch() {
    const locale = this.$i18n.locale;
    const limit = this.maxStories;
    this.stories = await this.$content('stories')
      .limit(limit)
      .only([
        'slug',
        'path',
        'mainHeadline',
        'subHeadline',
      ])
      .where({
        locale, // object-shorthand syntax
      })
      .sortBy('priority', 'desc')
      .fetch()
      .then((res) => {
        return res;
      });
  },
  mounted() {
    // need to fetch stories again on client side
    // this.fetchStories(); // disabled to showcase the issue
  },
  methods: {
    fetchStories() {
      this.$fetch();
    },
  },

Maybe I'll find time to recreate the issue in a sandbox, but for now I hope this information helps getting to the bottom of this.

katerlouis avatar Feb 18 '21 23:02 katerlouis

After stepping through production code, I found the issue (for me at least) is not that fetch isn't called. It's that the component's fetchKey is misaligned with the cached fetch data ($nuxt._pagePayload.fetch). After setting a custom fetchKey (thanks to #8466), the issue went away.

If this is indeed the correct solution, the documentation should give some guidance on when to use the new fetchKey option ~~when using Nuxt Content~~.

gsjen avatar Feb 22 '21 19:02 gsjen

Where would you see an improvement in the documentation?

atinux avatar Feb 23 '21 09:02 atinux

I think under the Data Fetching topic in Nuxt's docs, there should be a warning that if the fetch hook is used in a component in a layout, a custom fetchKey (or a component name) should be specified.

gsjen avatar Feb 23 '21 15:02 gsjen

Would you mind opening a PR to the nuxtjs.org repo? This would be really kind ☺️

atinux avatar Feb 24 '21 08:02 atinux

Same here. Several routes are using fetch(). It works when browsing from root. But when reloading a certain route, content is not showing up.

how do I fix this? what's the workaround?

aasutossh avatar Oct 16 '22 04:10 aasutossh

Same here. Several routes are using fetch(). It works when browsing from root. But when reloading a certain route, content is not showing up.

how do I fix this? what's the workaround? Could this be the reason? <Nuxt keep-alive /> in default layout

yamalweb avatar Oct 26 '22 05:10 yamalweb