vue-cookie-law icon indicating copy to clipboard operation
vue-cookie-law copied to clipboard

Version 1.13.0 broke SSR

Open ThibaultVlacich opened this issue 5 years ago • 20 comments

nuxt 2.12.2 vue 2.6.11 vue-cookie-law 1.13.2

Prior to version 1.13.0 I was using this plugin with Nuxt, and it was working perfectly. Nuxt render pages server-side, so I had to put the <vue-cookie-law> component in a <client-only> tag, like this:

<client-only>
  <cookie-law
    button-class="btn btn-primary"
  ></cookie-law>
</client-only>

With this new version, it is not working anymore, as I'm getting this error:

ReferenceError window is not defined node_modules/vue-cookie-law/dist/vue-cookie-law.js@15:4

Here a repro link with the version 1.13.2 installed: https://codesandbox.io/s/old-water-s4p24

ThibaultVlacich avatar Apr 01 '20 23:04 ThibaultVlacich

Hm that is weird. I have it running in an older nuxt project with the <no-ssr> component which should be now the client-only component. And it was working fine.

But I will look into this.

apertureless avatar Apr 02 '20 07:04 apertureless

Precision, just the import trigger the error. Don't even need to add the component. Just add this in a .vue page : import CookieLaw from 'vue-cookie-law' and the error appears.

ThibaultVlacich avatar Apr 02 '20 12:04 ThibaultVlacich

Might be related to the new webpack 4 build setup.

Comparing v.1.12


