Git Product home page Git Product logo

Comments (16)

mrillusion avatar mrillusion commented on June 2, 2024 1

Update as of Nuxt 3.11.0 it is possible to define pages as clientside or serverside specifically.

This means changing my [...slug].vue to [...slug].server.vue is a applicable workaround the resolves this issue. Note this is only possible in Nuxt 3.11.0 and higher.

It's still likely worthwhile to have this issue looked into by Storyblok to ensure their docs work as expected without these redundant API requests.

from storyblok-nuxt.

mrillusion avatar mrillusion commented on June 2, 2024 1

Hi @alvarosabu thanks for your follow up. Downloading the stackblitz example to my local machine results in the same behaviour as shown directly in stackblitz (See attached gif).

CleanShot 2024-04-22 at 16 42 30

There must be a difference between your example and the reproduction I have shared via stackblitz, are you able to review the repoduction I have shared or provide your working example so I can review?

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024 1

Thanks, @mrillusion I'm going to download your stackblitz and see if I can find the reason.

from storyblok-nuxt.

Youhan avatar Youhan commented on June 2, 2024

I can also replicate this using Nuxt 3.10.3 with Nitro 2.9.1 and @storyblok/[email protected]

from storyblok-nuxt.

Youhan avatar Youhan commented on June 2, 2024

It looks like the issue is that the <StoryblokComponent is rendering a dynamic component and Nuxt needs an import for the dynamic component(docs).

I ended up with a workaround that seems working. Please try and let me know.

on the page content type component, or any component that is rendering a list of children component, instead of this:

<script setup lang="ts">
import type { CtPageStoryblok } from '~/component-types-sb'

defineProps<{ blok: CtPageStoryblok }>()
</script>

<template>
    <div v-editable="blok">
      <StoryblokComponent v-for="item in blok.body" :key="item._uid" :blok="item" :uuid="item._uid" />
    </div>
</template>

I used this:

<script setup lang="ts">
import type { CtPageStoryblok } from '~/component-types-sb'
import { FeaturedArticlesHero } from '#components'

defineProps<{ blok: CtPageStoryblok }>()

const knownAsyncDataComponents: Record<string, any> = {
  'featured-articles-hero': markRaw(FeaturedArticlesHero),
}

function getComponent(item: any) {
  const comp = knownAsyncDataComponents[item.component]
  return {
    ...item,
    component: comp || item.component,
  }
}
</script>

<template>
  <div v-editable="blok">
    <StoryblokComponent v-for="item in blok.body" :key="item._uid" :blok="getComponent(item)" />
  </div>
</template>

Here is what /component/FeaturedArticlesHero.vue looks like. Note that it doesn't matter if you fetch from StoryBlock API directly or use useAsyncStoryBlok or just a simple fetch to jsonplaceholder. The problem seems to be the dynamic components.

<script setup lang="ts">
import type { FeaturedArticlesHeroStoryblok } from '~/component-types-sb'
const props = defineProps<{
  blok: FeaturedArticlesHeroStoryblok
}>()
const { data } = await useAsyncData(
  `testing----${props.blok._uid}`,
  () => $fetch('https://jsonplaceholder.typicode.com/todos/1'),
)
</script>

<template>
  <div>
    Featured Articles Hero
    <pre>{{ data }}</pre>
  </div>
</template>

from storyblok-nuxt.

mrillusion avatar mrillusion commented on June 2, 2024

Hi @Youhan I attempted this workaround and I am not seeing any changes/difference.

I did update it somewhat to handle any component name rather than individually importing all components.

// Page.vue
<script setup>
const props = defineProps({
  blok: {
    type: Object,
    required: true,
  },
})

const knownAsyncDataComponents = markRaw(props.blok.component);

function getComponent(item) {
  const AsyncComponent = knownAsyncDataComponents[item.component]
  return {
    ...item,
    component: AsyncComponent || item.component,
  }
}
</script>

