storybook-nuxt icon indicating copy to clipboard operation
storybook-nuxt copied to clipboard

NuxtLink, useRuntimeConfig, useNuxtApp, anything requiring nuxt instance does not work

Open daviddomkar opened this issue 1 year ago • 9 comments

This module is currently very broken and does not work when some component accesses the nuxt instance. From the logs it seams that the issue is that the nuxt instance is injected later and the components using the nuxt instance do not have access to it on the first preview render. This is problematic when deploying to chromatic or building static storybook while also negatively affecting DX because of the need to click away from the story and back to have NuxtLink rendered for example.

The issue is reproducible in this repository using the playground project. The "App" story under "Pages" has this problem. I also thought that somehow the "NuxtLink" story under "Components" renders a nuxt link and thought it may be a mistake on my side but the reality is that the "NuxtLink" story just renders a button, not a real "NuxtLink" which should be also fixed to not confuse people.

daviddomkar avatar Mar 31 '24 22:03 daviddomkar

https://github.com/nuxt-modules/storybook/issues/474 and https://github.com/nuxt-modules/storybook/issues/458 might be related

daviddomkar avatar Mar 31 '24 22:03 daviddomkar

@daviddomkar I also spent a lot of time solving problems related to the use of plugins or Nuxt-specific components. The last thing that really made some improvement was adding a setting in nuxt.config - components: true, that is: export default defineNuxtConfig({ components: true, // all your other settings }); I hope this helps someone save tons of hours.

ITsattva avatar Apr 17 '24 12:04 ITsattva

@daviddomkar I also spent a lot of time solving problems related to the use of plugins or Nuxt-specific components. The last thing that really made some improvement was adding a setting in nuxt.config - components: true, that is: export default defineNuxtConfig({ components: true, // all your other settings }); I hope this helps someone save tons of hours.

Nevermind. It still doesn't work. This setting only provided a chance that everything would work as expected on the first render, but after testing it for a while, there is still no guarantee that your component will render when Nuxt is ready for use.

ITsattva avatar Apr 17 '24 13:04 ITsattva

Hi @ITsattva it would be helpful if you would create a reproduction repo with the steps so i will be looking at it with priority

chakAs3 avatar Apr 18 '24 19:04 chakAs3

@chakAs3 I appreciate your responsiveness, but unfortunately, even with help, I cannot upgrade to version 8, as not all the add-ons I need have been updated to it at the time of my last compatibility check with the latest version.

@daviddomkar The main (and perhaps all) issues arise because the Nuxt context does not keep up with the rendering of components, so a solution might be to create a global decorator that explicitly checks whether Nuxt is loaded and only renders the component if Nuxt is available.

export const withNuxtReady = (Story, context) => {
const isNuxtReady = ref(false);

const checkNuxtReady = () => {
if (useNuxtApp()) {
isNuxtReady.value = true;
clearInterval(intervalId);
}
};

const intervalId = setInterval(checkNuxtReady, 100);

onUnmounted(() => {
clearInterval(intervalId);
});

return () => isNuxtReady.value ? h(Story(context.args), context) : h('div', 'Loading Nuxt...');
};

IMPORTANT: If the solution does not work, carefully check the console for errors related to your component and try again after resolving them.

ITsattva avatar Apr 23 '24 07:04 ITsattva

@chakAs3 I appreciate your responsiveness, but unfortunately, even with help, I cannot upgrade to version 8, as not all the add-ons I need have been updated to it at the time of my last compatibility check with the latest version.

@daviddomkar The main (and perhaps all) issues arise because the Nuxt context does not keep up with the rendering of components, so a solution might be to create a global decorator that explicitly checks whether Nuxt is loaded and only renders the component if Nuxt is available.

export const withNuxtReady = (Story, context) => {
const isNuxtReady = ref(false);

const checkNuxtReady = () => {
if (useNuxtApp()) {
isNuxtReady.value = true;
clearInterval(intervalId);
}
};

const intervalId = setInterval(checkNuxtReady, 100);

onUnmounted(() => {
clearInterval(intervalId);
});

return () => isNuxtReady.value ? h(Story(context.args), context) : h('div', 'Loading Nuxt...');
};

IMPORTANT: If the solution does not work, carefully check the console for errors related to your component and try again after resolving them.

This is work for me, but nuxt context is incorrect. If i use this decorator, i lose my plugins on nuxt context, this is bad(

But if i use this decorator i can use $config on my components.

VegasChickiChicki avatar Apr 28 '24 03:04 VegasChickiChicki

@chakAs3 I can reproduce this bug: https://github.com/VegasChickiChicki/nuxt-3-storybook-v2

  1. reload page on Nuxt Welcome Story - Error: [nuxt] instance unavailable
  2. injected plugin "api" does not exist on nuxt context

node - 20.3.1

VegasChickiChicki avatar Apr 28 '24 16:04 VegasChickiChicki

@chakAs3 I can reproduce this bug: https://github.com/VegasChickiChicki/nuxt-3-storybook-v2

  1. reload page on Nuxt Welcome Story - Error: [nuxt] instance unavailable
  2. injected plugin "api" does not exist on nuxt context

node - 20.3.1

thanks for the repro i will check it soon

chakAs3 avatar Apr 30 '24 16:04 chakAs3

Another reproduction: https://github.com/nuxt-modules/storybook/issues/482

tobiasdiez avatar May 01 '24 09:05 tobiasdiez

I found the cause for these issues after a thoroughly investigation but didn't find any time to create a PR yet (altough I hacked something and that worked). It's actually a combination of problems.

  • 1 of them is that the projectAnnotations are loaded in a Promise.all from the @storybook/vue package so the order where the side effects are running is nondeterministic

  • The other one is that the array of plugins is populated too late. We have to add a placeholder function when loading the file and not after the startup of nuxt.

jevadebe avatar May 21 '24 19:05 jevadebe

I found the cause for these issues after a thoroughly investigation but didn't find any time to create a PR yet (altough I hacked something and that worked). It's actually a combination of problems.

  • 1 of them is that the projectAnnotations are loaded in a Promise.all from the @storybook/vue package so the order where the side effects are running is nondeterministic
  • The other one is that the array of plugins is populated too late. We have to add a placeholder function when loading the file and not after the startup of nuxt.

Can you provide a temporary solutionšŸ™, WithNuxtReady doesn't work for me

baixiaoyu2997 avatar May 23 '24 10:05 baixiaoyu2997

I found the cause for these issues after a thoroughly investigation but didn't find any time to create a PR yet (altough I hacked something and that worked). It's actually a combination of problems.

  • 1 of them is that the projectAnnotations are loaded in a Promise.all from the @storybook/vue package so the order where the side effects are running is nondeterministic
  • The other one is that the array of plugins is populated too late. We have to add a placeholder function when loading the file and not after the startup of nuxt.

Can you provide a temporary solutionšŸ™, please

VegasChickiChicki avatar May 29 '24 14:05 VegasChickiChicki

@jevadebe Thanks for the investigation! In case you find the time for a PR (which is very much appreciated!), could you please make it against https://github.com/nuxt-modules/storybook/pull/618. In this PR, I've added a simple test case for NuxtLink which is currently failing due to this bug.

tobiasdiez avatar May 30 '24 12:05 tobiasdiez

Temporary solution seems to be what is in this comment: https://github.com/nuxt-modules/storybook/issues/458#issuecomment-1866232118

Adding window.__NUXT__ = { config: { app: {} } } in nuxtAppEntry function in preview.

still there are tons of error in console but at least the stories show up. I checked and Nuxt config seems to be correctly loaded for static bundle inside presets viteFinal function. So something must break it during further processing.

soulrpg avatar Jun 24 '24 16:06 soulrpg

@chakAs3 Can this be fixed soon please? Storybook is entirely unusable with Nuxt 3 in the current state which is just making us consider another framework at this point.

daviddomkar avatar Jun 27 '24 13:06 daviddomkar

Thanks @jevadebe for your investigation. In https://github.com/nuxt-modules/storybook/pull/619 I was able to fix this more or less, modulo the two follow-up issues https://github.com/nuxt-modules/storybook/issues/662 and https://github.com/nuxt-modules/storybook/issues/661.

I can very much understand the frustration that this issue caused (in fact in prevented myself from using the storybook module in my own project). But please also take into account that both @chakAs3 and me are working on it in our free time. So if anyone would like to use storybook in their own project and encounters an issue, I would kindly ask them to investigate the underlying reason and in the best case provide a PR to fix it.

tobiasdiez avatar Jun 27 '24 18:06 tobiasdiez