Day 11 of #100DaysOfCode: The basis of Next.js - Pages, Link, and Meta
Tags: 100daysofcode, nextjs, react, javascript
Published: 2020-05-05 14:22:42

## Introduction
It's easy to use Next.js to write a React application. There are a few basic feature for Next.js.
* Create Next.js App
* Pages
* Link
* Fetching data
* Meta in pages

## Create Next.js App
1.Installation
```
npm init
npm install --save react react-dom next
mkdir pages
```
2.Edit package.json
```
"scripts": {
    "dev":"next",
    "build":"next build",
    "start":"next start"
}
```
3.Create pages/index.js
```javascript
const Index = () => (<h1>hello</h1>)
export default Index;
```
4.run
```
npm run dev
```
5.Open browser and visit http://localhost:3000
###Setting up for TypeScript
1.Create tsconfig.json
```
touch tsconfig.json
```
2.run
```
npm run dev
```

##Pages
**In Next.js, a page is a React Component exported from a .js, jsx, .ts, or .tsx file in the pages directory. Each page is associated with a route based on its file name.
Example: If you create pages/about.js that exports a React component like below, it will be accessible at /about.
source: https://nextjs.org/docs/basic-features/pages**
* Create about.js
```javascript
function About() {
  return <div>About</div>
}
export default About
```
* Visit http://localhost:3000/about

##Link
```javascript
import Link from 'next/link'
const Index = () => (
    <div>
        <h1>hello</h1>
        <link href='/about'>
            <a> about </a>
        </link>
    <div>
)
export default Index;
```

##Fetching data
1.Use getInitialProps to fetch data then pass data from props
2.Use next/router to rerender the page to call getInitialProps again
```javascript
...
import fetch from "isomorphic-fetch";
import {useState} from 'react';
import Router from 'next/router'

const Index = ({news}) => {
    const [value, setValue] = useState({
        text1:'whatever',
        text2:'whatever'
    })
    const {text1, text2} = value;
    
    const handleChange = name => e => {
      setValue({...value, [name]: e.target.value})
    }
    
    const handleSubmit = e => {
      e.preventDefault();
      Router.push(`/news?searchTerm=${text1}`)
    }
    
    const searchForm = () => (
        <form onSubmit = {handleSubmit}>
            <input 
              type = "text" 
              value={text1}
              onChange = {handleChange('text1')}/>
            <button></button>
            <input 
              type = "text" 
              value={text2}
              onChange = {handleTextChange('text2')}/>
            <button></button>
        </form>
    )
    
    return (
      {searchForm()}
    )
}

Index.getInitialProps = async ({query}) => {
  let news;
  try {
    const res = await fetch(`.../search?query=${query.searchTerm}`);
    news = await res.json();
  } catch (err) {
    news = [];
  }
  
  return {
      news
  }
}
export default Index;
```
## Shallow routing
**Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps, getStaticProps, and getInitialProps. To enable shallow routing, set the shallow option to true. Consider the following 
source:https://nextjs.org/docs/routing/shallow-routing**
```javascript
import { useEffect } from 'react'
import { useRouter } from 'next/router'

// Current URL is '/'
function Page() {
  const router = useRouter()

  useEffect(() => {
    // Always do navigations after the first render
    router.push('/?counter=10', undefined, { shallow: true })
  }, [])

  useEffect(() => {
    // The counter changed!
  }, [router.query.counter])
}

export default Page
```

##Meta in pages
* Head 

```javascript
import Head from 'next/head'
...
<Head>
    <title></title>
    <meta name="des" content="..."/>
    <meta name="keywords" content="seo"/>
    <meta name="author" content="..."/>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</Head>
```

* Document

```javascript
import Document, {Html, Head, Main, NextScript} from 'next/document'
class MyDocument extends Document {     
    render() {         
        return (             
            <Html>                 
                <Head>      
                    <title></title>
                    <meta name="des" content="..."/>
                    <meta name="keywords" content="seo"/>
                    <meta name="author" content="..."/>      
                </Head>                 
                <body>                     
                    <Main />                     
                    <NextScript />                 
                </body>             
             </Html>         
         )     
      } 
}
export default MyDocument
```

## Articles
There are some of my articles. Feel free to check if you like! 
* My blog-posts for software developing: https://medium.com/a-layman
* My web resume: https://jenhsuan.github.io/ALayman/cover.html
* Facebook page: https://www.facebook.com/imalayman