jqueryreactjswebpackgatsbylightgallery

How to use lightgallery with Gatsby/React


I'm trying to build an image gallery with Gatsby/React using the jQuery plugin called "lightgallery". I managed to figure out how to get it to work in development. However, when I try to build the site, I run into a problem. Here's my component code

import React, { Component } from 'react'
import Content from '../components/content-container/content'
import $ from 'jquery'
import 'lightgallery'
import 'lg-video'
import 'lg-zoom'

import img_1 from '../images/assets/1.jpg'
import img_2 from '../images/assets/2.jpg'
import img_3 from '../images/assets/3.jpg'

import './gallery.sass'

class Gallery extends Component {
  onLightGallery = node => {
    this.lightGallery = node
    $(node).lightGallery()
  }

  componentWillUnmount() {
    $(this.lightGallery)
      .data('lightGallery')
      .destroy(true)
  }

  render() {
    return (
      <Content>
        <Hero heroImage="hero hero-img-gallery">
          <h1 className="hero-title">Gallery</h1>
        </Hero>
        <div className="wrapper">
          <p className="title-gallery">Project video</p>
          <div className="lightgallery" ref={this.onLightGallery}>
            <figure href={img_1}>
              <img src={img_1} alt="moxon" />
              <figcaption>text</figcaption>
              <Play />
            </figure>
            <figure href={img_2}>
              <img src={img_2} alt="thumbnail" />
              <figcaption>text</figcaption>
            </figure>
            <figure href={img_3}>
              <img src={img_3} alt="thumbnail" />
              <figcaption>text</figcaption>
            </figure>
          </div>
          <p className="title-gallery">images</p>
          <div className="lightgallery" ref={this.onLightGallery}>
            <figure href={img_1}>
              <img src={img_1} alt="thumbnail" />
              <figcaption>text</figcaption>
            </figure>
            <figure href={img_2}>
              <img src={img_2} alt="thumbnail" />
              <figcaption>text</figcaption>
            </figure>
          </div>
        </div>
      </Content>
    )
  }
}

export default Gallery

Everything works in development, however, when I try to "gatsby build", it throws me the following error:

  1340 |     };
  1341 |
> 1342 |     $.fn.lightGallery = function(options) {
       | ^
  1343 |         return this.each(function() {
  1344 |             if (!$.data(this, 'lightGallery')) {
  1345 |                 $.data(this, 'lightGallery', new Plugin(this, options));


  WebpackError: TypeError: Cannot set property 'lightGallery' of undefined

  - lightgallery.js:1342
    [lib]/[lightgallery]/dist/js/lightgallery.js:1342:1

  - lightgallery.js:1358
    [lib]/[lightgallery]/dist/js/lightgallery.js:1358:2

  - lightgallery.js:8 Object.<anonymous>
    [lib]/[lightgallery]/dist/js/lightgallery.js:8:1

  - lightgallery.js:9 ./node_modules/lightgallery/dist/js/lightgallery.js
    [lib]/[lightgallery]/dist/js/lightgallery.js:9:6

  - lightgallery.js:18 Object../node_modules/lightgallery/dist/js/lightgallery.js
    [lib]/[lightgallery]/dist/js/lightgallery.js:18:2

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1


  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - sync-requires.js:10 Object../.cache/sync-requires.js
    lib/.cache/sync-requires.js:10:53

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - static-entry.js:9 Module../.cache/static-entry.js
    lib/.cache/static-entry.js:9:22

  - bootstrap:19 __webpack_require__
    lib/webpack/bootstrap:19:1

  - bootstrap:83
    lib/webpack/bootstrap:83:1


  - universalModuleDefinition:3 webpackUniversalModuleDefinition
    lib/webpack/universalModuleDefinition:3:1

  - universalModuleDefinition:10 Object.<anonymous>
    lib/webpack/universalModuleDefinition:10:2

I have no idea what went wrong and how to fix this issue as I am new to gatsby/react and webpack. Any pointers would be much appreciated!


Solution

  • You're running into this issue because the lightgallery code is being run on the server where window and other parts of the DOM are not available. You can learn more about how to debug and workaround this in the official Gatsby documentation here.

    That resource recommends the following to exclude the third-party library from being evaluated server-side:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      if (stage === "build-html") {
        actions.setWebpackConfig({
          module: {
            rules: [
              {
                test: /bad-module/,
                use: loaders.null(),
              },
            ],
          },
        })
      }
    }