50

I have a Meteor/React project, using ES6 modules. I've installed materialize-css using npm, but I'm not sure how to actually use the Materialize classes in my JSX code. What am I supposed to import from materialize-css? Or do I just have to include the CSS in my main index.html file?

I mostly want it for the grid system, as I'll be using material-ui for the actual UI components.

ffxsam
  • 26,428
  • 32
  • 94
  • 144
  • I'm starring this for later, hopefully you get a good response - I've not had luck with using ES6 imports to get `materialize-css` into my projects, I've had to resort to the old-school ``, which I do not enjoy. – lux Feb 19 '16 at 16:14
  • Are you using webpack for this? Have you come to a solution? I, too have been using the CSS for the grid only, but I get by with a link in the head tag; I'm just curious to see how others use it. – joepin Apr 24 '18 at 15:41

16 Answers16

43

Since I use CSS Modules, importing materialize css would scope it to that particular component. So I did the following

Step 1) install materialise

npm install materialize-css@next 

Step 2) in index.html

<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.3/css/materialize.min.css">

Step 3) import materialise.js in whichever component its needed

for e.g. in SomeComponent.js (for e.g. if this is about a sidenav)

import React from 'react';
import M from 'materialize-css';
....
// ref can only be used on class components
class SomeComponent extends Component {
  // get a reference to the element after the component has mounted
  componentDidMount(){
    M.Sidenav.init(this.sidenav);
  }

  render(){
    return (
      <ul className={this.props.classes}
          ref={ (sidenav) => {this.sidenav = sidenav} }
          id={this.props.id}>
        // menuItems
      </ul>
    )
  }
}

just a beginner, so I would appreciate any comments on downsides of this method

supi
  • 2,172
  • 18
  • 15
  • Do I also need to add JQuery and Materialize.min.js or does the npm lib takes care of it? – Rishav Feb 24 '20 at 10:14
  • the npm lib takes care of it. – supi Feb 29 '20 at 03:08
  • 3
    Nice. Also JQuery is no longer a dependency for Materialize. – Rishav Mar 01 '20 at 04:54
  • I thought materialize-css and react-materialize were the same, but they are completely different. If you want to use the APIs in [React Materialize](http://react-materialize.github.io/react-materialize/?path=/story/react-materialize--welcome) Follow the instructions there. It is better than decoding all the answers here. – beeftosino Mar 25 '20 at 06:15
  • I made an

    tag and a

    – Aryamaan Goswamy May 01 '20 at 10:29
23

With NPM:

Step 1) Install materialize

npm install materialize-css@next 

Check the materialize documentation for any updates. Don't miss the @next at the end. The installed version will be something like: ^1.0.0-rc.2 or ^1.0.0-alpha.4

Step 2) Import materialize JS:

import M from 'materialize-css'

Or if that doesn't work you can try import M from 'materialize-css/dist/js/materialize.min.js'

Step 3) Import materialize CSS:

In index.html

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">

OR in javascript

import 'materialize-css/dist/css/materialize.min.css'

In order for the css import to work, you would need a css loader. Note that this loader is already included in projects built using create-react-app so you don't need the next steps. If instead, you are using custom webpack config, then run:

npm install --save-dev style-loader css-loader

Now add css-loader and style-loader in webpack config

const path = require("path");

module.exports = {
    entry: "./src/index.js",
    output: {
        filename: "bundle.js",
        path: path.join(__dirname, "build")
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /.js$/,
                exclude: /(node_modules)/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["env", "react"]
                    }
                }
            }
        ]
    }
}

Now you can initialize components individually, or all at once using M.AutoInit();

Step 4) Import materialize icons:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

With CDN:

Add the following in your HTML file.

<!-- Materialize CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css">

<!-- Materialize JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>

<!-- Materialize Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

Then, in the webpack config, add externals: https://webpack.js.org/configuration/externals/

Coding Elements
  • 1,000
  • 10
  • 14
  • 1
    Thanks! Using npm worked for me for initializing my Materialize'd ` – keaglin Nov 03 '18 at 07:25
14

You can use https://react-materialize.github.io/#/, why to reinvent the wheel.

installation react-materialize

npm install react-materialize

Usage

import {Button, Icon} from 'react-materialize'

export default () => (
  <Button waves='light'>
    <Icon>thumb_up</Icon>
  </Button>
)

Sample

https://github.com/hiteshsahu/react-materializecss-template

Screenshot

enter image description here

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
  • 6
    React-Materialize only implements a subset of Materialize's components, so it's still desirable to find a way to use Materialize itself. – Ryan Plant Jul 15 '17 at 16:03
  • 2
    I find Material-UI as alternative to Materilize CSS. It implement most materail ui components and have plenty of examples to jump start. I even made my web page using matetial-ui see http://HiteshSahu.com – Hitesh Sahu Aug 05 '19 at 10:28
  • Actually React-Materialize is re-inventing the staff. If you use this library, you'll see the final classes that actually div, nav and other elements, will have the particular names, and not the same names as the materialize CSS. Which by my opinion bring a lot of confusion, and extra staff to learn. I do prefer to import CSS as @supi suggested. – Kostanos Aug 29 '19 at 16:57
  • @HiteshSahu sample link is 404 – harschware Aug 09 '20 at 22:03
