How To Build My Own Website (1) - Next.js

5min read

Contents

  1. The choice of Next.js
  2. Parse and Display Markdown
  3. Style my website
  4. Image Optimization


I had always dreamed of building my own website, to express myself, to keep memory of what I have done, and to make others know me faster. Although I had self-learned web developing technologies, e.g. html/css, javascript, react, redux, jquery, etc, for a long time, there wasn't a golden chance to start this "huge" thing, regarding to the styling, routing, deploying and so on… All beginnings are hard😄

I used Jekyll for my Blog. It's like this:

But I am not satisfied with it. To customize the page, I need to give a HTML file, which is inconvenient.

Recently I met with Next.js. It is a React framework, which means I can write React Components✌️. After walking through its starter tutorial, which is to create a very simple blog app, I found it is the perfect framework that helps me to start my website building.

This article mainly talks about some basic features making it perfect for my website building. Next two articles: 1, 2 will illustrate how I deal with Markdown and Style.

In this article, firstly I will talk about some basic features making it perfect for my website building. Then I will illustrate how I deploy it to Github Pages.

Page-based Routing System

In Next.js, a page is a React Component placed under /pages directory. This hierarchy makes it clear to separate the page components with those feature components.

However, what the most powerful is that it supports dynamic routes. So:

  • a page defined as /pages/posts/[slug].js can power all my blog post pages, like /posts/2021-3-10-build-my-website-nextjs, /posts/2021-2-19-mock-requestanimationframe-in-jest, etc.

  • a page defined as /pages/blog/[[...page]].js can power not only /blog/*, but also /blog and /blog/*/*. So my paginated blog pages can be

    • /blog
    • /blog/page/2, /blog/page/3, ...
    • /blog/front-end, blog/unity
    • /blog/front-end/2, blog/unity/2, ...

    In next.config.js, I can define /blog/page/1 redirecting to /blog, /blog/front-end/1 redirecting blog/front-end. This is common web flavored.

    The redirects in next.config.js only works in Node.js environment, and do not affect client-side routing, see this. My website is statically exported, so when it is published on Github Pages, the redirects fails. Also I tried rewrites, but the result is not what I want, and it also fails to refresh by browser.

  • in React Component, I can obtain the route data by query object, which is accessed by the useRouter hook in next/router. So for the above multi-format routes, I can distinguish them by:

    // "/blog"
    query: { "page": false }
    query: { "page": null }
    query: { "page": [] }
    query: { "page": undefined }
    
    // "/blog/page/2", "/blog/page/3" ...
    query: { "page": [ 'page', '2'] }
    query: { "page": [ 'page', '3'] }
    
    // "/blog/front-end", "/blog/unity"
    query: { "page": [ 'front-end' ] }
    query: { "page": [ 'unity' ] }
    
    // "/blog/front-end/2", "/blog/unity/2"
    query: { "page": [ 'front-end', '2' ] }
    query: { "page": [ 'unity', '2' ] }

Pre-rendering

Next.js generates HTML for each page in advance. There are two forms: Static Generation and Server-side Rendering.

The difference is in when it generates the HTML for a page.

Commonly a personal website is static, which is generated at build time.

Data Fetching

Next.js also provides two ways to fetch external data for pre-rendering, with which I can generate blog pages by reading the local markdown files.

  1. getStaticPaths to specify which paths to pre-render. For example, in /pages/posts/[slug].js, the below code includes paths for all post pages.

     export async function getStaticPaths() {
       const posts = getAllPosts(['slug'])
    
    return {
         paths: posts.map((post) => {
           return {
             params: {
               slug: post.slug,
             },
           }
         }),
         fallback: false,
       }
     }
  2. getStaticProps to pass external data to the props of the page's React Component. For example, in /pages/posts/[slug].js, the below code passes the post data to the Post component for rendering.

      function Post({ post }) {
        //render the post
      }
    
      export async function getStaticProps({ params }) {
        let post = getPostBySlug(params.slug);
        return {
          props: {
            post,
          }
        }
      }

    The parameter params is from the params in the returned object of getStaticPaths.

Fast Refresh

Next.js enables Fast Refresh to allow me to glance at what I have just done. Think about this scenario:

I am writing this blog, and I want to see what it is like when it deploys.

ps. Jekyll enables fast refresh, too.

It's React!

There is no need to illustrate how React makes it easier to develop web pages here. I just want to say it is at the top of my list.

Deploy To Github Pages

Next.js app is recommended to deploy on Vercel, because it is an all-in-one platform developed by the same team. However, in spite of Vercel, I also want to deploy it on Github Pages, where my old Blog is, until I have my own domain.

The following steps show how I did to deploy to gh pages:

  1. Create a github repository, named with [github-user-name].github.io. If you don't follow this template, the pages will be under a subpath, e.g.. [github-user-name].github.io/[custom-github-repository-name], which may bring inconvenience in path.

  2. Set the remote origin to github repository.

  3. Do some customized configuration in next.config.js, like adding environment variables, plugins, etc.

  4. Install rimraf, gh-pages.

  5. Add scripts in package.json:

   {
       "scripts": {
       "deploy": "rm -rf node_modules/.cache && rimraf out && next build && next export && touch out/.nojekyll && gh-pages -d out -t true"
     },
   }
  1. Run
   npm run deploy
  1. Change github repository Settings. Navigate to GitHub Pages, set the Source to be branch "gh-pages", directory /(root), and click Save.

Why Not Use Existing Website Builder

1. It is Pricey!

Although some popular website builders, like Wix and WordPress, provide free services to create websites, the services are limited, unless you purchase for the Premium Plans. This is always what happens😅. ​

2. I am Not Advertising.

In my plans for the website, there is no intension for any advertisement. So it doesn't need to be fancy. In fact, I prefer it to be simple but tech-favored.

3. It is Not Under My Control.

There are indeed many templates on those website builders, which save us plenty of time to design and development websites. But they are just as what they are. I'd like to do what ever I want on my own website. It should be limitless😉.


MORE FROM THE BLOG

Use React Context + useReducer...

React Hooks have brought us much convenience in writing concise readable code. Recently, I have been enjoying the usage of...

4min read

How To Build My Own...

This article illustrates how I applied image optimization to improve the performance of my website.
2min read

How To Build My Own...

This article illustrates how I style my own website using Tailwindcss framework, make theme color configurable, and apply interactive animations.
2min read

How To Build My Own...

Parsing and displaying Markdown files are one of the most important things in building a personal website, because all my...

3min read