• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 7 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⚑ JavaScript boilerplate for a full stack app built using React.js, Next.js, Express.js, react-bootstrap, SCSS and full SSR with eslint.

next-express-bootstrap-boilerplate

Contents


TL;DR.

Boilerplate code to get you up and running quickly with a full stack JavaScript web application whose frontend is built with React.js, Next.js, Bootstrap and SCSS and backend is built using Express.js. React code is isomorphic and the components are rendered both on the server with Server Side Rendering (SSR) as well as on the browser.

Installation.

β€’ sudo npm i -g next-express-bootstrap-boilerplate.

β€’ next-boilerplate to initialize a project in the current directory or next-boilerplate $FOLDER_NAME.

β€’ If $FOLDER_NAME given, cd into that folder.

β€’ npm run dev or yarn dev. (For development)

β€’ npm start or yarn start. (For production) | start script will first build the app and then serve the production version at :9001.

β€’ Go to localhost:9001 to verify.

β€’ Start coding! :)

β€’ Alternate installation.

β€’ First clone the repo. git clone https://github.com/MustansirZia/next-express-bootstrap-boilerplate.

β€’ cd next-express-bootstrap-boilerplate.

β€’ rm -rf .git.

β€’ npm i or yarn.



App structure.

|-- app 	// Next.js app lives here.
|  |
|  `-- components 	// Common components live here.
|  |  |
|  |  `-- Theme.js
|  |
|  `-- pages  // App routes live here.
|  |  |
|  |  `-- index.js
|  |  |
|  |  `-- profile.js
|  |
|  `-- styles   // CSS and SCSS files live here.
|  |  |
|  |  `-- index.scss
|  |  |
|  |  `-- vendor
|  |     |
|  |     `-- bootstrap.min.css
|  |
|  `-- .babelrc					
|  |
|  `-- next.config.js 	// App config lives here.
|  |
|  `-- postcss.config.js   
|
|
`-- public    // Static assets can live here.
|  |
|  `-- icons
|     |
|     `-- github.png         
|
|
`-- app.js
|
`-- next.js
|
`-- package.json
|
`-- README.md
|
`-- LICENSE

Our React app is housed under app/. Since it uses Next.js, all the main app routes go under app/pages. The common or miscellaneous components are housed under app/components.