10

There are several ways of using Materialize CSS in ReactJS. However, I always use the following easiest one.

Here you can use Materialize CSS classes just like your HTML site using only ClassName with tags.


1 ) Install Materialize CSS for ReactJS using NPM.

npm install materialize-css@next 

2 ) Then import the minified materialize CSS file to index.js file.

import 'materialize-css/dist/css/materialize.min.css'

3 ) Now if you want to use google icons add the following codes in your public / index.html file.

<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

4 ) Finally to use Javascript events on input forms or other places add the following codes in your public / index.html file.

 <!-- Compiled and minified JavaScript -->
 <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

N.B. => Since all files need to go through the index.js file, so importing your minified Materialize CSS to index.js once is enough. Otherwise, you need to import these CSS files to all your js files.


That's enough to prepare your ReactJS folder for up and running with Materialize CSS. Happy Coding.


IFTEKHAR I ASIF
  • 377
  • 5
  • 9
7

as for the question, i think just npm i materialize-css and then

import "materialize-css/dist/css/materialize.min.css";
import "materialize-css/dist/js/materialize.min.js";

should do the job.


I wanted to share a problem I faced and how i solved it. I wanted to get materialbox to work and here is how i did it

import React, { Component } from "react";
import M from "materialize-css/dist/js/materialize.min.js";

class Image extends Component {
  constructor(props) {
    super(props);
    this.imageRef = React.createRef();
  }

  onLoad = () => {
    M.Materialbox.init(this.imageRef.current);
  };

  render() {
    return (
      <img
        src="..."
        alt="..."
        className="materialboxed"
        ref={this.imageRef}
        onLoad={this.onLoad}
      />
    );
  }
}

export default Image;

an interesting thing to note - it didnt work when i was trying M.init inside componentDidMount maybe because the image doesnt load by the time the call to componentDidMount is made.


react-materialize will surely make things easier if you want to use a lot of JS using components like modals etc.

keemahs
  • 780
  • 11
  • 14
  • Worked like magic! How did you figure out this import path? Where in the docs is this mentioned? – gignu Dec 28 '22 at 17:21
6

There are possible ways that I can recommend to use:

  1. One way is just include your stylesheet file in index.html and use className property in your React components just like this.

        var myDivElement = <div className="foo" />;
        ReactDOM.render(myDivElement, document.getElementById('example'));
    
  2. Another way is to bundle all your stylesheeets in one stylesheet file and to use them as previous one.

  3. One option could be to use webpack. By using webpack, it is possible to use embedded stylesheets in jsx files just by requiring stylesheet that you want to include.

    require("./stylesheet.css")

    To examine in detail webpack stylesheet option: http://webpack.github.io/docs/stylesheets.html

  4. Also see JedWatson's classnames repo for conditional className usage. https://github.com/JedWatson/classnames
burak
  • 3,839
  • 1
  • 15
  • 20
  • Unfortunately none of these help me. Materialize's CSS is conflicting with Material UI if I include the stylesheet in the HTML ``. http://i.stack.imgur.com/bGzzo.png – ffxsam Feb 22 '16 at 06:31
  • If the customization is the main problem, this is available in Material's theme manager property. Check this part to configure theme http://www.material-ui.com/#/customization/themes @ffxsam – burak Feb 22 '16 at 11:02
  • but what about using method on top of jquery like `$(".modal").modal('open');` ? – Tomasz Mularczyk Jan 20 '17 at 12:45
  • 1
    @Tomasz you can write them in lifecycle methods of React. – Yurii N. Jan 20 '17 at 16:16
  • Actually, since React uses its virtual dom infrastructure, it's not the best approach to use jquery. If you are implementing a new project, not maintaining a legacy app, try to use http://www.material-ui.com/ which provides React components that are styled with Google's material design. @Tomasz – burak Jan 20 '17 at 17:32
  • 1
    @burakhanalkan the problem with material-ui, that it doesn't implement many components, which materialize has, e.g. collapsible, parallax, or simple grid system. – Yurii N. Jan 23 '17 at 11:41
  • Just FYI, there seems to be a react implementation of (some) materialize components: https://github.com/react-materialize Didn't try it yet, though – Sebastianb Feb 24 '17 at 17:57
6

Solution Without index.html

  1. From react-materialize - Installation

    npm install materialize-css

    npm install react-materialize


  1. In your App.js or App.jsx add
   import "materialize-css/dist/css/materialize.min.css";
   import "materialize-css/dist/js/materialize.min.js";



Usage Examples:

Example 1

import React from "react";
import { Button } from "react-materialize";

export default function CustomMediaBox() {
  return <Button> Click Me </Button>;
  );
}


Example 2

import React from "react";
import { MediaBox } from "react-materialize";

export default function CustomMediaBox() {
  return (
    <MediaBox
      options={{
        inDuration: 275,
        onCloseEnd: null,
        onCloseStart: null,
        onOpenEnd: null,
        onOpenStart: null,
        outDuration: 200
      }}
    >
      <img
        alt=""
        src="https://materializecss.com/images/sample-1.jpg"
        width="650"
      />
    </MediaBox>
  );
}