(function webpackUniversalModuleDefinition(root, factory) {
--
7 | if(typeof exports === 'object' && typeof module === 'object')
8 | module.exports = factory();
9 | else if(typeof define === 'function' && define.amd)
10 | define("CookieLaw", [], factory);
11 | else if(typeof exports === 'object')
12 | exports["CookieLaw"] = factory();
13 | else
14 | root["CookieLaw"] = factory();
15 | })(this, function() {

and v.1.13


(function webpackUniversalModuleDefinition(root, factory) {
--
7 | if(typeof exports === 'object' && typeof module === 'object')
8 | module.exports = factory();
9 | else if(typeof define === 'function' && define.amd)
10 | define("CookieLaw", [], factory);
11 | else if(typeof exports === 'object')
12 | exports["CookieLaw"] = factory();
13 | else
14 | root["CookieLaw"] = factory();
15 | })(window, function() {

It looks like this got replaced with window.

apertureless avatar Apr 02 '20 13:04 apertureless

Further issues with 1.13.3 SSR build:

/node_modules/vue-cookie-law/dist/vue-cookie-law.js:972 var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]') ^ ReferenceError: document is not defined at addStyle

mikerogerz avatar Apr 02 '20 17:04 mikerogerz

Same here

ThibaultVlacich avatar Apr 02 '20 23:04 ThibaultVlacich

Please use the old version for now. It is still a webpack build issue. Need to investigate further.

apertureless avatar Apr 03 '20 14:04 apertureless

Already have it locked to 1.12.0 in my project, for the time being. Thanks for looking into this.

mikerogerz avatar Apr 03 '20 17:04 mikerogerz

Not sure it's the best solution, but a workaround :

let CookieLaw;
if (process.client) {
  CookieLaw = require("vue-cookie-law").default;
}

jwheatp avatar Apr 20 '20 17:04 jwheatp

I can confirm that this is a huge problem. Nuxt and Vue users can't use this plugin, anymore. Please fix it soon :))

/node_modules/vue-cookie-law/dist/vue-cookie-law.js:972 var styleElement = document.querySelector('style[' + ssrIdKey + '~="' + obj.id + '"]') ^ ReferenceError: document is not defined at addStyle

Another, failing solution

So, I tried to load it dynamically, but still get an error:

    <client-only>
      <CookieLaw theme="aatheme" buttonText="Vielen Dank »">
        <div slot="message">
          We use cookies.
        </div>
      </CookieLaw>
    </client-only>
export default {
  components: {
    TheHeader,
    TheFooter,
    'CookieLaw': () => import('vue-cookie-law')
  },
}

Error message

 ERROR  [Vue warn]: Failed to resolve async component: () => Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(null, /*! vue-cookie-law */ "vue-cookie-law", 7))
Reason: ReferenceError: document is not defined

michaeljakob avatar Apr 24 '20 14:04 michaeljakob

@apertureless

Looks like this option should be set to default 'window'

https://github.com/apertureless/vue-cookie-law/blob/eb35aa33ccc138d551ff9bc28765a978f2de1f41/build/webpack.release.js#L33

lxzxl avatar Apr 29 '20 04:04 lxzxl

@lxzxl

Sadly nope. I had to set this to this to fix the first error in this issue (window is not defined)

And the webpack config also confirms this:

https://webpack.js.org/configuration/output/#outputglobalobject

When targeting a library, especially when libraryTarget is 'umd', this option indicates what global object will be used to mount the library. To make UMD build available on both browsers and Node.js, set output.globalObject option to 'this'.

The current error has something to do with the styles that get injected. But I need to investigate further.

apertureless avatar Apr 29 '20 06:04 apertureless

I'll try to debug it.

alexandernst avatar May 11 '20 10:05 alexandernst

Thanks that would be great. I am currently very low on time.

The issue in general is, that the dynamic style loading of webpack breaks. An easy'ish workaround would be to extract the CSS so people have to import it, themself.

However this would be a breaking change. Thats why I was looking for other solutions to this. However, it there are not other solutions I would go with the extracting of css.

apertureless avatar May 11 '20 10:05 apertureless

Thanks for looking into this.

I assumed that having a separate css file is how it should be anyways (like the majority of 3rd party components I use in my project). Due to it being a breaking change, couldn't it simply be released as a new major version?

On Mon, 11 May 2020 at 05:45, Jakub [email protected] wrote:

Thanks that would be great. I am currently very low on time.

The issue in general is, that the dynamic style loading of webpack breaks. An easy'ish workaround would be to extract the CSS so people have to import it, themself.

However this would be a breaking change. Thats why I was looking for other solutions to this. However, it there are not other solutions I would go with the extracting of css.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apertureless/vue-cookie-law/issues/67#issuecomment-626625593, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAWU3VT3RLO25JMXCIMJV3RQ7JLJANCNFSM4LZW36IA .

mikerogerz avatar May 11 '20 14:05 mikerogerz

This works for me:

// plugins/cookie-law.ts
import Vue from 'vue'
import CookieLaw from 'vue-cookie-law'

export default () => {
  Vue.component('cookie-law', CookieLaw)
}
// nuxt.config.ts
plugins: [
    ...
    {src: '@/plugins/cookie-law', mode: 'client'}
  ]
// file.vue
<client-only>
   <cookie-law theme="base" />
</client-only>

tre-dev avatar Jun 14 '20 06:06 tre-dev

@tre-dev This works indeed. Small precision, ssr: false is deprecated and mode: 'client' is now the preferred syntax.

ThibaultVlacich avatar Jun 14 '20 11:06 ThibaultVlacich

@tre-dev I use Gridsome (so my Vue knowledge is probably less than that of Nuxt.js users), but I should be able to translate that.

Rocketpilot avatar Jun 14 '20 12:06 Rocketpilot

you can try dynamic import:

components: {
    CookieLaw: () => {
      if (process.client) {
        return import(/* webpackChunkName: 'vue-cookie-law' */ 'vue-cookie-law')
      }
    },
  },

KonradHEXANT avatar Sep 09 '20 12:09 KonradHEXANT

By the way, for people using basic Vue SSR without Nuxt.js, you must put the following (the declaration) into the entry-client.js file:

  Vue.component('cookie-law', CookieLaw);

And in your component template (PUG style):

client-only
   cookie-law

sneko avatar Sep 10 '20 00:09 sneko

works also with nuxt components: { CookieLaw: () => (process.client ? import('vue-cookie-law') : null), },

deepsoul avatar Jan 26 '21 14:01 deepsoul