Open10

Full Stack Netflix Clone in Next.js 13

wadakatuwadakatu

以下のYoutubeを参考にNetflixクローンを作成する
動画内では Next.js 12を使っている
しかし、現状最新はNext.js 13なので、そちらを利用する

https://youtu.be/mqUN4N2q4qY

wadakatuwadakatu

バージョン情報

node -> v18.16.1
npm -> 9.5.1
Next.js -> 13.4.9
wadakatuwadakatu

npx create-next-app --typescript

Next.js 12 と 13で聞かれる項目が結構異なる
Next.js 13の場合、TailwindCSS設定も簡単にできる
/srcディレクトリは使わず、/appディレクトリを使うようにする

wadakatuwadakatu

ファイル整理

  • stylesディレクトリはNext.js 13にはない
    • appディレクトリ直下にglobals.cssが配置されている
    • globals.cssにTailwindCSSの設定がされている
wadakatuwadakatu

Authページ作成

Next.js 12

Pages router

Pages routerの場合、Pagesディレクトリ直下にauth.tsxを作成すれば、http://localhost:3000/authで遷移可能

https://nextjs.org/docs/pages/building-your-application/routing

Next.js 13

App Router

App Routerの場合は、appディレクトリ直下にまずauthディレクトリを作成する必要がある。
そして、そのauthディレクトリ直下に、page.tsxを作成する
これで、http://localhost:3000/authでアクセスが可能になる。

https://nextjs.org/docs/app/building-your-application/routing#the-app-router

wadakatuwadakatu

Input.tsx onChangeエラー

Inputコンポーネントを使用すると以下のエラーに遭遇

- error Error: Event handlers cannot be passed to Client Component props.
  <... label="Email" onChange={function} id=... type=... value=...>
                              ^^^^^^^^^^
If you need interactivity, consider converting part of this to a Client Component.
    at stringify (<anonymous>)

解決策

'use client;' をInputコンポーネントを呼び出す側のファイル先頭に記述する

https://stackoverflow.com/questions/74471642/nextjs-13-button-onclick-event-handlers-cannot-be-passed-to-client-componen

wadakatuwadakatu

NextAuth ファイル構成

動画内では、apiディレクトリに[...nextauth].tsを作成している。
Next.js 13では、Router Handlersが採用されているので、APIを作成するにはroute.js | .tsの中にAPIを記述する必要がある。

そのため、app/auth/[...nextauth]/route.tsを作成した。

wadakatuwadakatu

会員登録処理

ファイル構成

Next.js 12

pages/api/register.ts

Next.js 13

app/auth/api/register/route.ts

メソッド名

Next.js 12

export default async function handler()...

命名はなんでも良さげ

Next.js 13

export default async function POST()...

命名は、HTTPメソッド名のみ(GET, POST, PUT, DELETEなど)

リクエスト・レスポンス

Next.js 12

import {NextApiRequest, NextApiResponse} from 'next'

リクエストから値を取り出す時
const {email, name, password} = req.body;
レスポンスを返す時
return res.status(422).json({error: 'このメールアドレスは既に登録されています。'});

Next.js 13

import {NextRequest, NextResponse} from 'next/server';

リクエストから値を取り出す時
const { email, name, password } = (await req.json()) as {
            name: string;
            email: string;
            password: string;
        };
レスポンスを返す時
 return NextResponse.json({error: 'このメールアドレスは既に登録されています。'}, {status: 422});
wadakatuwadakatu

ログイン処理(NextAuth.js)

Initializationの処理が、Next.js 12 (Page Router)とNext.js 13 (App Routerでは異なる)
Optionsに関しては、内容・書き方共に同じ

書き方参考

https://next-auth.js.org/configuration/initialization#route-handlers-app

https://next-auth.js.org/configuration/options

ルーティング変更

デフォルトでは、api/auth/*のパスでAPIが呼ばれる。
つまり、Next.js 13の場合、app/api/auth/[...nextauth]配下にroute.tsファイルを用意する必要がある。

しかし、app/auth/api/auth配下に[...nextauth]/route.tsを設置したい場合があるとする。
その場合、NEXTAUTH_URLbasePathのいずれかを記述すればOK
今回は、<SessionProvider>のbasePathを以下のように追加した

<SessionProvider basePath={'/auth/api/auth'}>
    {children}
</SessionProvider

https://next-auth.js.org/configuration/options#nextauth_url