Optionally - Adding Icons

  1. Although not required, if you want to use google icons, add the following to your App.css or any .css file imported from the App.js or App.jsx

    @import url('https://fonts.googleapis.com/icon?family=Material+Icons');



Note

If you get an error like this:

./node_modules/react-materialize/lib/Breadcrumb.js Module not found: Can't resolve 'classnames' in '/Users/artiomlk...

npm install classnames

ArtiomLK
  • 2,120
  • 20
  • 24
2

Inorder to address the concern of bundle size, the easiest way to use it is as follows:

  1. Include the CDN links in your index.html file
  2. Initialize M in your React Component's constructor this.M = window.M
  3. All the other required initializations in case of Modals and other Materialize Components can be done as mentioned in their Documentation using this.M
  4. I like to do those initialization in the componentDidMount lifecycle method.
  5. When unmounting i.e. inside componentWillUnmount, i use the destroy() method on the instances of initialized Materialize Components.
thewebjackal
  • 785
  • 8
  • 17
2
  • Install Materialize
npm i materialize-css@next
  • Initialize
import React, { useEffect } from 'react';
import 'materialize-css/dist/css/materialize.min.css';
import M from 'materialize-css/dist/js/materialize.min.js';


function App() {

  useEffect(() => {
    M.AutoInit();
  },[])

  return (
    <div className="App">
         // content...
    </div>
  );
}
Aman Bhardwaj
  • 1,509
  • 1
  • 7
  • 7
1

You can copy into "imports" folder and add by

import '../imports/stylesheets/materialize.min.css';

or use this for LESS example

@import '{}npm-package-name/stylesheets/...';
kosiakMD
  • 923
  • 7
  • 22
1

These answers didn't satisfy my biggest concern which was bundle size and importing a ton of code in order to use a few components. I've written up a solution here that includes code splitting and an easy compilation step.

The key points are:

  1. Compile base JS files (there are 4)
  2. Ensure the base JS is included before your imports / bundler runs
  3. Change the CSS imports to only what you need
  4. Run materialize.scss through your bundler if it supports Sass or run the compilation step to get a minified css file.
  5. Import individual components and activate them manually

Read post for more details.

mattdlockyer
  • 6,984
  • 4
  • 40
  • 44
1

Use CDN:

<!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

Then const M = window.M; to do initialization.

atultherajput
  • 175
  • 3
  • 18
0

I don't know am I too late to put this answer. You can use componentDidMount like this video

However, It does not use react-hooks. You'd better use react hooks (useEffects)

coding_Lover
  • 393
  • 1
  • 4
  • 13
0

How to use materialize-css with React with icons and other js features

  1. yarn add materialize-css@next --save or npm install materialize-css@next --save

  2. yarn add install material-icons or npm install material-icons

3.Kindly import the following like this ; snap

import 'materialize-css/dist/css/materialize.min.css';

import 'materialize-css/dist/js/materialize';

import 'material-icons/iconfont/material-icons.css'

function App() {
  return (
    <div className="App">
     <nav className="nave-wrapper">
       <div className="container">
       <a href="#!" class="brand-logo left">Logo</a>
       <ul className="right">

         <li><a href="#!">Home</a></li>
         <li><a href="#!">About</a></li>
         <li><a href="#!">Contact</a></li>
       </ul>
        </div>
     
     </nav>
      <div className="container">
      <i class="material-icons">add</i>
      <i class="large material-icons">insert_chart</i>
      <div class="row">
      <form class="col s12">
      <div class="row">
        <div class="input-field col s6"/>
          <i class="material-icons prefix">account_circle</i>
          <input id="icon_prefix" type="text" class="validate"/>
          <label for="icon_prefix">First Name</label>
        </div>
        <div class="input-field col s6">
          <i class="material-icons prefix">phone</i>
          <input id="icon_telephone" type="tel" class="validate"/>
          <label for="icon_telephone">Telephone</label>
        </div>
      </form>
  </div>
     </div>
    </div>
  );
}

export default App;
Sepiocop
  • 11
  • 1
0
  • Install Materialize
npm i materialize-css@next
npm install react-materialize
  • Initialize
import React, { useEffect } from 'react';
import 'materialize-css/dist/css/materialize.min.css';
import M from 'materialize-css/dist/js/materialize.min.js';


const App = () => {
  useEffect(() => {
    // Init Materialize JS
    M.AutoInit();
  });

  return (
    <div className="App">
         // content...
    </div>
  );
}
export default App;
Mido Hamza
  • 51
  • 1
  • 3
0
  1. Install materialize css via npm through npm install materialize-css@next

  2. Add this code import 'materialize-css/dist/css/materialize.min.css' to your App.js file to add materialize globally so you don't have to call materialize in individual components.

  3. Call materialize classes like so <button className="waves-effect waves-light btn blue darken-4"><i class="material-icons">add</i></button>

  4. For materialize fonts add <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> to your index.html in the public folder and call the icons anywhere

Side note: I am using React 18.2.0. Also, I can send you my github code for you to go through.