Why is vue-splide not working with Nuxt2?

Viewed 428

I'm trying to add Vue-Splide to my Nuxt project, after following the Vue-Splide documentation to install the plugin, and registering it as a Nuxt plugin I get the error Cannot use import statement outside a module.

nuxt.config.js

buildDir: '../functions/nuxt',
build: {
  publicPath: '/public/',
  vendor: [''],
  extractCSS: true,
  babel: {
    presets: [
      '@babel/preset-env'
    ],
    plugins: [
      ["@babel/plugin-transform-runtime"]
    ]
  }
},
plugins: [
  { src: '~/plugins/splide.client.js', mode: "client" }
],

splide.client.js

import Vue from 'vue';
import VueSplide from '@splidejs/vue-splide';
import '@splidejs/splide/dist/css/themes/splide-default.min.css';

Vue.use(VueSplide);

template

<splide :options="{ rewind: true }" class="banner-container">
  <splide-slide class="slide" v-for="slide in slides" :key="slide.id">
    <img :src="slide.imagen" :alt="slide.tombre" />
   </splide-slide>
</splide>

After transpiling Vue-Splide I now get the error window is not defined, and the stacktrace shows it's happening on node_modules\@splidejs\splide\dist\js\splide.js, I tried surrounding the splide tags with <client-only></client-only>, but that didn't seem to work.

What else am I missing here?

Updating to include my dependencies

"dependencies": {
  "@nuxtjs/firebase": "^7.6.1",
  "@splidejs/vue-splide": "^0.3.5",
  "firebase": "^8.9.1",
  "isomorphic-fetch": "^3.0.0",
  "nuxt": "^2.0.0"
},
"devDependencies": {
  "@babel/plugin-transform-runtime": "^7.15.0",
  "@babel/preset-env": "^7.15.6",
  "@babel/runtime": "^7.15.4",
  "@nuxtjs/tailwindcss": "^4.2.1",
  "autoprefixer": "^10.4.0",
  "babel-eslint": "^10.0.1",
  "babel-plugin-module-resolver": "^4.1.0",
  "eslint": "^4.19.1",
  "eslint-friendly-formatter": "^4.0.1",
  "eslint-loader": "^4.0.2",
  "eslint-plugin-vue": "^7.19.1",
  "firebase-tools": "^9.22.0",
  "node-sass": "^6.0.1",
  "postcss": "^8.3.11",
  "sass-loader": "^12.3.0",
  "tailwindcss": "^2.2.19"
}
2 Answers

The documentation of the vue-splide integration is clearly talking about Vue3 composition API.

Checking in the github issues of vue-splide, I found this one which is referencing a solution that you've linked above. Meanwhile, when trying this, those are the warnings that I do have in my CLI.

Those are also related to Vue3 (which is not compatible with Nuxt2, only Nuxt3 supports Vue3). Looking at the date of all the posts, it looks like it was matching somewhat the time-frame when Vue3 was still in a beta-limbo and probably not adopted by everybody.

At some point, I guessed that the package maybe lost some retro-compatibility with Vue2 in the next months. I then tried to install the version 0.3.5 of @splidejs/vue-splide rather than the latest one and it's working perfectly fine with it!


Here is the whole setup to have it working with Nuxt2 nuxt.config.js

plugins: [{ src: '~/plugins/splide.js', mode: 'client' }],

PS: no need for a transpile because this is not the issue at all here

/plugins/splide.js

import Vue from 'vue'
import VueSplide from '@splidejs/vue-splide'
import '@splidejs/splide/dist/css/themes/splide-default.min.css'

Vue.use(VueSplide)

/pages/index.vue

<template>
  <client-only>
    <Splide :options="{ rewind: true }">
      <SplideSlide>
        <img
          src="https://images.unsplash.com/photo-1638204958375-4824be216720?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=776&q=80"
          alt="Sample 1"
        />
      </SplideSlide>
      <SplideSlide>
        <img
          src="https://images.unsplash.com/photo-1638176061592-d8475d970c19?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80"
          alt="Sample 2"
        />
      </SplideSlide>
    </Splide>
  </client-only>
</template>

It works perfectly fine


I've reported the issue in the github issue, if somebody wants to have more up-to date info or an official answer from the mantainer.
EDIT: we received a confirmation on the non retro-compatibility. Also, the usage of <client-only> is also required to prevent DOM mismatch.

Issue was caused by the configuration required for Firebase hosting if following Firebase's Server-Side Render Vue Apps with Nuxt.js video.

By removing the line buildDir: '../functions/nuxt' in the nuxt.config.js file the project runs fine locally, however, in order to deploy to Firebase you have to:

  1. Replace publicPath: '/public/' with publicPath: '/', both in src/nuxt.config.js, and functions/index.js.
  2. Run npm run build.
  3. Copy the contents of src/.nuxt to functions/nuxt.
  4. Copy the contents of src/.nuxt/dist/client and src/.nuxt/dist/server to public/.

For the moment I do not know if there's a way for vue-splide to work while building to the functions folder, as I already tried installing vue-splide on the functions project with no success.

Related