Como integrar Next.js, React.js, Node.js, Bootstrap y AdmiLTE 3

Next.js se está volviendo un framework de desarrollo popular entre los desarrolladores JavaScript por diversas razones, pero a mí me gusta por el uso de React.js para el frontend y como desarrollador que ya se sabe manejar en Bootstrap con AdminLTE me gustó la idea de integrarlos y lo realicé de la siguiente forma.

Instalar next y react con el siguiente comando npm

npm install next react react-dom

Para iniciar con Next debemos configurar package.json, crear la carpeta pages y dentro de pages crear el archivo index.js. Creamos la carpeta pages:

mkdir pages

Creamos o editamos el archivo package.json con las siguientes lineas:

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Y creamos el archivo pages/index.js

export default () => 
Hello React, Next and Node!!!

Ya con esto tenemos un página con React, Next y Node funcionando en nuestro local. Vamos a desplegar modo desarrollo con:

npm run dev

Como pueden ver en consola, al visitar localhost:3000 pueden ver el mensaje escrito en pages/index.js

Ahora vamos a implementar Bootstrap 4 y AdminLTE con SASS usando el paquete @zeit/next-sass

npm install @zeit/next-sass node-sass

Debemos indicarle a Next que debe cargar el paquete en cada ejecución, para eso creamos un archivo llamado next.config.js

const withSass = require('@zeit/next-sass')
module.exports = withSass()

Hacemos nuestro primer archivo scss para las pruebas en styles/styles.scss

$color: blue;
.color {
  color: $color;
}

Ajustamos pages/index.js para las primeras pruebas, quedando de la siguietne forma

import '../styles/styles.scss'
export default () => 
Hello React, Next and Node!!!

Ya tenemos SCSS en el proyecto, pasamos a instalar los paquetes de Bootstrap y AdminLTE. Primero debemos instalar AdminLTE versión 2 y luego intalamos la versión 3.

npm install bootstrap admin-lte
npm install [email protected]

Editamos el archivo styles/styles.scss quedando de la siguiente forma

/**
 * App entry scss file
 *
 * @url https://getbootstrap.com/docs/4.0/getting-started/theming/
 * @url https://getbootstrap.com/docs/4.0/getting-started/webpack/#importing-precompiled-sass
 */
//$blue:    purple; // Override variables here to style accordingly
@import '~bootstrap/scss/bootstrap';
@import "~admin-lte/build/scss/AdminLTE-raw.scss";

Agregamos el pages/_document.js que es el layout principal

import Document, {Head, Main, NextScript} from 'next/document'

export default class MyDocument extends Document {
    render() {
        return (
            
            
                
                
                

            
        )
    }
}

Copiamos unos archivos estáticos a la carpeta static

mkdir static
cp node_modules/admin-lte/dist/js/adminlte.js static/
cp node_modules/admin-lte/dist/js/adminlte.js.map static/
cp node_modules/admin-lte/dist/js/adminlte.min.js static/
cp node_modules/admin-lte/dist/js/adminlte.min.js.map static/

Ahora creamos la carpeta donde colocaremos los diferentes layouts del proyecto

mkdir -p components/Layout

Creamos nuestro primer layout en components/Layout/AdminContent.js con este contenido

import PropTypes from 'prop-types';

const AdminContent = (props) => {
    return 
{props.title &&

{props.title}

{props.titleButton && props.titleButton}
}
{props.children}
}; AdminContent.propTypes = { title: PropTypes.string, titleButton: PropTypes.element, }; export default AdminContent;

El siguiente layout es components/Layout/AdminControlSidebar.js

const AdminControlSidebar = (props) => {
    return 
};

export default AdminControlSidebar;

Vamos con components/Layout/AdminFooter.js

import PropTypes from 'prop-types';

const AdminFooter = (props) => {
    if (!props.leftContent && !props.rightContent) {
        return null;
    }

    return 
{props.rightContent &&
{props.rightContent}
} {props.leftContent && props.leftContent}
}; AdminFooter.propTypes = { leftContent: PropTypes.element, rightContent: PropTypes.string, }; export default AdminFooter;

Ahora con components/Layout/AdminHeader.js

import Link from 'next/link';

const AdminHeader = (props) => {
    return 
};

export default AdminHeader;

components/Layout/AdminLayoutHoc.js

import "../../styles/styles.scss"
import AdminHeader from "../../components/Layout/AdminHeader";
import AdminSidebar from "../../components/Layout/AdminSidebar";
import AdminControlSidebar from "../../components/Layout/AdminControlSidebar";
import AdminContent from "../../components/Layout/AdminContent";
import PropTypes from 'prop-types';

/**
 * Main admin layout - A Higher Order Component
 */
class AdminLayoutHoc extends React.Component {
    render() {
        return 
{this.props.children} {/*I must be an element
}/>*/}
} } AdminLayoutHoc.propTypes = { contentTitle: PropTypes.string, contentTitleButton: PropTypes.element, }; export default AdminLayoutHoc

Por último components/Layout/AdminSidebar.js

import Link from 'next/link';
import PropTypes from 'prop-types';
import { withRouter } from 'next/router';

class AdminSidebar extends React.Component {
    render() {
        const { pathname } = this.props.router;
        return 
    }
}

AdminSidebar.propTypes = {
    projectName: PropTypes.string,
};

AdminSidebar.defaultProps = {
    projectName: 'AdminLTE 3'
};

export default withRouter(AdminSidebar)

Actualizamos pages/index.js

import AdminLayoutHoc from '../components/Layout/AdminLayoutHoc';

export default class Index extends React.Component {
    render() {
        return } url={this.props.url}>
            

 Headlines

h1. Bootstrap heading

h2. Bootstrap heading

h3. Bootstrap heading

h4. Bootstrap heading

h5. Bootstrap heading
h6. Bootstrap heading
Card Footer

 Text Emphasis

Lead to emphasize importance

Text green to emphasize success

Text aqua to emphasize info

Text light blue to emphasize info (2)

Text red to emphasize danger

Text yellow to emphasize warning

Text muted to emphasize general

 Description

Description lists
A description list is perfect for defining terms.
Euismod
Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
Donec id elit non mi porta gravida at eget metus.
Malesuada porta
Etiam porta sem malesuada magna mollis euismod.

 Description Horizontal

Description lists
A description list is perfect for defining terms.
Euismod
Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
Donec id elit non mi porta gravida at eget metus.
Felis euismod semper eget lacinia
Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

 Color Palette

Primary

Disabled
#3c8dbc

Info

Disabled
#00c0ef

Success

Disabled
#00a65a

Warning

Disabled
#f39c12

Danger

Disabled
#f56954

Gray

Disabled
#d2d6de

Black

Disabled
#111111
} }

En este punto ya tenemos la platilla básica, vamos a agregar dos páginas. La primera es pages/users.js

import AdminLayoutHoc from "../components/Layout/AdminLayoutHoc";
import Link from 'next/link';

export default class Users extends React.Component {
    render() {
        return 
                
            }
            url={this.props.url}
        >
            

Current active users

ID User Date Status Reason Progress
183 John Doe 11-7-2014 Approved This user was approved by Anil
175 Mike Doe 11-7-2014 Denied This user was declined by Anil
} }

La segunda página es pages/add-user.js

import AdminLayoutHoc from "../components/Layout/AdminLayoutHoc";
import Link from 'next/link';

export default class AddUser extends React.Component {
    render() {
        return } url={this.props.url}>
            

New User Form

Looks good!
Enter a last name