DEV Community

loading...
Cover image for What is Static Site Generation of Next.js?

What is Static Site Generation of Next.js?

hiro9108 profile image hiro9108 ・9 min read

Hello, I am Hiro.
I am a student of web development in Vancouver.

Do you know what is Next.js?
This has good features for developing front-end.
I would like to show you basic features of this good technology.
But, I would like to show you what is react.js before I explain it.

That is framework of the JavaScript which allows us to create single page application(SPA) easily. SPA has only one page in the application file and connect to backend server via JSON data format. React gets the data and renders it to HTML dom. If you use it, you can create the loose coupling application which is easy to maintain.

But, this framework has the problem about SEO.
The application created by react has only one html file and simple html dom. For example, if you create the application by using Create React App(CRA) which is provided by Facebook, you can see simple html dom like this.

public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

That includes one simple div tag.

 <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
 </body>
Enter fullscreen mode Exit fullscreen mode

Other html doms are created by react components called JSX. It means that our browser create html doms by using JavaScript.
This is good, but when it comes to SEO, this feature causes the problem that Google Crawler does not understand the web page contents.
There is no problem with Business or Administrator application because these web applications are not important about SEO. But, if you want to improve it of your application, you need to think of solutions that how to show our web site contents to google crawler.

But, we have the easy solution. Next.js solves this problem. This is the framework of React.js and has some features which allow us to create SPA application with good SEO more easily.
When you learn about this framework, you see words like SSR or SSG. These functions are big differences between React.js and Next.js.

So, I would like to show you what is Next.js in this article.

Create Next.js Application

First of all, you can execute the command in your terminal to create the inital next.js application after moving your working directory.

npx create-next-app <Your Project Name>
Enter fullscreen mode Exit fullscreen mode

If you want to use npm, you can use below.

npx create-next-app <Your Project Name> --use-npm
Enter fullscreen mode Exit fullscreen mode

Of course, you can check the official document below. This is the useful document to understand it.

Official Tutorial Site

After creating initial application, you can boot your development server.

npm run dev
Enter fullscreen mode Exit fullscreen mode

If you success the command, you can see the initial Next.js application like this.

Screen Shot 2021-04-15 at 7.14.20

Routing of Next.js

When it comes to routing, Next.js is more easily than React.js. React need to import some modules like BrowserRouter, Switch, Route and Link from react-router-dom. But you import only Link from next/link and create the new file in the pages folder created by next.js if you want to set routing in the application.
I want to show simple example. Please create the new file called blog.js in the pages folder.

pages/blog.js

import React from "react";
import Link from "next/link";

const Blog = () => {
  return (
    <div>
      <h2>Blog Page</h2>
    </div>
  );
};

export default Blog;
Enter fullscreen mode Exit fullscreen mode

And please edit the index.js file in the pages folder like below. I just add Link to the file for moving to blog page.

pages/index.js

import Head from "next/head";
import Link from "next/link";
import styles from "../styles/Home.module.css";

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          <Link href="/blog">
            <a>Move to Blog</a>
          </Link>
        </h1>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by{" "}
          <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
        </a>
      </footer>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

When you click the link, move to the blog page. That's it. It is very easy and simple😺

Static Site Generation(SSG)

In this application, Next.js execute the html rendering in the server side. Thanks to this feature, it is possible to response data quickly to users and notice web site contents to google crawler. These are better things than react.

React is client side rendering. It means that the web page does not work well if you disable JavaScript on your browser. This is the simple example.

Launch React application
Screen Shot 2021-04-15 at 12.13.27

Open the developer tool and turn off Japascript by run command
Screen Shot 2021-04-15 at 12.14.02

We cannot see the web page
Screen Shot 2021-04-15 at 12.14.38

That is like Client Side Rendering functionality.

How about Static Site Generation?
SSG create the html file when you build the source code.

*When you use the development server(npm run dev), the html file is created per requests because developments should be more easily.

I also show the simple example about SSG functionality.

Execute the following command in your project.

npm run build
Enter fullscreen mode Exit fullscreen mode

After doing, you can see .next folder. This folder is built by the command and you can see the html file which has already created. And then, execute the following command.

npm start
Enter fullscreen mode Exit fullscreen mode

you can see the web page and turn off JavaScript. But, We can see the all contents like below.

Disable JavaScript
Screen Shot 2021-04-15 at 13.13.40

We can see whole contents
Screen Shot 2021-04-15 at 13.14.01

So, Next.js does not create the html file in client side.
Next, we can check the built folder. Actually, google crawler can see this built folder's html contents.

.next/server/pages/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width" />
    <meta charset="utf-8" />
    <title>Create Next App</title>
    <link rel="icon" href="/favicon.ico" />
    <meta name="next-head-count" content="4" />
    <link
      rel="preload"
      href="/_next/static/css/381f5b9c92d1673af027.css"
      as="style"
    />
    <link
      rel="stylesheet"
      href="/_next/static/css/381f5b9c92d1673af027.css"
      data-n-g=""
    />
    <link
      rel="preload"
      href="/_next/static/css/9c4381274c2a4fd9d205.css"
      as="style"
    />
    <link
      rel="stylesheet"
      href="/_next/static/css/9c4381274c2a4fd9d205.css"
      data-n-p=""
    />
    <noscript data-n-css=""></noscript>
    <link
      rel="preload"
      href="/_next/static/chunks/webpack-50bee04d1dc61f8adf5b.js"
      as="script"
    />
    <link
      rel="preload"
      href="/_next/static/chunks/framework.1cddd991bfe63666dc71.js"
      as="script"
    />
    <link
      rel="preload"
      href="/_next/static/chunks/commons.aab7fb15a9beb752d70d.js"
      as="script"
    />
    <link
      rel="preload"
      href="/_next/static/chunks/main-9a218112b2a04fa38bab.js"
      as="script"
    />
    <link
      rel="preload"
      href="/_next/static/chunks/pages/_app-56fe20dd7df999edbcbd.js"
      as="script"
    />
    <link
      rel="preload"
      href="/_next/static/chunks/pages/index-74d863034f308fe688d0.js"
      as="script"
    />
  </head>
  <body>
    <div id="__next">
      <div class="Home_container__1EcsU">
        <main class="Home_main__1x8gC">
          <h1 class="Home_title__3DjR7"><a href="/blog">Move to Blog</a></h1>
        </main>
        <footer class="Home_footer__1WdhD">
          <a
            href="https://vercel.com?utm_source=create-next-app&amp;utm_medium=default-template&amp;utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
            >Powered by<!-- -->
            <img src="/vercel.svg" alt="Vercel Logo" class="Home_logo__1YbrH"
          /></a>
        </footer>
      </div>
    </div>
    <script id="__NEXT_DATA__" type="application/json">
      {
        "props": { "pageProps": {} },
        "page": "/",
        "query": {},
        "buildId": "vAlb756HaKNXTe9J5pPd6",
        "nextExport": true,
        "autoExport": true,
        "isFallback": false
      }
    </script>
    <script
      nomodule=""
      src="/_next/static/chunks/polyfills-4f14e8c8ea1352d3ef0d.js"
    ></script>
    <script
      src="/_next/static/chunks/webpack-50bee04d1dc61f8adf5b.js"
      async=""
    ></script>
    <script
      src="/_next/static/chunks/framework.1cddd991bfe63666dc71.js"
      async=""
    ></script>
    <script
      src="/_next/static/chunks/commons.aab7fb15a9beb752d70d.js"
      async=""
    ></script>
    <script
      src="/_next/static/chunks/main-9a218112b2a04fa38bab.js"
      async=""
    ></script>
    <script
      src="/_next/static/chunks/pages/_app-56fe20dd7df999edbcbd.js"
      async=""
    ></script>
    <script
      src="/_next/static/chunks/pages/index-74d863034f308fe688d0.js"
      async=""
    ></script>
    <script
      src="/_next/static/vAlb756HaKNXTe9J5pPd6/_buildManifest.js"
      async=""
    ></script>
    <script
      src="/_next/static/vAlb756HaKNXTe9J5pPd6/_ssgManifest.js"
      async=""
    ></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Compare with the build folder of initial React application by creating CRA.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <link rel="manifest" href="/manifest.json" />
    <title>React App</title>
    <link href="/static/css/main.9d5b29c0.chunk.css" rel="stylesheet" />
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script>
      !(function (e) {
        function r(r) {
          for (
            var n, a, i = r[0], c = r[1], l = r[2], s = 0, p = [];
            s < i.length;
            s++
          )
            (a = i[s]),
              Object.prototype.hasOwnProperty.call(o, a) &&
                o[a] &&
                p.push(o[a][0]),
              (o[a] = 0);
          for (n in c)
            Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]);
          for (f && f(r); p.length; ) p.shift()();
          return u.push.apply(u, l || []), t();
        }
        function t() {
          for (var e, r = 0; r < u.length; r++) {
            for (var t = u[r], n = !0, i = 1; i < t.length; i++) {
              var c = t[i];
              0 !== o[c] && (n = !1);
            }
            n && (u.splice(r--, 1), (e = a((a.s = t[0]))));
          }
          return e;
        }
        var n = {},
          o = { 1: 0 },
          u = [];
        function a(r) {
          if (n[r]) return n[r].exports;
          var t = (n[r] = { i: r, l: !1, exports: {} });
          return e[r].call(t.exports, t, t.exports, a), (t.l = !0), t.exports;
        }
        (a.e = function (e) {
          var r = [],
            t = o[e];
          if (0 !== t)
            if (t) r.push(t[2]);
            else {
              var n = new Promise(function (r, n) {
                t = o[e] = [r, n];
              });
              r.push((t[2] = n));
              var u,
                i = document.createElement("script");
              (i.charset = "utf-8"),
                (i.timeout = 120),
                a.nc && i.setAttribute("nonce", a.nc),
                (i.src = (function (e) {
                  return (
                    a.p +
                    "static/js/" +
                    ({}[e] || e) +
                    "." +
                    { 3: "b7dd6f7e" }[e] +
                    ".chunk.js"
                  );
                })(e));
              var c = new Error();
              u = function (r) {
                (i.onerror = i.onload = null), clearTimeout(l);
                var t = o[e];
                if (0 !== t) {
                  if (t) {
                    var n = r && ("load" === r.type ? "missing" : r.type),
                      u = r && r.target && r.target.src;
                    (c.message =
                      "Loading chunk " +
                      e +
                      " failed.\n(" +
                      n +
                      ": " +
                      u +
                      ")"),
                      (c.name = "ChunkLoadError"),
                      (c.type = n),
                      (c.request = u),
                      t[1](c);
                  }
                  o[e] = void 0;
                }
              };
              var l = setTimeout(function () {
                u({ type: "timeout", target: i });
              }, 12e4);
              (i.onerror = i.onload = u), document.head.appendChild(i);
            }
          return Promise.all(r);
        }),
          (a.m = e),
          (a.c = n),
          (a.d = function (e, r, t) {
            a.o(e, r) ||
              Object.defineProperty(e, r, { enumerable: !0, get: t });
          }),
          (a.r = function (e) {
            "undefined" != typeof Symbol &&
              Symbol.toStringTag &&
              Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }),
              Object.defineProperty(e, "__esModule", { value: !0 });
          }),
          (a.t = function (e, r) {
            if ((1 & r && (e = a(e)), 8 & r)) return e;
            if (4 & r && "object" == typeof e && e && e.__esModule) return e;
            var t = Object.create(null);
            if (
              (a.r(t),
              Object.defineProperty(t, "default", { enumerable: !0, value: e }),
              2 & r && "string" != typeof e)
            )
              for (var n in e)
                a.d(
                  t,
                  n,
                  function (r) {
                    return e[r];
                  }.bind(null, n)
                );
            return t;
          }),
          (a.n = function (e) {
            var r =
              e && e.__esModule
                ? function () {
                    return e.default;
                  }
                : function () {
                    return e;
                  };
            return a.d(r, "a", r), r;
          }),
          (a.o = function (e, r) {
            return Object.prototype.hasOwnProperty.call(e, r);
          }),
          (a.p = "/"),
          (a.oe = function (e) {
            throw (console.error(e), e);
          });
        var i = (this.webpackJsonpreactjs = this.webpackJsonpreactjs || []),
          c = i.push.bind(i);
        (i.push = r), (i = i.slice());
        for (var l = 0; l < i.length; l++) r(i[l]);
        var f = c;
        t();
      })([]);
    </script>
    <script src="/static/js/2.542171dc.chunk.js"></script>
    <script src="/static/js/main.f01f29a2.chunk.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

I want to pick up inside body tag because of seeing easily.

.next/server/pages/index.html

<body>
    <div id="__next">
      <div class="Home_container__1EcsU">
        <main class="Home_main__1x8gC">
          <h1 class="Home_title__3DjR7"><a href="/blog">Move to Blog</a></h1>
        </main>
        <footer class="Home_footer__1WdhD">
          <a
            href="https://vercel.com?utm_source=create-next-app&amp;utm_medium=default-template&amp;utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
            >Powered by<!-- -->
            <img src="/vercel.svg" alt="Vercel Logo" class="Home_logo__1YbrH"
          /></a>
        </footer>
      </div>
    </div>
 </body>
Enter fullscreen mode Exit fullscreen mode

Build file of React.js

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
</body>
Enter fullscreen mode Exit fullscreen mode

Alright, We can see differences between both.
React has only simple contents but Next.js has already created the html file. It means that goole crawler can understand the contents created by Next.js. So, if you want to improve SEO on your web application, this framework is good choice.

Conclusion

In this article, I just compared the functionality between Next.js and React.js. Of course, this article show simple SSG's knowledge. I will write articles how to get API data with Next.js like using getStaticProps, getStaticPaths and so on.(getStaticProps and getStaticPaths are functions prepared by Next.js)

If you interested in this article, please comment to me!

Thank you for taking your time to read this article!

Biography

I am student of Vancouver, Canada and have job experience for Back-end technology. I also like AWS services and have some certifications.
Nowadays, I am learning Front-end Technology like JavaScript/TypeScript, React, Next.js.

I am looking for part-time job or volunteer work in Canada. If you are curious about me, Please contact me😸

LinkedIn

Discussion (0)

Forem Open with the Forem app