Materialize your Next.js project with MDBootstrap for React


Topic: Materialize your Next.js project with MDBootstrap for React
Published 04.02.2019 Updated 03.12.2019

Jakub Mandra staffpremium posted 2 years ago

Materialize your Next.js project with MDBootstrap for React

Think about the app where you create some files, write JS code, and then simply deploy it with no worries about routing. And by default, it is rendered on the server.

That's how the Next.js works. 
It uses JavaScript and React with Node.js to build the app. Here are the features it offers to you as a developer:

  • Server-rendered by default
  • Automatic code splitting for faster page loads
  • Simple client-side routing (page based)
  • Webpack-based dev environment with Hot Module Replacement support
  • Able to implement with Express or any other Node.js HTTP server
  • Customizable with your own Babel and Webpack configurations

Since v.4.10.0 MDB React package supports SSR and tree-shaking, so it is the best time to mix those two cool products together.

I'm Jakub, I work as a Front-End Developer in MDBootstrap.com, and I want to share with you this quick guide on how to integrate MDBReact into your Next.js project.


Project setup

Before we start make sure you have Node.js installed on your machine. All you need to know, you can find here. Mine is 10.15.0

Initialize project with npm. Hit:

npm init -y

Now we can install our dependencies vianpm We will of course need NextReact and ReactDOM to manage our Document Object Model. Also, we want to easily set our server code. We will use Express - fast and minimalist framework for Node.

npm install --save next react react-dom express

Let's set up our simple server. Create server.js file in your root directory and simply paste below code there.

const express = require('express')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
.then(() => {
    const server = express()

    server.get('*', (req, res) => {
        return handle(req, res)
    })

    server.listen(3000, (err) => {
        if (err) throw err
        console.log('> Ready on http://localhost:3000')
    })
})
.catch((ex) => {
    console.error(ex.stack)
    process.exit(1)
})

Add a script to your package.json like this:

"scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
},

Now you can use Next.js for building your application. You can try this simple example:

  • Create pages folder inside your project root directory
  • Inside pages create those two simple files: index.js and register.js
  • You can set up routing by simply using `next/link` module
  • Your first Next.js app is now alive!
import Link from 'next/link';

const Index = () => (
    <div>
        <p>Hello Next.js</p>
        <Link href="/register">
            <a>Register</a>
        </Link>
    </div>
)

export default Index
import Link from 'next/link';

export default () => (
    <div>
        <div>Register page here.</div>
        <Link href="/">
            <a>Home</a>
        </Link>
    </div>
)

To run our server on development mode hit:

npm run dev

Now you can open localhost:3000 in your browser to see your app running.


MDBReact setup

But we want to work with MDBootsrap UI components, right? We will use here the free version of mdbreact. We will have to import styles. NextJS supports importing `.css``.scss``.less``.styl` files with some external modules. You can read more in Next.js documentation.

For mdbreact purposes, we will use @zeit/next-css module. Also to support fonts and images imports we will need to install some additional plugins.

  • `next-fonts` made to manage font loading
  • next-images which will help with images
  • next-compose-plugins to simplify our configuration of plugins
npm install --save mdbreact @zeit/next-css next-fonts next-images next-compose-plugins

Then we will have to set up our next configuration. Create next.config.js file in your project root directory and paste the code below.

const withCSS = require('@zeit/next-css');
const withFonts = require('next-fonts');
const withImages = require('next-images');
const withPlugins = require("next-compose-plugins");

module.exports = withPlugins([withCSS, withFonts, withImages]);

From now we can use MDBootstrap styles and components in our application. You just simply need to import those styles in your desired component, like so:

import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';

Let's try it out in our index.js file. Let's replace the link with the material button.

Just like a button, you can place any of your custom React components or even a div within a Link.
The only requirement for components placed inside a Link is they should accept an onClick prop.
import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';
import Link from 'next/link';

import { MDBBtn } from 'mdbreact';

const Index = () => (
    <div>
        <p>Hello Next.js</p>
        <Link href="/register">
            <MDBBtn>Register</MDBBtn>
        </Link>
    </div>
)

export default Index;

Problematic components

Nothing is perfect, Next.js uses its own routing modules, so we can't use NavLink from MDBReact, because it is implemented with react-router-dom, which Next doesn't support.

