React App | Next js Server-side rendering Framework
Next.js | react server-side rendering Framework: As we all know that react is a very popular UI library for creating blazing fast web apps and even mobile apps.
The Benefits of Server-Side Rendering React App
SEO might be the conversation that starts your team talking about server-side rendering, but it’s not the only potential benefit.
Here’s the big one: server-side rendering displays pages faster. With server-side rendering, your server’s response to the browser is the HTML of your page that is ready to be rendered so the browser can start rendering without having to wait for all the JavaScript to be downloaded and executed. There’s no “white page” while the browser downloads and executes the JavaScript and other assets needed to render the page, which is what might happen in an entirely client-rendered React site.
And Next js is a perfect solution for creating react app which is rich in server-side rendering capabilities.
In this article, we will see some great stuff in the next Js
- Special Pages
- Configuration
- Extend Webpack
For this article we will first create a next starter project
npx create-next-app sampleapp
now in the pages directory you will have an index.js file which will serve as a home route for your application and if you want more routes you can just create files and use them as route
- pages/index.js - → localhost:3000
- pages/about.js - → localhost:3000/about
Special Pages
The first one is pages/_document.js, which allows us to define the surroundings of the page, such as the Head section. This could be useful to change the page title, add meta information or styles, and so on
// pages/_document.js
import Document, {Head, Main, NextScript} from 'next/document';export default class MyDocument extends Document {
render() {
return (
<html>
<Head>
<title>Smart Next Js</title>
// Enter Link Tags and scripts tags
</Head>
<body>
<Main/>
<NextScript/>
</body>
</html>
)
}
}
we’ve configured the very basic surroundings of the actual markup that will be injected in the page straight in the body tag; also, we’ve added a title to the custom Head component.
The next special Page is pages/_app.js, which allows us to wrap all pages (including the error) in a special wrapper
// pages/_app.js
import App, {Container} from 'next/app';
import React from 'react';export default class MyApp extends App { static async getInitialProps ({ Component, router, ctx }) {
let pageProps = {};
if (Component.getInitialProps) pageProps = await Component.getInitialProps(ctx);
return {pageProps};
} state = {someState: ''}; render () {
const {Component, pageProps} = this.props
return (<Container>
<Component {...pageProps} someState={this.state.someState}/>
</Container>);
}}
The next one is the default 404 or 500 error handler, pages/_error.js
// pages/_error.js
import React from 'react'export default class Error extends React.Component {
static getInitialProps({ res, err }) {
const statusCode = res ? res.statusCode : err ? err.statusCode : null;
return { statusCode }
} render() {
return (
<p>
{this.props.statusCode
? `An error ${this.props.statusCode} occurred on server`
: 'An error occurred on client'}
</p>
)
}
}
Configuration (use scss in next js)
Let's add the scss support in our next js app
lets create a scss file for style in src/index.scss
body
font-family: Arial, sans-serif
font-size: 12px
Let's import this file in pages/_app.js (assuming this is a global stylesheet file if not you can import it in the specific pages also )
and if you run
npm run dev
you will get an error
to resolve it we will first need some npm packages
npm install next node-sass @zeit/next-sass --save-dev
next, create a file named next.config.js in the route of your app
// next.config.js
const withSass = require('@zeit/next-sass')
module.exports = withSass()
and with this changes, you should be able to run your application with scss support
Another useful thing is the configuration of the build/dev phases via custom config.
To do that, you can use the following template:
// next.config.js
const withSass = require('@zeit/next-sass');const {PHASE_DEVELOPMENT_SERVER} = require('next/constants');module.exports = (phase, {defaultConfig}) => { if(phase === PHASE_DEVELOPMENT_SERVER) {
return withSass(defaultConfig);
} return withSass(Object.assign({}, defaultConfig, {
distDir: 'build-new'
}));};
Here, we have set the destination directory to build-new. The function receives phase and the default config as arguments, and you can use phase to determine what has to be modified in default config, based on your preferences.
Here, config also allows us to expose variables to your pages at runtime:
// next.config.js
const withSass = require("@zeit/next-sass");const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");module.exports = (phase, { defaultConfig: defaultConfig }) => {
if (phase === PHASE_DEVELOPMENT_SERVER) {
return withSass(defaultConfig);
} return withSass(
Object.assign({}, defaultConfig, {
distDir: "build-custom",
})
);
};
module.exports = {
serverRuntimeConfig: {
secretKey: "secret",
},
publicRuntimeConfig: {
publicKey: "public",
},
};
Extend Webpack (use typescript in next js)
Without next js Plugin
Webpack is the bundler used to produce the Next.js dev server and builds. It can be configured to bundle more things than by default. As an example, let’s add TypeScript.
Let's start by creating tsconfig file in the root
tsconfig.json:{
"compileOnSave": false,
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"jsx": "preserve",
"lib": [
"dom",
"es2015",
"es2016"
],
"module": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"skipLibCheck": true,
"target": "esnext",
"typeRoots": [
"./node_modules/@types"
]
}
}
Next let's add some dependencies for typescript
npm install ts-loader typescript @types/react
@types/next @types/node --save-dev
make a change in the next.config.js
// next.config.js
const withSass = require("@zeit/next-sass");const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");module.exports = (phase, { defaultConfig: defaultConfig }) => {
if (phase === PHASE_DEVELOPMENT_SERVER) {
return withSass(defaultConfig);
} return withSass(
Object.assign({}, defaultConfig, {
distDir: "build-custom",
})
);
};module.exports = {
webpack(config, { dir, defaultLoaders }) {
config.module.rules.push({
// add a custom loader rule
test: /\.+(ts|tsx)$/, // apply this rule only to TS[X] files
use: [
defaultLoaders.babel, // we use default babel on top of TS
{
loader: "ts-loader",
options: { transpileOnly: true },
},
],
include: [dir],
exclude: /node_modules/, // exclude everything from node_modules for performance
});
config.resolve.extensions.push(".ts", ".tsx"); // register require resolve extensions
return config;
},
};module.exports = {
serverRuntimeConfig: {
serverOnly: "secret",
},
publicRuntimeConfig: {
serverAndClient: "public",
},
};
that's it just change index.js to index.tsx and everything should be up and running with typescript now
With Next js Plugin
now as typescript is so popular next already has a plugin for it just install this dependency
npm install @zeit/next-typescript @types/react @types/next
@types/node --save-dev
add in next.config.js
// for typescript
const withTypescript = require('@zeit/next-typescript');
module.exports = withTypescript({});
The final next.config.js will look like this
// next.config.js
const withSass = require("@zeit/next-sass");const { PHASE_DEVELOPMENT_SERVER } = require("next/constants");// for typescript
const withTypescript = require('@zeit/next-typescript');
module.exports = withTypescript({});module.exports = (phase, { defaultConfig: defaultConfig }) => {
if (phase === PHASE_DEVELOPMENT_SERVER) {
return withSass(defaultConfig);
} return withSass(
Object.assign({}, defaultConfig, {
distDir: "build-custom",
})
);
};
module.exports = {
serverRuntimeConfig: {
serverOnly: "secret",
},
publicRuntimeConfig: {
serverAndClient: "public",
},
};
if this is helpful do share it with the community it motivates to write more
You can find out more about developing in React with Gatsby on John’s React development blog
Thanks