Next.js uses styled-jsx to apply styles to our components. It is a css-in-js solution and will work inside this boilerplate too. But apart from this, we can write our own individual css or scss files for each of our components and place them under app/styles. We can later on import these style files just as we do in plain react but we need to put them inside <style> tags for them to work. (Since that's how Next.js handles all the styling).

As you can see our bootstrap.min.css is also housed under app/styles/vendor and is loaded inside a HOC called Theme. We essentially load all the bootstrap styling into this component and make it a wrapper for every component which uses components from react-bootstrap. That's how we can import and use bootstrap components into our own components. Check app/pages/index.js as an example for this.

β€’ How it works?

Our css and scss files are essentially transpiled to css-in-js during runtime and loaded or hot loaded into our app by a recipe that I got from here. That's what the app/.babelrc, app/postcss.config.js and the webpack config inside app/next.config.js are for.

app/pages/index.js.

import Link from 'next/link';
import { Button } from 'react-bootstrap';
import Theme from '../components/Theme';

// Straight away require/import scss/css just like in react.
import indexStyle from '../styles/index.scss';

const Index = () => (
    // Wrap your page inside <Theme> HOC to get bootstrap styling.
    // Theme can also be omitted if react-bootstrap components are not used.
    <Theme>
        {
            /*
            Set indexStyling via dangerouslySetInnerHTML.
            This step will make the below classes to work.
            */
        }
        <style dangerouslySetInnerHTML={{ __html: indexStyle }} />

        <span className="heading">React.js | Next.js | Express.js | Bootstrap - SCSS</span>
        <span className="text">with SSR.</span>

        {/* Acquire static assets from express static directly. */}
        <div className="img-container">
            <img alt="" src="/icons/github.png" />
        </div>

        <span className="text">
            <a href="https://github.com/MustansirZia/next-express-bootstrap-boilerplate">
              Github
            </a>
        </span>
        <br />
        <div className="btn">
            <Link href="/profile">
                <Button bsStyle="primary">Click Me</Button>
            </Link>
        </div>

        {/* Styling using styled-jsx. */}
        <style jsx>{`
              .btn {
                display: flex;
                justify-content: center;
              }`
        }
        </style>
    </Theme>
);

export default Index;

Express integration.

The backend routing is handled primarily inside app.js. There is where we initialize our express router. There is only app level middlewares at the moment (with a single route defined - /main in place). You can move the routing to a separate root folder like routes and use router level middlewares.
It should look quite familiar to the app.js of a normal express app with the exception of the asynchronous next(app) function call. This bootstraps Next.js with our express server and adds two middlewares to our existing router.
The first middleware adds req.app and req.handle properties to our req object. We can use these to render pages from Next.js inside our express routes.
The second middleware simply makes sure to divert any request comes to a route that is not defined within our express routes to the Next.js' handler which takes care of it automatically by looking up inside app/pages for a corresponding component. (This is why a request to / and /profile is catered to even though it is not defined in the express router; Only /main is defined there).
Thus, as you can see requests to /main and / mean the same thing. Each component is rendered on the server and then sent to the client.
Static files like icons or fonts are served from public/ and an asset such as those can be reached on the url / such as /icons/github.png.
Look inside app.js and next.js to know more.

app.js.

const express = require('express');
// const logger = require('morgan');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const next = require('./next');

const app = express();
// Put in place textbook middlewares for express.
if (process.env.NODE_ENV !== 'production') {
    // app.use(logger('dev'));
}
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/', express.static(path.join(__dirname, 'public')));

const start = async (port) => {
    // Couple Next.js with our express server.
    // app and handle from "next" will now be available as req.app and req.handle.
    await next(app);

    // Normal routing, if you need it.
    // Use your SSR logic here.
    // Even if you don't do explicit routing the pages inside app/pages
    // will still get rendered as per their normal route.
    app.get('/main', (req, res) => req.app.render(req, res, '/', {
        routeParam: req.params.routeParam
    }));

    app.listen(port);
};

// Start the express server.
start(9001);

Goodies.

Hot loading.

(For dev environment)

Hot loading is automatically added for any change inside app by Next.js which hot loads components as you change them. (This includes any css scss files)

Hot loading for any server side code is handled by nodemon which restarts the node server automatically.

Linting.

Eslint is also added which uses the airbnb style guide. Custom rules are defined to suit this very boilerplate inside package.json via a key called eslintConfig.


Compatibility.

This boilerplate uses react ^16.6.3 and react-dom ^16.6.3.

Also, it should be okay with node version >= 8.12.0. Sinice I've used async/await, for older versions I would recommend building with babel with the help of a plugin called transform-runtime.

Further reading.

β€’ Learnnextjs.com.
β€’ Next.js blog.

Contributions.

PRs are quite welcome! :)

LICENSE.

β€’ MIT.

Support.

Support my OSS work by buying me a coffee!

Buy Me A Pizza

More Repositories

1

react-native-fused-location

Finest location for react-native on Android using the new Fused API.
Java
128
star
2

overlay_container

A flutter widget which renders its child outside the original widget hierarchy.
Dart
31
star
3

serverless-link-preview

A serverless, scalable service to get website description and preview deployed on AWS Lambda.
JavaScript
12
star
4

go-rethinklogger

Automatically persists all the logs of your Go application inside RethinkDB.
Go
8
star
5

mustansir.npx

My name "mustansir" as an npx command. πŸš€
JavaScript
8
star
6

pokemon-service

A subdomain service that can serve different Pokemons based on the subdomain (Pokemon slug) from which it was accessed from.
TypeScript
7
star
7

Decky

Android app writtten in Kotlin which showcases fully draggable deck of cards.
Kotlin
6
star
8

markdown-visitor-badge

πŸ‘‘ Embeddable markdown visitor badge created using Golang, Vercel's serverless functions and distributed Redis.
Go
6
star
9

institutions-api

A RESTful microservice to query all colleges in India, universities in India and all international universities around the world using their name, a prefix of their name or any part of their name.
Go
5
star
10

csgo-dedicated-server

A containerized dedicated server for Counter-Strike: Global Offensive.
Shell
5
star
11

textcord

Serverless function/API for sending and receiving messages from a Discord text channel via SMS.
Go
3
star
12

mustansir.dev

Home for my blog.
HTML
2
star
13

MustansirZia

GitHub Profile Description.
1
star
14

js-exam

This is a very simple JavaScript exam to make you feel comfortable with arrays, strings, objects and JavaScript in general.
JavaScript
1
star