But we can handle it. We will use example Navbar component from mdbreact documentation.

  • Copy and paste the component's code into your index.js file
  • Replace MDBNavLink's with Next's Link
  • Attach class="nav-link" to the  element

At the and MDBNavItem should look like below:

<MDBNavItem>
    <Link href="/">
        <a className="nav-link">Home</a>
    </Link>
</MDBNavItem>

And the whole code for our basic Layout component:

import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';
import Link from 'next/link';
import {
    MDBNavbar, MDBNavbarBrand, MDBNavbarNav, MDBNavItem, MDBNavbarToggler, MDBCollapse, MDBFormInline,
    MDBDropdown, MDBDropdownToggle, MDBDropdownMenu, MDBDropdownItem, MDBContainer
} from "mdbreact";

class Index extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isOpen: false
        };
    }

    toggleCollapse = () => {
        this.setState({ isOpen: !this.state.isOpen });
    }

    render() {
        return (
            <MDBNavbar color="indigo" dark expand="md">
                <MDBNavbarBrand>
                <strong className="white-text">Navbar</strong>
                </MDBNavbarBrand>
                <MDBNavbarToggler onClick={this.toggleCollapse} />
                <MDBCollapse id="navbarCollapse3" isOpen={this.state.isOpen} navbar>
                <MDBNavbarNav left>
                    <MDBNavItem>
                    <Link href="/">
                        <a className="nav-link">Home</a>
                    </Link>
                    </MDBNavItem>
                    <MDBNavItem>
                    <Link href="/register">
                        <a className="nav-link">Register</a>
                    </Link>
                    </MDBNavItem>
                    <MDBNavItem>
                    <MDBDropdown>
                        <MDBDropdownToggle nav caret>
                        <span className="mr-2">Dropdown</span>
                        </MDBDropdownToggle>
                        <MDBDropdownMenu>
                        <MDBDropdownItem href="#!">Action</MDBDropdownItem>
                        <MDBDropdownItem href="#!">Another Action</MDBDropdownItem>
                        <MDBDropdownItem href="#!">Something else here</MDBDropdownItem>
                        <MDBDropdownItem href="#!">Something else here</MDBDropdownItem>
                        </MDBDropdownMenu>
                    </MDBDropdown>
                    </MDBNavItem>
                </MDBNavbarNav>
                <MDBNavbarNav right>
                    <MDBNavItem>
                    <MDBFormInline waves>
                        <div className="md-form my-0">
                        <input className="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" />
                        </div>
                    </MDBFormInline>
                    </MDBNavItem>
                </MDBNavbarNav>
                </MDBCollapse>
            </MDBNavbar>
        );
    }
}

export default Index;

Custom component

There is one more thing I want to discuss here. NextJS d have an index.js file like in React project (f.e. create-react-app) where you can import your styles, your App.js component and dive into code with no worries. You have to import styles etc every time you write a new component.

But it provides custom component to initialize pages. You can read more here.

Add _app.js file into your pages folder, and paste there below code. MyApp component automatically wraps up your pages during page initialization and attach our styles.

import React from 'react';
import App, { Container } from 'next/app';
import "@fortawesome/fontawesome-free/css/all.min.css";
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';

export default class MyApp extends App {
    static async getInitialProps({ Component, ctx }) {
        let pageProps = {};

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps(ctx)
        }

        return { pageProps };
    };

    render() {
        const { Component, pageProps } = this.props;

        return (
            <Container>
                <Component {...pageProps} />
            </Container>
        );
    }
}

Delete style imports from your index.js file and restart your application to see the magic happens.


I have built a simple starter for Next.js with MDBReact, which is called nextjs-with-mdbreact. And you can find it here, on my GitHub
There is a custom App component, with external Layout component implementation, which we have coded together previously.

Don't hesitate to leave a comment. Every suggestion, mistake report, or 'pull request' is also kindly seen.

Keep hacking! :)

 

ariadi commented a year ago

Hi,

How do I use my mdbreact pro into nextjs ? Your help very appreciate. Thanks


Divyesh Joshi commented 2 years ago

Great Kudos , very helpful , thank you :)


Jodhandeep Singh propremium commented 11 months ago

Hi,

I am getting the following error when trying to follow the tutorial.