<template>
  <div v-editable="props.blok">
    <component
      v-for="item in props.blok.body"
      :key="item._uid"
      :is="getComponent(item).component"
      :blok="item"
    />
  </div>
</template>

from storyblok-nuxt.

Youhan avatar Youhan commented on June 2, 2024

For me the trick was to explicitly import all the components that have useAsyncData in them. Have you tried that?

from storyblok-nuxt.

mrillusion avatar mrillusion commented on June 2, 2024

But only my [...slug].vue has useAsyncData then I pass this on to each component via props? Am I misunderstanding what you mean?

I haven't explicitly imported all components as it seemed like an anti-pattern when they are already autoimported but I'll give it a shot in the meantime. Thanks!

from storyblok-nuxt.

Youhan avatar Youhan commented on June 2, 2024

Yeah it is really hard to tell without sharing working code. Is it possible for you to share a minimal reproduction code?

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024

Thanks for the detailed explanation @mrillusion I will take a look

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024

Hi @mrillusion I just opened a PR to solve this when using useAsyncStoryblok, let me explain why this was happening.

The composable useAsyncStoryblok uses the useStoryblokApi(); under the hood, this means that it uses isomorphic-fetch

If you check the Nuxt docs on data fetching https://nuxt.com/docs/getting-started/data-fetching you will see the following warning

Warning

Beware that using only $fetch will not provide network calls de-duplication and navigation prevention.
It is recommended to use $fetch for client-side interactions (event based) or combined with useAsyncData when fetching the initial component data.

Since $fetch is similar to isomorphic-fetch is the reason why the duplication happens. So whenever you use the raw storybook API wrap it with useAsyncData in a similar way as I did on the PR for the composable useAsyncStoryblok

Hope this helps.

from storyblok-nuxt.

github-actions avatar github-actions commented on June 2, 2024

🎉 This issue has been resolved in version 6.0.8 🎉

The release is available on:

Your semantic-release bot 📦🚀

from storyblok-nuxt.

mrillusion avatar mrillusion commented on June 2, 2024

Hi @alvarosabu thank you for taking a look into this.

I have updated my Stackblitz reproduction to use storyblok-nuxt 6.0.10 and it appears the issue still exists with no change? Am I missing something?

https://stackblitz.com/edit/nuxt-storyblok-fetch-issue?file=package.json

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024

hi @mrillusion I would suggest trying locally? Stackblitz may do the network requests when generating the project.

I also added a StoryblokComponent to the [slug].vue template and getting the same result as the video

I attached a video of a statically generated Nuxt project, when you navigate to a route using useAsyncStoryblok the network call doesn't appear in the devtools anymore. Please let me know if it's not like that on your side.

Nuxt.dedup.network.calls.mp4

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024

Hi @mrillusion I'm still investigating the issue, I can only reproduce it if I download your Stackblitz reproduction, I tested the same scenario (A page with a Teaser/Feature with a NuxtLink inside) on a project of mine and also a new fresh project and the error doesn't occur 🫠. I'm trying to figure out what's different between them.

What I noticed is that in your reproduction is that even if we follow Nuxt recommended useFetch for de-duplication on SSG and create the raw call without the Storyblok module, it has the same issue.

I also discovered that only happens if the navigation inside the blok component is a NuxtLink, if you change it for a normal anchor it doesn't happen.

from storyblok-nuxt.

alvarosabu avatar alvarosabu commented on June 2, 2024

Hi, @mrillusion I finally have some updates, so I forked the Stackblitz reproduction you provided and removed the Storyblok Module completely to use Nuxt useFetch instead.

The issue persists, if you navigate using the NuxtLink it does a request. If you navigate with a normal anchor it doesn't.

It seems to be an upstream issue. I would suggest trying it out in a fresh nuxt install project since we weren't able to reproduce it anywhere but in the reproduction link you provided.

https://stackblitz.com/edit/nuxt-storyblok-fetch-issue-db6het?file=pages%2F%5B...slug%5D.vue

Screenshot 2024-04-25 at 10 34 56

from storyblok-nuxt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.