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

window or document is not defined #198

Closed
Lizhooh opened this issue Jul 6, 2017 · 10 comments
Closed

window or document is not defined #198

Lizhooh opened this issue Jul 6, 2017 · 10 comments

Comments

@Lizhooh
Copy link

Lizhooh commented Jul 6, 2017

I want to include some libraries and use cdn.
Where's index.html?
What should I do?

npm start is no error, but npm run build error:

Template execution failed: ReferenceError: window is not defined
  ReferenceError: window is not defined
Template execution failed: ReferenceError: document is not defined
  ReferenceError: document is not defined

code 1 (window is not defined):

import Swiper from 'swiper';

// .... Swiper using window object
componentDidMount() {
  let { options, swiperIsInitialized } = this.props;      
  //  <div className="swiper-container" ref={r => this.root = r}>
  this.swiper = new Swiper(this.root, options);
  this.props.swiperIsInitialized(this.swiper);
}

code 2 (document is not defined):

import './style';
import App from './components/app';

const head = document.querySelector('html > head');

// add css
head.innerHTML += `
    <link href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet">
`;

export default App;
@developit
Copy link
Member

There's no need to put those in <head>, you can just render them using VDOM.

In components/app.js:

class App extends Component {
  render() {
    return (
      <div id="app">
        <link href="//cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.min.css" rel="stylesheet" />
        <link href="//cdn.bootcss.com/Swiper/3.4.2/css/swiper.min.css" rel="stylesheet" />
        <Header />
        <Router onChange={this.handleRoute}>
          <Home path="/" />
          <Profile path="/profile/" user="me" />
          <Profile path="/profile/:user" />
        </Router>
      </div>
    );
  }
}

For your code 1:

componentDidMount() {
  let { options, swiperIsInitialized } = this.props;      
  //  <div className="swiper-container" ref={r => this.root = r}>
  let Swiper = require('swiper');
  this.swiper = new Swiper(this.root, options);
  this.props.swiperIsInitialized(this.swiper);
}

@hassanbazzi
Copy link
Member

@Lizhooh
Copy link
Author

Lizhooh commented Jul 7, 2017

@hassanbazzi Thank you, but ...
Swiper.js source code using window object, how to use window-or-global to solve the problem ?
Could you give me a example ?

@thangngoc89
Copy link
Collaborator

@Lizhooh See #178

@Lizhooh
Copy link
Author

Lizhooh commented Jul 8, 2017

@thangngoc89 ok, thank.

@Lizhooh
Copy link
Author

Lizhooh commented Jul 8, 2017

( ^_^ ), then the solution is::
add npm scripts: "np-build": "preact build --no-prerender"
run: npm run np-build

@Lizhooh Lizhooh closed this as completed Jul 13, 2017
@simonv3
Copy link

simonv3 commented Mar 2, 2021

I'm going to put this here because it took me a while to figure out, but it looks like dynamically loading the component that contains the library code that uses window seems to fix this. In my case I use leaflet, which does not support server side rendering, and uses window quite extensively.

In the below example WhereWeWorkMap loads leaflet. (using react-leaflet).

const WhereWeWorkMap = lazy(() => import("widgets/WhereWeWorkMap"));
...
...
return <Suspense fallback={<Fragment></Fragment>}>
  <WhereWeWorkMap />
</Suspense>

Folks might find this useful, or also tell me why they think this is a bad idea.

@rschristian
Copy link
Member

@simonv3

As the docs say, it's probably better and easier to wrap the specific parts that cannot be prerendered in a window check: if (typeof window !== "undefined") { ... }

@simonv3
Copy link

simonv3 commented Mar 2, 2021

@rschristian It's an external library, so I don't have access to that code, and when I added that if statement around the component I do control it still threw that error.

@rschristian
Copy link
Member

rschristian commented Mar 2, 2021

@simonv3 You should be able to wrap it around the import or whatever. Not sure how you're using that lib, but so long as you don't import it, it can't execute and look for window. Still will probably need the dynamic import, (i.e., import()) but you can still prerender the rest of your component.

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

No branches or pull requests

6 participants