"./node_modules/mdbreact/dist/css/mdb.css 1:0

Module parse failed: Unexpected character '@' (1:0)

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

> @charset "UTF-8";

| /*!

| * Material Design for Bootstrap 4"


Any help/advise would be appreciated.

Thanks


mincom propremium commented 11 months ago

``

const withCSS = require('@zeit/next-css')

module.exports = withCSS({

webpack(config, options) {

config.module.rules.push({

test: /\.(woff2|woff)(\?v=[0-9]\.[0-9]\.[0-9])?(\?#iefix)?$/,

loader: 'url-loader?limit=10000&mimetype=application/font-woff&name=[name].[ext]',

options: {

publicPath: './static'

}

});

config.module.rules.push({

test: /\.(ttf|eot|svg|png|jpg|gif|ico|otf)(\?v=[0-9]\.[0-9]\.[0-9])?(\?#iefix)?$/,

loader: 'file-loader?name=[name].[ext]',

options: {

publicPath: './static'

}

});

return config

},

});

``

This works for me.


Piotr Glejzer staff commented 11 months ago

If you will remove @charset "UTF-8"; from mdb.css file and re-compiled it will be work.


Belovol pro commented a year ago

Is it possible to use mdbreact with react router on server side, if I not use next js?


Jakub Mandra staffpremium commented a year ago

It's not. You have to use some SSR framework, for example Next.js or Gatsby


Belovol pro commented a year ago

May be it's possible with express.js like here?


johnmadril commented a year ago

can we use this nextjs-with-mdbreact. for our site in production is it the free one or premium ??


Jakub Mandra staffpremium commented a year ago

Hi,

This boilerplate is free :)


You can of course install paid version of mdbreact (MDBReact Pro) if you wish.


EvRo commented 9 months ago

I'm a pro user and I'm having trouble using the pro version. I've updated my package.json with my access tokens but when I install the packages and open my dev server I get the error "cannot use import statement outside a module". What's strange is that the free version works but my pro account doesn't please advise.


Palma pro commented 7 months ago

This not working: "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem."


lvothnrv commented 6 months ago

Hi, I have a problem with the icons, they are not displayed, I see unicode instead of the icon.
If you have the solution .. its would really help me very much thanks in advance.


Jakub Chmura staffpremium commented 6 months ago

Hi, I'm checking now a problem with next.js from your thread in the support forum. I am adding this problem above to my checklist and I would like to have this conversation transferred to our support forum to your thread.

Best, Kuba


turrione commented 4 months ago

Hello, I have a problem with styles when I build and start in production mode.

In development everything is as expected. Instead, in production, some bootstrap classes override those of mdb.


Jakub Chmura staffpremium commented 4 months ago

It will be much easier to solve this problem when you show us your code example or more information about this issue to reproduce it. You can do it at our support forum.

Best, Kuba


turrione commented 4 months ago

Hello Jackub,

The error can be reproduced in this repository.

https://github.com/turrione/nextjs-redux-jtwAuth-multilanguage-boilerplate

I have added in the home, under the navigation two divs with the classes bg-secondary and bg-light. Inside these divs there is a component MDBBtn color="blue" and another MDBBtn color="indigo"

In development everything looks as expected, but in production bg-light and bg-secondary change color and the button color becomes black.

This is just an example but in the project that I am developing there are more classes that in development are shown in one way and in production in another.


Jakub Chmura staffpremium commented 4 months ago

Please post a topic on our support forum. There we have a higher priority for solving problems. In the meantime, I will add a task to check this problem.

Best, Kuba


Carlos Alberto Osorio Angel propremium commented 1 months ago

Hello, excellent document. Please can you help me as soon as possible to do the same but with the mdbreact in the PRO version, I bought the MDBootstrap for React PRO version and I couldn't use it with Next.js.

Thank you.


Magdalena Dembna staffpremium commented 1 months ago

You need to change the mdbreact dependency in your package.json file:

"mdbreact": "git+https://oauth2:YOUR_TOKEN_GOES_HERE@git.mdbootstrap.com/mdb/react/re-pro.git"

And run npm i again. If you need help with generating your access token, you can find the instruction here in the PRO tab: https://mdbootstrap.com/docs/react/getting-started/quick-start/#existing


Write
Please insert min. 20 characters.