logaretm / villus

🏎 A tiny and fast GraphQL client for Vue.js

Home Page:https://villus.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nuxt3 SSR Deployed on netlify

fanckush opened this issue Β· comments

in the root app I am using useClient inside setup like so:

<script setup lang="ts">
...
useClient({
  url: 'https://...',
  use: [myPlugin, ...defaultPlugins()],
})
</script>

and in the page I have

export default {
  async setup() {
    ...
    const { data } = await useQuery({
      ...
    })
  }
}

locally everything works fine but when deployed to netlify with SSR I am getting the following error:

image

This has popped up before in #92

provide/inject usually break with async/await in setup() function because that effectively takes the execution outside the setup itself, especially when transpiled. This is a limitation of provide/inject and not villus.

Locally your server may not be transpiring the await statement but in production, it could be transforming it in such a way that breaks that limitation.

So you can stick to using the non-async version of the API and avoid using suspense to get around these issues.

Thanks for the info!

@logaretm what about the warning:
[Vue warn]: provide() can only be used inside setup ().
as you can see, I'm using useClient() in a non-async setup() function yet I still get the warning as if it were async. Is this related to Villus or maybe a nuxt3/vue3 bug?

I would need an example to check this out, I'm using villus in production without these problems. Can you create an example on codesandbox or a public repo here on GitHub? I will be happy to take a look.

@logaretm thanks. I did some debugging and I think it might be a bug in netlify but I'm not sure.

❌ in short, this gives me the warning on netlify (also locally with netlify dev):

// app.vue

// HERE: import useClient
import { useClient } from 'villus'

export default {
  setup() {
      console.log("before");
      useClient({
        ...
      })
      console.log("after");
    },
  }
}

βœ… while this doesn't give any warning. it works πŸŽ‰

// app.vue

import { VILLUS_CLIENT, createClient } from 'villus'

// HERE: define manually instead (exact same implementation as Villus's lib) 
function useClient(opts) {
    const client = createClient(opts);
    provide(VILLUS_CLIENT, client); // Villus uses `vue.provide` but otherwise it's identical
    return client;
}

export default {
  setup() {
      console.log("before");
      useClient({
        ...
      })
      console.log("after");
    },
  }
}

the warning I'm talking about is:

[Vue warn]: provide() can only be used inside setup ().

I have no idea why this works while the other doesn't 😞

This is interesting, which provide are you importing here? Is it from Vue or is it from some nuxt library?

Nuxt is auto importing it (directly from vue AFAIK), but just to be sure, I tried to manually import provide from vue directly and it's the same

I'm thinking that vee-validate and nuxt's vue imports are not pointing to the same Vue dist file. Resulting in two different provide/inject namespaces. Previously with webpack you would solve this by aliasing vue to one of its dist files. I'm not sure how to do that with Nuxt 3 yet or if that's even the issue.

@logaretm I managed to fix the problem, I think you're right. for some reason the library is using a different instance of Vue.

I transpiled the lib and it worked just like instructed in this comment m4rvr/storyblok-rich-text-renderer#21 (comment)

I did this for all the my dependencies and the build size dropped from 5 MB to 1.5 MB