Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.13.0 broke SSR #67

Open
ThibaultVlacich opened this issue Apr 1, 2020 · 20 comments
Open

Version 1.13.0 broke SSR #67

ThibaultVlacich opened this issue Apr 1, 2020 · 20 comments
Assignees

Comments

@ThibaultVlacich
Copy link

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

@apertureless
Copy link
Owner

apertureless commented Apr 2, 2020

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.

@ThibaultVlacich
Copy link
Author

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.

@apertureless
Copy link
Owner

apertureless commented Apr 2, 2020

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 apertureless self-assigned this Apr 2, 2020
@mikerogerz
Copy link

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

@ThibaultVlacich
Copy link
Author

Same here

@apertureless apertureless reopened this Apr 3, 2020
@apertureless
Copy link
Owner

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

@mikerogerz
Copy link

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

@jwheatp
Copy link

jwheatp commented Apr 20, 2020

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

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

@michaeljakob
Copy link

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

@lxzxl
Copy link

lxzxl commented Apr 29, 2020

@apertureless

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

globalObject: 'this',

@apertureless
Copy link
Owner

@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.

@alexandernst
Copy link

I'll try to debug it.

@apertureless
Copy link
Owner

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.

@mikerogerz
Copy link

mikerogerz commented May 11, 2020 via email

@tre-dev
Copy link

tre-dev commented Jun 14, 2020

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>

@ThibaultVlacich
Copy link
Author

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

@Rocketpilot
Copy link

@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.

@KonradDRAST
Copy link

KonradDRAST commented Sep 9, 2020

you can try dynamic import:

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

@sneko
Copy link

sneko commented Sep 10, 2020

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

valeriosillari added a commit to valeriosillari/zitronenstrasse that referenced this issue Oct 13, 2020
@deepsoul
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests