Getting Started with Next.js

Lance Watanabe
Don’t Leave Me Out in the Code
6 min readAug 11, 2020

What is Next.js: Nextjs is a framework for developing React applications that improves user experience by utilizes server-side rendering and automatic code-splitting.

Why should we use Next.js?

  1. Server-side Rendering (“SSR”): Normally, our React apps are rendered using Client Side Rendering or “CCR.” When the browser makes a request to our server, the server initially responds with bare bones resulting in a blank page. Next, the browser downloads the JavaScript file and executes the React code generating HTML that is displayed in the browser. As you can see, the HTML is generated at the end of the loading period so the user sees nothing until the page is fully loaded. With Nextjs, HTML is rendered on the server (Server Side Rendering or “SSR”). Therefore, when the browser makes a request to our server, the server initially responds with HTML that is immediately rendered. At this point, the user can see the web page before the JavaScript file is loaded. In other words, the user will see web content quicker in SSR than CSR. Note, since the JavaScript file and React code have not been loaded yet, the web page is not interactive. After the HTML is loaded, the browser loads the JavaScript and React code at which point the web page becomes interactive.
  2. SEO: Google’s web crawlers scan HTML and favor faster load times. As mentioned, since Nextjs utilizes SSR, HTML will be rendered quicker in the browser than an equivalent app using CSR.
  3. Code Splitting: Nextjs only loads necessary libraries and JavaScript logic which improves performance. In other words, a given module will only be loaded when the user requests it.
  4. Simple Routing: Instead of having to setup routes using <Switch><BrowserRouter exact path =’login’ component = {Login} /> </Switch>, Nextjs uses <Link href=’login’ /> for routing.

Let’s get started: We are going to create a simple Nextjs app that renders cat-related text from an API. I’m going to assume that you have a fundamental understanding of React.

Initialize and install dependencies: First, initialize your package.json using npm init. Next, use npm or yarn in your command line to install next, react, and react-dom.

npm init
npm install next react react-dom

Define Scripts: In your package.json file replace the “scripts” key with the following.

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

Create a “pages” folder and create an Index.js file: Inside of your “pages” folder, create a file called “index.js.” Now, we’re going to write a functional component (we could use a class component) with some simple text and export it.

const Index = () => (
<div>
<h1>Home</h1>
</div>
);
export default Index;

Run your script: Great. Type the following code in your command line.

npm run dev

We are now running the world’s simplest Nextjs app. Navigate to localhost:3000 in your browser to see the rendering.

Create an About page: Let’s create a second file in our “pages” folder and call it “about.js.” If we navigate to localhost:3000/about, we will see our about.js page.

const About = () => (
<div>
<h1>About</h1>
</div>
);
export default About

Routing: To make a route to our about.js page in our index.js file, we import Link from ‘next/link” and insert the <Link> component with href=’/about’ into our JSX. Note, that the <Link> component expects one child so you need to put <a>About</a> inside of the <Link>.

import Link from 'next/link';const Index = () => (
<div>
<h1>Home</h1>
<Link href='/about'>
<a>About</a>
</Link>{' '}
</div>
);

Styling: We can add styling within the component using <style jsx></style>. We use backticks inside the style tag and start writing our CSS. Instead of writing our CSS in a global CSS file, we wrote the styling inside the index.js file so the it was applied to the index.js file only. Of note, the about.js did not receive this styling. As you can see, we can use the <style jsx> to style components individually.

import Link from 'next/link';const Index = () => (
<div>
<h1>Home</h1>
<style jsx>
{`
h1 {
color: red;
}
`}
</style>
<Link href='/about'>
<a>About</a>
</Link>{' '}
</div>
);

Wrappers: We can use a wrapper component to pass down styling into our components. For example, we can add the cyborg theme from bootswatch by wrapping our home.js file and about.js file in a <Layout> component. Here are the three steps to make our <Layout> wrapper component:

  1. We need to import the <Head> component from ‘next/head.’ This simulates the <head> tag in HTML.
  2. We insert a link tag containing our path to the bootswatch CDN inside of our <Head> component. You can see some of the other styling choices here: https://www.bootstrapcdn.com/bootswatch/
  3. Use props.children to render all of the components (i.e. index.js and about.js) that are wrapped inside of <Layout />
import Head from 'next/head';const Layout = (props) => (
<div>
<Head>
<link
rel='stylesheet'
href='https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/cyborg/bootstrap.min.css'
/>
</Head>
{props.children}
</div>
);
export default Layout;

We wrap our home.js JSX inside of our <Layout> component as shown below. We do the same thing to about.js.

import Link from 'next/link';
import Layout from '../components/Layout';
const Index = () => (
<Layout>
<div>
<h1>Home</h1>
<Link href='/about'>
<a>About</a>
</Link>{' '}
</div>
</Layout>
);
export default Index;

getInitialProps(): You can configure certain data to be pre-populated with the HTML using getInitialProps(). getInitialProps() returns an object which will be passed into the component’s props. getInitialProps() is an asynchronous function so we can use it to make API calls. In our example below, we make a call to an API that returns cat-related text and displays it in index.js using props.cats.text.

import Link from 'next/link';
import Layout from '../components/Layout';
const Index = (props) => (
<Layout>
<div>
<h1>Home</h1>
<Link href='/about'>
<a>About</a>
</Link>{' '}
</div>
{props.cats.text}
</Layout>
);
Index.getInitialProps = async () => {
const res = await fetch('https://cat-fact.herokuapp.com/facts/random');
const data = await res.json();
return {
cats: data,
};
};
export default Index;

React State: Since Nextjs is just a framework for React, we can manipulate state in the same way as normal React components. We continue our example by setting the text (data.title) within the <h1> tag dynamically based on the state. We add a button that fires setTitle() to change the title in the state from ‘Home’ to ‘Away.’

import Link from 'next/link';
import Layout from '../components/Layout';
import { useState } from 'react';
const Index = (props) => {
const [data, setTitle] = useState({
title: 'Home',
});
const handleClick = () => {
setTitle({
...data,
title: 'Away',
});
};
return (
<Layout>
<div>
<h1>{data.title}</h1>
<button style={{ display: 'block' }} onClick={() => handleClick()}>
Switch Title
</button>
<Link href='/about'>
<a>About</a>
</Link>{' '}
</div>
{props.cats.text}
</Layout>
);
};
Index.getInitialProps = async () => {
const res = await fetch('https://cat-fact.herokuapp.com/facts/random');
const data = await res.json();
return {
cats: data,
};
};
export default Index;

--

--