How to use fancybox with webpack?

12,060

Solution 1

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.

Solution 2

I fought with the same issue and found that you can have 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'
        } )
    ]
};

Solution 3

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.

Solution 4

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.

Share:
12,060

Related videos on Youtube

Jaditpol
Author by

Jaditpol

Just another developer in the path of learning.

Updated on September 15, 2022

Comments

  • Jaditpol
    Jaditpol over 1 year

    I'm currently developing a webpage and started using webpack in my build process. I've managed to use slick-carrousel plugin downloaded via npm but can't make fancybox to work!

    I've downloaded it via npm and imported it as stated in the documentation:

    var $ = require("jquery");
    var slick = require("slick-carousel");
    var fancybox = require("fancybox")($);
    

    Then in my code I try to initailize a fancybox object and nothing happens. It throws no errors at all.

    $(".filtros__filtrar").on('click', function() {    
      $.fancybox.open({
        src  : '#tns-filtros',
        type : 'inline',
        opts : {
          smallBtn: false
        }
      });
    });
    

    If I do a console log of those variables I get:

    console.log(fancybox);  ->  undefined
    console.log(slick);     ->  {}
    

    Which means slick module is loading correctly but not fancybox.

    Somewhere I read that you have to use imports-loader to make fancybox recognize jquery variables. So I downloaded it via npm and included this in my webpack.config file:

    module: {
      rules: [
        {
          test: /fancybox[\/\\]dist[\/\\]js[\/\\]jquery.fancybox.cjs.js/,
          use: "imports-loader?jQuery=jquery,$=jquery,this=>window"
        }
      ]
    }
    

    But it doesn't work either.

    Can someone give me a light on this subject? Thanks in advance!

  • Jaditpol
    Jaditpol over 6 years
    You are totally right Mikhail! If I check console.log($.fancybox) I get ƒ (){o.open.apply(this,arguments)} which is correct. I'll have to see what else I'm doing wrong. Thanks!
  • Jaditpol
    Jaditpol about 6 years
    Thanks @ItoPizarro that's awesome!
  • Ryan Marshall
    Ryan Marshall over 5 years
    "require" was the key for me, instead of "import" - thanks!
  • cezar
    cezar about 5 years
    Using window.jQuery = $; is unfortunately a very ugly hack. The answer from Ito Pizarro helps to get read of that line.
  • Christoffer Helgelin Hald
    Christoffer Helgelin Hald about 4 years
    I'd say you should install like this npm install @fancyapps/fancybox --save (not --save-dev) as fancybox is to be used on the front-end and not a build-tool etc.
  • Jaditpol
    Jaditpol over 3 years
    You're right. Fixed. Thanks @ChristofferHelgelinHald