React-slick: Does this work with server side rendering? no 'window' or 'document' dependencies?

Created on 2 Apr 2016  路  30Comments  路  Source: akiran/react-slick

I've been trying out too many carousel react components that assume they are running on the client and have 'window' and 'document' dependencies all over the place. This breaks the code trying to integrate it on an isomorphic app...

Most helpful comment

Isomorphic / universal React web-apps are becoming the standard
To avoid a ReferenceError: window is not defined
I'd suggest to wrap all dependencies to window with

var canUseDOM = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
)
if(canUseDOM ){
     // use window dependency...
}else{
  //have an alternative that wouldn't break functionality...
}

All 30 comments

Nope, it doesn't, also depends on mounted DOM for measurement.

@Ajar-Ajar did you ever find a solution for isomorphic rendering?

Isomorphic / universal React web-apps are becoming the standard
To avoid a ReferenceError: window is not defined
I'd suggest to wrap all dependencies to window with

var canUseDOM = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
)
if(canUseDOM ){
     // use window dependency...
}else{
  //have an alternative that wouldn't break functionality...
}

This should be fixed in [email protected]

I'm having the same problem with a universal setup. The carousel mostly works when I use via stylesheet tags, but on first load (server-side render) there are visual bugs with the slider that disappear by clicking through links (client-side render).

When I try with the npm package instead of stylesheet tags it doesn't work at all.

Ran into this issue as well. Current solution is as @Ganasist mentioned, if working with a universal setup, it will only work properly if you include both the stylesheet and the npm package.

@ypyang237 I'm having this issue as well. When you say "include both the stylesheet and the npm package", do you mean you are including the CDN for slick-carousel, while using npm for react-slick? Or are you importing the slick-carousel stylesheets to a separate stylesheet? None of the css is being applied on my isomorphic app.

Thanks in advance!

@alexanthony813
Yes, you understood correctly. I included the two CDN stylesheets for slick-carousel and had react-slick installed with npm as well to get it working. Hope this helps you!

I have react-slick working with server-side rendering, however I get the following error when using certain responsive settings. I believe it has to do with features only available in my "responsive" breakpoint (i.e. dots):

Settings:

const settings = {
  dots: false,
  draggable: false,
  fade: true,
  infinite: true,
  swipe: false,
  responsive: [
    {
      breakpoint: 767,
      settings: {
        dots: true,
        draggable: true,
        fade: false,
        swipe: true,
      },
    },
  ],
};

Error:

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:

Not sure if anything can be done about this, since the server-side rendered component doesn't know the browser width and the dots will always render client-side, but maybe there's a way to make this error disappear?

I'm having the same issue that @coreyleelarson. It even shows the difference between server and client rendering:
(client) "><div class="slick-arrow slick-prev"
(server) "><div class="slick-list" data-reactid="

This enquire.js require breaks again server rendering:
https://github.com/akiran/react-slick/commit/b798b1fbd0aa50c73b3c0a2b506b7a27a3f40f31#diff-e8eaa42a1b8ab4981d9272be425c03dfR8

node_modules/enquire.js/src/MediaQueryDispatch.js:14
    if(!window.matchMedia) {
        ^

ReferenceError: window is not defined
    at new MediaQueryDispatch (node_modules/enquire.js/src/MediaQueryDispatch.js:14:9)
    at Object.<anonymous> (node_modules/enquire.js/src/index.js:2:18)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (node_modules/react-slick/lib/slider.js:25:16)

getting the same error as @paradoxxxzero

having same error as @paradoxxxzero too
hard downgrading react-slick to 0.14.6 solved this issue. I hate to downgrade like this but hopefully it gets resolved soon.

Same error as @paradoxxxzero within a universal app has popped up in the last 48 hours using v0.14.5.

@jdmswong @rtmalone Can you try 0.14.11

0.14.11 seems to fix the server rendering :+1:

@paradoxxxzero @akiran indeed. upgrading to 0.14.11 solved the issue. thanks, all.

I am using the latest build 0.15.0 but still while rendering on server side getting visual issues.Included the stylesheets too as mentioned in above comments but still not able to work out.Anyone has any working examples?

All the issues that are related to server-side rendering, are supposed to be handled in the third release (maybe the third week) from now.

@laveesingh Wanted to check in on this. I have been trying to find a way around this (can't just only render it Client side as we need the HTML for SEO), and am wondering if I should just wait for the official solution or keep plugging away.

Everything works fine server wise, for me at least, what am I missing? :)

@silicakes oddly, switching my container component from a pure component to a React.Component Class instance seems to have fixed it. Not clear on why, as of yet.

With NextJS, it renders ok, but for some reason my last slide disappears and is just blank. I'm not sure why. I can still swipe the empty space and get back to the first slide (without animation). A little frustrating. It seems I have 3 slides, but the first slide never shows - it starts on the second slide. In addition if I resize the window, everything breaks. If I wrap the Slider with NoSSR - the width is incorrect and it doesn't appear to be 100% correct. Is there a viable alternative to slick using NextJS?

Could you regenerate it in CodeSandbox?

@laveesingh well I'm glad I threw together an example project because I can't actually reproduce my errors. So something must be wrong with my project. I'll do more investigation. Thank you for the help. here an example of react-slick with nextjs if anyone is interested. https://github.com/sscaff1/react-slick-example

I also have visual issues with server rendering (even with the latest v0.20). I don't get errors, but all the images initially show inline (not hidden) causing the page to look odd and distorted when first loaded, and then it resolves once the initial load is finished on the client. So the end result is an unprofessional looking distortion of the page that takes a second or two to get corrected.

I haven't myself tried any of the techniques to prevent the component from rendering at all on the server, and those techniques may be a viable temporary workaround, but it seems like this type of thing could be handled gracefully inside react-slick by detecting the execution environment and rendering appropriate content based on whether the environment is server or client.

It now supports server side rendering quite well. In fact, our demos are built with gatsby.js. There may seem some slight glitch on load, but most of them have been fixed and these fixes will be deployed soon enough.

@laveesingh Hi mate, I got a use case where I would like to have initialSlide randomly generated on every page load. However, it does not work as html code between server and client differs. How would you handle that? Has anyone else faced the same problem? Cheers.

@KevinOl I'm not sure exactly what you mean, but I've created a component that wraps react-slick and only actually renders the react-slick component client-side. If the environment is server it only renders the first slide (not using react-slick). This gives complete control over what happens server-side and isn't dependent on any react-slick code. Just an idea that might make things easier.

@dlong500 The idea is to display a random slide whenever someone browses the site. Therefore, initialSlide is used with a random number based on how many slides there are.

initialSlide: Math.floor(Math.random() * items.length)

My issue is that this leads to messing around with the content of the slides. Eg. contentA should be in slide1 but it results in contentA being in slide4

Ideally I would like the rendering of the server being same as the client. Meaning having the same random slide shown client and server sides. Of course using Math.random that way will generate different output on server and client. I thought using https://github.com/davidbau/seedrandom.

Anyway I may use your solution and have some sort of placeholder. Even if this means having some sort of 'visual flickering'.

Thanks!

UPDATE
I ended up dispatching a random seed on the server then use a selector to grab the value for both server and client
initialSlide: Math.floor(randomSeed * items.length)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BradyEdgar94 picture BradyEdgar94  路  3Comments

walker-jiang picture walker-jiang  路  3Comments

slashwhatever picture slashwhatever  路  3Comments

adamthewan picture adamthewan  路  4Comments

briziel picture briziel  路  3Comments