短縮リンク作成サービスを開発した話 - フロントエンド編01

## 概要
2023年末頃に、短縮リンク作成サービスを開発・リリースしました。
開発したサービスは以下のものになります。
[https://nlia.jp](N-LIA)
開発するにあたってのお話などは、前回の記事を参照してください。
[短縮リンク作成サービスを開発した話](https://zenn.dev/yatsumi823/articles/github-zenn-shorten-link-story-yatsumi)

この記事では、実際のコードも交えながら、どのような仕組みで動いているのかを解説します。

## 使用している技術
使用している技術は、以下の通りです。
- Next.js V14(Reactのフレームワーク)
- Pages Router(App Routerではないやつ)
- Next PWA(PWA対応)
- axios(バックエンドのサーバーとAPI通信するために使用)
- Chakra UI(UIのライブラリ)
- React Hook Form(フォームのバリデーションなど)

### Next.JS
Next.jsは、開発時点で最新バージョンの14を使用しています。Next.jsを使用した理由としては、当時デジタル庁のサイトにNext.jsが使われており、動作がかなり速いと思ったからです。

【参考リンク(Qiita)】
https://qiita.com/mu_tomoya/items/f78f1fad3a8b57ac7dc3

### Pages Router
App Routerを使用することも検討しましたが、当時はリファレンスのほとんどがPages Routerでのものだったため、App Routerの導入は見送りました。加えて、後述するChakra UIとの相性がそれほど良くなかったことも理由です。

### Next PWA
リンク作成のアプリなので、PWA対応したほうが良いかと思いました。Next.jsにてPWA対応する方法を調べたところ、以下の記事を見つけたため参考にさせていただきました。

【参考リンク(Qiita)】
https://qiita.com/Coa3/items/c81c8c7984bd5fc4ec69
Next PWAについては、Pages Router/App Routerそれぞれにて導入する方法を、別途執筆する記事にて紹介予定です。期待してお待ちください。

### axios
今回の開発方針として、Next.jsで構築する部分はVercelに、Laravelで構築する部分(バックエンド)はXServerにデプロイすることを最初に決定していました。
Next.jsをXServerにデプロイしなかった理由は、ビルドする手間が大変そうだったのとVercelでのページ表示速度などがかなり速かったからです。
逆に、LaravelをXServerにデプロイした理由は、今までXServerを個人的に使用しており、またLaravelのデプロイに関するリファレンスが充実していたからです。

話はそれましたが、こういった理由で別サーバーになる以上、データの送信/受信はAPIを使用せざるを得ません。そこで、調べたところaxiosが良さそうなので使用しました。

【参考リンク(Qiita)】
https://qiita.com/ksh-fthr/items/2daaaf3a15c4c11956e9

### Chakra UI
Next.jsでは、UIライブラリを導入することがよさそうです。特にcss初心者の私にとっては、UIを一から作ることが難しかったので、ライブラリ導入を決断しました。
ReactのUIライブラリではMUI(Material UI)が有名ですが、ありきたりになるのを防ぐために別のものを導入しようと思いました。様々なライブラリでコンポーネントを見ている限り、見やすくて実装難易度が容易なものとしてChakra UIを使用するのがよさそうだと思い、導入しました。

【参考リンク】
https://chakra-ui.com/docs/components

### React Hook Form
React Hook Formを使えばバリデーションなどが簡単に実装できそうだったので導入してみました。

## 実装編
### プロジェクトの作成
では、さっそく実装に移りましょう。作業用ディレクトリの中で以下のコマンドを実行しましょう。
```
npx create-next-app
```
すると、「What is your project named?」と聞かれるため、プロジェクト名を入力してEnterキーを押してください。(今回は「shortenlink」と入力しました。)

次に進むと、以下の質問があるので、以下のように設定します(小泉構文みたいですみません)。
- Would you like to use TypeScript? ... Yes (TypeScriptを使用します。使用しない場合はNoを選択)
- Would you like to use ESLint? ... Yes (ESLintというエラーチェックツールを使用します。使用しない場合はNoを選択)
- Would you like to use Tailwind CSS? ... Yes (Tailwind CSSという、デザインが簡単になるツールを使用します。使用しない場合はNoを選択)
- Would you like to use `src/`directory? ... Yes (ディレクトリ構成にこだわりがなければYesを選択)
- Would you like to use App Router? ... No (App RouterではなくPages Routerを使用するためNoを選択)

### Chakra UIの導入
こちらを参考に、Chakra UIを導入していきます。
https://chakra-ui.com/getting-started/nextjs-pages-guide

#### npmでインストール以下のコマンドを実行しましょう。
```
npm i @chakra-ui/react @chakra-ui/next-js @emotion/react @emotion/styled framer-motion
```

#### _app.tsxファイルの編集
_app.tsxファイルを以下のように編集します。ファイルがない場合は作成してください。
```tsx
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import { ChakraProvider } from '@chakra-ui/react'

export default function App({ Component, pageProps }: AppProps) { 
  return (
    <ChakraProvider>
      <Component {...pageProps} />
    </ChakraProvider>
  )
}

```
以上でChakra UIの導入は完了です。

### トップページの作成
続いてトップページを作成します。
トップページは、src/pagesの中の「index.tsx」です。Next.js Pages Routerでは、src/pagesの中に表示されるページを作成します。
N-LIAでは、今後短縮リンク以外のサービスも提供予定なので、使用するサービスを選択できる画面を作成します。
```tsx
import Head from 'next/head'
import { Inter } from 'next/font/google'
import styles from '@/styles/Home.module.css'
import { Heading, Text, Button, VStack } from '@chakra-ui/react'
import NextLink from 'next/link'

const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <>
      <Head>
        <title>N-LIA</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className={`${styles.main} ${inter.className}`}>
        <Heading>N-LIA</Heading>
        <Text>ご利用のサービスを選択してください。</Text>
        <VStack  textAlign={'center'}>
          <NextLink href={'/shortenLink'}>
            <Button m={2}>短縮リンク作成</Button>
          </NextLink>
        </VStack >
      </main>
    </>
  )
}

```

## 今日はここまで
かなり長くなってしまったので、いったん今回はここまでにします。次回は、リンクの作成ページの実装部分についてです。