Next.js Quick Start Guide
Server-side rendering done right
Kirill Konshin
- 164 pages
- English
- ePUB (mobile friendly)
- Available on iOS & Android
Next.js Quick Start Guide
Server-side rendering done right
Kirill Konshin
About This Book
Create, build and deploy universal JavaScript applications using Next.js
Key Features
- Work with the entire tool-chain for developing universal Javascript applications with Next.js
- A straightforward guide to implementing server-side rendering
- Use Next.js to build SEO-friendly and super fast websites
Book Description
Next.js is a powerful addition to the ever-growing and dynamic JavaScript world. Built on top of React, Webpack, and Babel, it is a minimalistic framework for server-rendered universal JavaScript applications. This book will show you the best practices for building sites using Next. js, enabling you to build SEO-friendly and superfast websites.
This book will guide you from building a simple single page app to a scalable and reliable client-server infrastructure. You will explore code sharing between client and server, universal modules, and server-side rendering.
The book will take you through the core Next.js concepts that everyone is talking about – hot reloading, code splitting, routing, server rendering, transpilation, CSS isolation, and more. You will learn ways of implementing them in order to create your own universal JavaScript application. You will walk through the building and deployment stages of your applications with the JSON API, customizing the confguration, error handling, data fetching, deploying to production, and authentication.
What you will learn
- Explore the benefts of server-side rendering with Next.js
- Create and link JavaScript modules together by understanding code splitting and bundling
- Create website pages and wire them together through website navigation
- Extend your application with additional Webpack loaders and features, as well as custom Babel plugins and presets
- Use GraphQL and Apollo frameworks with Next.js to fetch data and receive push notifcations
- Design and implement core modules, such as logging and authentication, and then more complex solutions for access control and business rule management
- Write tests and use online CI tools such as Travis, GitLab, and more
- Build a Docker-based container for your app and deploy it to online services such as Heroku and Now.sh
Who this book is for
This book is for JavaScript developers who want to learn how to generate server-rendered applications.
Frequently asked questions
Information
Application Life Cycle Handlers and Business Logic
- Authentication
- Role-based access control
- Business rule management
- Internationalization
- Error handling
- Caching
- Analytics
Authentication
- Persistent storage of user credentials
- A method to send credentials to the server from the client side
- A check that finds the user and verifies the entered credentials
- A mechanism that signs all user requests so that the server can identify who is requesting what
- A mechanism that allows the user to sign out
$ npm install uuid lodash --save-dev
const uuid = require('uuid/v4');
const find = require('lodash/find');
const users = [
{username: 'admin', password: 'foo', group: 'admin'},
{username: 'user', password: 'foo', group: 'user'},
];
const tokens = {};
const findUserByUsername = (username) => find(users, {username});
const findUserByToken = (token) => {
if (!(token in tokens)) throw new Error('Token does not exist');
return users[tokens[token]];
};
const login = (username, password) => {
const user = findUserByUsername(username);
if (!user) throw new Error('Cannot find user');
if (user.password !== password) throw new Error('Wrong password');
const token = uuid();
tokens[token] = users.indexOf(user);
return {
token,
user
};
};
const logout = (token) => {
delete tokens[token];
};
// users.js
const uuid = require('uuid/v4');
const find = require('lodash/find');
const users = [
{username: 'admin', password: 'foo', group: 'admin'},
{username: 'user', password: 'foo', group: 'user'},
];
const tokens = {};
const findUserByUsername = (username) => find(users, {username});
const findUserByToken = (token) => {
if (!(token in tokens)) throw new Error('Token does not exist');
return users[tokens[token]];
};
const login = (username, password) => {
const user = findUserByUsername(username);
if (!user) throw new Error('Cannot find user');
if (user.password !== password) throw new Error('Wrong password');
const token = uuid();
tokens[token] = users.indexOf(user);
return {
token,
user
};
};
const logout = (token) => {
delete tokens[token];
};
exports.findUserByUsername = findUserByUsername;
exports.findUserByToken = findUserByToken;
exports.login = login;
exports.logout = logout;
$ npm install express body-parser cookie-parser --save-dev
// server.js
const express = require('express');
const next = require('next');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const port = 3000;
const cookieName = 'token';
const dev = process.env.NODE_ENV !== 'production';
const app = next({dev});
const handle = app.getRequestHandler();
const server = express();
server.use(cookieParser());
server.use(bodyParser.json());
server.get('*', (req, res) => {
return handle(req, res);
});
app.prepare().then(() => {
server.listen(port, (err) => {
if (err) throw err;
console.log('NextJS is ready on http://localhost:' + port);
});
}).catch(e => {
console.error(e.stack);
process.exit(1);
});
const cleanupUser = (user) => {
const newUser = Object.assign({}, user);
delete newUser.password;
return newUser;
};
server.post('/api/login', (req, res) => {
try {
console.log('Attempting to login', req.body);
const authInfo = users.login(req.body.username, req.body.password);
authInfo.user = cleanupUser(authInfo.user);
res.cookie(cookieName, authInfo.token, {
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
httpOnly: true
});
res.send...