How to use fancybox with webpack?

This is not entirely true - "I've downloaded it via npm and imported it as stated in the documentation". You do not have to assign require('fancybox')($) into variable, this calling returns nothing. Below - it is a snippet from docs

var $ = require('jquery');

require('fancybox')($); <------- (2)

You can check if your jQuery object has fancybox method with console.log($.fancybox). If it returns a function, it means that you successfully import a fancybox package to your code. So you should seek the cause of the error in another place. In this case, check if the object which you passed to $.fancybox.open is correct. As I know, the property src of this object should contain an url to image or video what you want to show. Like in this example from fancybox official site.


Here's my setup

1) Install Fancybox NPM

npm install @fancyapps/fancybox --save-dev

2) Initialize Fancybox

// Require jQuery (Fancybox dependency)
window.$ = window.jQuery = require('jquery');

// Fancybox
const fancybox = require('@fancyapps/fancybox');
// Fancybox Stylesheet
const fancyboxCSS = require('!style!css!@fancyapps/fancybox/dist/jquery.fancybox.css');

3) Select what elements to open with Fancybox

To attach Fancybox to the images, you need to add the attribute [data-fancybox="optional-gallary-identifier"] to the element.

You can do this manually via HTML or with jQuery. Here are 2 ways you can do this with jQuery.

To open all images with Fancybox (a > img)

$(document).ready(function() {
  $('.lightbox a > img').parent().attr('data-fancybox');
});

To group images into galleries by .lightbox wrapper

$(document).ready(function() {
  $('.lightbox').each(function(i) {
    $(this).find('a > img').parent().attr('data-fancybox', 'group-' + i);
  });
});

If you have any dynamically loaded content, i.e. ajax, you'll need to apply the data-fancybox attribute to the dynamically loaded elements.


Ok. I managed to solve the problem like this.

First, I realized that I installed Fancybox 2 instead of Fancybox 3 so I uninstalled the first and installed the last (Thanks to @Mikhail Shabrikov for making me realize that!).

npm uninstall fancybox --save-dev
npm install @fancyapps/fancybox --save

Second, I dig through Fancybox original code and saw that it requires jQuery to be passed to it as window.jQuery and not $ so in my requires I did this:

var $ = require("jquery");
window.jQuery = $;  <-- This is what do the magic!!
var slick = require("slick-carousel");
require("@fancyapps/fancybox");

And voila! Everything works now.


I fought with the same issue and found that you can have webpack automatically load modules — making them available to the various plugins as needed — via ProvidePlugin right in the webpack.config. Webpack's documentation covers the naked $ or jQuery instances…

webpack.config.js

module.exports = {
    ...
    plugins: [
        new webpack.ProvidePlugin( {
            $: 'jquery',
            jQuery: 'jquery'
        } )
    ]
};

But, as metaskopia found, Fancybox wants window.jQuery. To that end, the following worked:

module.exports = {
    ...
    plugins: [
        new webpack.ProvidePlugin( {
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        } )
    ]
};