You know, masonry is a very common layout when we create a web page with HTML5, we usually use Desandro’s masonry.pkdg.js. Today I have to create the masonry layout in my React + Next.js project, I tried many react masonry components which I searched on Github, but no one is exactly what I want. So I tried to go straight to use masonry.pkdg.js in my React project.

I tried to import the masonry library first as below:

import Masonry from 'masonry-layout/masonry'

Then, initialize with vanilla javascript:

import Masonry from 'masonry-layout/masonry'

var elem = document.querySelector('.grid');
var msnry = new Masonry( elem, {
  // options
  itemSelector: '.grid-item',
  columnWidth: 200
});

export default function Home() {
   return (
      <div className="grid">
         <div className="grid-item">....</div>
         <div className="grid-item">....</div>
         .....
      </div>
   );
}

But the error is: “document is not defined.”, then I changed the code as below

import Masonry from 'masonry-layout/masonry'

const initMasonry = () => {
  var elem = document.querySelector('.grid');
  var msnry = new Masonry( elem, {
    // options
    itemSelector: '.grid-item',
    columnWidth: 200
  });
}

export default function Home() {
   initMasonry()
   return (
      <div className="grid">
         <div className="grid-item">....</div>
         <div className="grid-item">....</div>
         .....
      </div>
   );
}

Still doesn’t work, the error is “window is not defined”. So I was searching on Google and tried many ways to make it work, finally, I was realized I made a so silly mistake, yes, I have to frank that I really don’t familiar with React.

Just add “useEffect” method, import masonry layout with require() method andinitialize it within useEffect:

import React, { useEffect } from 'react'

export default function Home() {
   useEffect(() => {
     const Masonry = require('masonry-layout') //Import masonry here with require
     let elem = document.querySelector('.grid')
     let msnry = new Masonry( elem, {
       itemSelector: '.grid-item',
       columnWidth: 200
     })
   })
   return (
      <div className="grid">
         <div className="grid-item">....</div>
         <div className="grid-item">....</div>
         .....
      </div>
   );
}

Works! Of course, don’t forget to add your own CSS for .grid and .grid-items, as same as you create the masonry layout in the HTML5 template.

Hope this tip is helpful for someone who is still confused about this question.

Comments to: Create Masonry Layout In React With Desandro’s masonry.pkgd.js

    Leave a Reply