0

I have read all the other posts I can find on this topic on Stack overflow (of which there are many). But from what I can gather, they all offer the same potential fixes such as wrapping the code with if(process.client), or wrapping the component with <client-only> tags, and adding mode:"client" or adding the client suffix to the plugin in the nuxt.config.js file. None of these solutions worked for me unfortunately. It seems that the package file (flickity.js) is still being run on the server side causing errors. I've tried replacing the import with a require and wrapping that in an if (process.client) conditional as well, and that didn't work either. The error I get if I do not include the import Flickity from 'flickity'; line is, as you can expect Flickity is undefined. When I do include it as below, I get window is not defined - flickity.js Does anyone know any other requirements to prevent this package from running server side that I have missed?

Component which uses flickity (wrapped in a client-only tag)

<script>

        import Flickity from 'flickity'; // I have tried removing this having been told that Nuxt automatically imports all plugins. But it didn't work and rendered a Flickity is undefined error

        


        export default {
            created() {  
                
            },
            props: {
                images: {
                    required:true,
                    type:Array
                }
            },
            mounted() {
                this.initiateCarousel();

            },
            methods: {
                initiateCarousel() {
                    if (process.client) {
                        const gallery = this.$refs.gallery;
                        const carousel = this.$refs.carousel;
                        console.log(carousel)
                        var flkty = new Flickity( carousel , {
                            cellAlign: 'left',
                            lazyLoad: 3,
                            contain: true,
                            pageDots: false,
                            prevNextButtons: false
                        });
                    }
                }
            },
        }
    </script>

plugins array in nuxt.config.js

plugins: [
  '~/plugins/flexboxgrid/index',
  '~/plugins/flickity.client'

],

Flickity.client.js file in ~plugins directory

import Flickity from 'flickity'; 

(i also tried adding export default Flickity; to this file but that rendered the same server errors

ToddPadwick
  • 430
  • 1
  • 6
  • 13
  • This occurs because you're importing the package inside of a component that is rendered on the server side. – Ohgodwhy Jan 21 '21 at 17:50
  • Thanks @Ohgodwhy. I thought that might be the case. But how do I import the package on the client side only? – ToddPadwick Jan 21 '21 at 17:57

1 Answers1

4

With a nuxt plugin, you will import Flickity on every page.

An alternative is to make a dynamic import of your Flickity with an await import, and only for the current nuxt page on mounted event, as follows:

async mounted() {
   await this.initiateCarousel();
},
methods: {
  async initiateCarousel() {
    if (process.client) {
        const gallery = this.$refs.gallery;
        const carousel = this.$refs.carousel;
        console.log(carousel);

        const { default: Flickity } = await import(/* webpackChunkName: "flickity" */ 'Flickity');

        var flkty = new Flickity( carousel , {
            cellAlign: 'left',
            lazyLoad: 3,
            contain: true,
            pageDots: false,
            prevNextButtons: false
        });
    }
  }
}
Nicolas Pennec
  • 7,533
  • 29
  • 43
  • Thanks, @nicolas. This looks promising. But I may not have implemented it correctly. I am getting 'Flickity is not a constructor' error. I have removed the Nuxt plugin and removed the standard import from the component. I have then added your code to the component (but I added the async initiateCarousel() function to methods as I presume that was a mistake?) have I missed something? – ToddPadwick Jan 22 '21 at 09:24
  • @ToddPadwick my bad... This lib doesn't expose an ES6 export. So you have to use the `default` value as follows: `const { default: Flickity } = await import(...)`. I've updated my answer ;-) – Nicolas Pennec Jan 22 '21 at 13:27
  • 1
    Brilliant. that worked! Thank you so much @nicolas. I wonder why this is not flagged as a solution for external non-vue packages in the Nuxt documentation? It's surely a common problem. – ToddPadwick Jan 22 '21 at 14:32
  • Hi @nicolas. so although that worked fine when running npm run dev, it turns out that it does not work when running build - do you know why that might be? Only just discovered because i deployed it just now. I'm getting this error: `ERROR in ./components/modules/Gallery.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--2-0!./node_modules/@nuxt/components/dist/loader.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./components/modules/Gallery.vue?vue&type=script&lang=js&) Module not found: Error: Can't resolve 'Flickity' in '/workspace/components/modules'` – ToddPadwick Jan 26 '21 at 20:42
  • its coool, haha. I just realized on node that we can import at runtime process. thankyou brathaa – Alauddin Afif Cassandra Jul 26 '21 at 08:43