はじめに
Next.jsで認証の仕組みを作っていくチュートリアルの具体的な作業に入っていきます。
今回のゴール
この記事のゴールはNext.jsが動かせる状態にして、トップ画面にタイトルとボタンを設置。
その後、ボタンをクリックするとログイン画面、アカウント登録画面に遷移するところまでとなります。
- トップ画面完成イメージ
- ボタンをクリックするとログイン画面、アカウント登録画面に遷移
Next.jsで画面を作成したことがある方や、画面遷移の実装をしたことがある方は飛ばして頂いても問題ありません。
Tailwind CSSとは
このライブラリの特徴は、Bootstrapなどの他のCSSフレームワークと異なり、ボタンやテーブルなどの要素に対する一連の定義済みクラスを提供しないことである。代わりに、"ユーティリティ"CSSクラスを提供するので、これを組み合わせて要素をスタイリングする。
引用元:https://ja.wikipedia.org/wiki/Tailwind_CSS
CSSを書いたことがある方ならイメージつくかと思いますが、CSSを書くよりは若干短縮してCSSっぽいものを定義することができます。
Next.jsの開発元であるVercelはTailwind CSSを推奨しておりこの後登場するNext.jsのセットアップ時に一緒にTailwind CSSを導入できるようになっています。
今回のチュートリアルでも使っていこうと思います。
shadcn/uiとは
shadcn/uiはReactのUI コンポーネントライブラリであるRadix UIとCSSフレームワークのTailwind CSS を利用して作成した再利用可能なコンポーネントを提供してくれるライブラリです。
この後、入力フォームを作成したり、ボタンを作成したり実装に必要なコンポーネントを作っていくのですが、さすがにdivタグやbuttonタグを駆使して1から作るとなると時間がかかります。
ライブラリを活用して実装時間を短縮していきたいと思います。
環境セットアップ
下記のコマンドでNext.jsバージョン14をセットアップしていきます。
$ npx create-next-app@14.0.4 tutorial-nextjs-14-auth
幾つか質問が出てきますが全てYesで問題ありません。
3番目に聞かれた質問が先ほど紹介したTailwind CSSとなります。
Yesを選択することですぐ使える状態となります。
Need to install the following packages:
create-next-app@14.0.4
Ok to proceed? (y) y
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /Users/test/Documents/workspace/tutorial-nextjs-14-auth.
Using npm.
Initializing project with template: app-tw
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- autoprefixer
- postcss
- tailwindcss
- eslint
- eslint-config-next
それでは一度、Next.jsを起動してみましょう。
$ npm run dev
localhost:3000
で下記の画面が表示されればOKです。
次にshadcnをインストールしていきます。
npx shadcn@latest init
ここでも幾つか質問が出てきます。
①Styleは? -> New York
②Base Colorは? -> slate
③CSS Valiablesは使う? -> true
こちらは後で設定変更も可能です。
✔ Preflight checks.
✔ Verifying framework. Found Next.js.
✔ Validating Tailwind CSS.
✔ Validating import alias.
✔ Which style would you like to use? › New York
✔ Which color would you like to use as the base color? › Slate
✔ Would you like to use CSS variables for theming? … no / yes
✔ Writing components.json.
✔ Checking registry.
✔ Updating tailwind.config.ts
✔ Updating app/globals.css
✔ Installing dependencies.
✔ Created 1 file:
- lib/utils.ts
Success! Project initialization completed.
You may now add components.
インストールが完了すると幾つかファイルが追加されているかと思います。
先ほど設定した内容はこちらに反映されています。
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
また/lib
配下に下記のファイルが作成されます。
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
こちらはTailwind CSSを書くときの便利な関数となります。
使い方については後ほどご紹介します。
ここまではあくまでshadcnを使うための土台の設定みたいなもので、
個々のコンポーネントを使うにはそれぞれ都度インストールしていくことになります。
まずはボタンのコンポーネントをインストールしてみます。
$ npx shadcn@latest add button
すると、/components/ui
配下に下記のファイルが作成されます。
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
最後にエクスポートされている、Button
(必要に応じてbuttonVariants
)を使ってボタンを実装していきます。
コードを読むと、variant
とsize
というキーがあるかと思います。
そしてそれぞれにTailwind CSSで色々と定義されています。
ボタンコンポーネントを扱うときにはこのvariant
とsize
を使うことでボタンの色や大きさを自分好みに設定できるようになっています。
トップ画面作成
まずボタンコンポーネントが使えるか確認したいので、/app
配下のpage.tsxで下記のようにコードを書きます。
import { Button } from "@/components/ui/button"
export default function Home() {
return (
<main>
<Button variant='destructive' size='lg'>テスト用のボタン</Button>
</main>
)
}
Next.jsを起動すると、赤いボタンが表示されるかと思います。
今回はvariant='destructive'
と設定したので赤になっていますが、他のvariant
を使うと色が変わることが確認できるかと思います。
ボタンコンポーネントが使えることが確認できましたので、早速トップ画面を作っていきます。
globals.css
に以下のコードを追記します。shadcnのインストールで色々とコードが書き込まれていますがそのまま残しておいてください。
@tailwind base;
@tailwind components;
@tailwind utilities;
+ html,
+ body,
+ :root {
+ height: 100%;
+ }
以下、略
次にボタンコンポーネントに画面遷移の処理を実装したコンポーネントを作ります。
- アカウント登録画面に遷移するコンポーネント
- ログイン画面に遷移するコンポーネント
2つ作ります。
/components/auth
配下
'use client'
import { useRouter } from 'next/navigation'
import { Button } from '../ui/button'
export const LoginButton = () => {
const router = useRouter()
const onClick = () => {
router.push('/auth/login')
}
return (
<Button onClick={onClick} className="w-full cursor-pointer">
ログインする
</Button>
)
}
同じく/components/auth
配下
'use client'
import { useRouter } from 'next/navigation'
import { Button } from '../ui/button'
export const RegisterButton = () => {
const router = useRouter()
const onClick = () => {
router.push('/auth/register')
}
return (
<Button
onClick={onClick}
variant="secondary"
className="w-full cursor-pointer"
>
アカウントを登録する
</Button>
)
}
作成後に、トップ画面でこれらのコンポーネントを使います。
import { LoginButton } from '@/components/auth/login-button'
import { RegisterButton } from '@/components/auth/register-button'
export default function Home() {
return (
<main className="flex h-full flex-col items-center justify-center bg-sky-100">
<div className="space-y-6 text-center">
<h1 className={'text-6xl font-semibold drop-shadow-md'}>
トップ画面
</h1>
<p className="text-lg">Next.jsによる認証チュートリアル</p>
<div>
<LoginButton />
</div>
<div>
<RegisterButton />
</div>
</div>
</main>
)
}
Next.jsを起動し下記のような内容が表示されればOKです。
補足:このような画面が出てくるケースがあるかと思います。
クライアントコンポーネントで動かす必要のあるケースで'use client'
をつけ忘れた場合によく出てくるメッセージです。
今回のケースですと、login-button.tsx
やregister-button.tsx
などでつけ忘れていないかご確認ください。
現状、ボタンをクリックすると「404 | This page could not be found.」が表示されるかと思います。
この記事の最後のセクションとなるログインとアカウント登録の画面を作成していきたいと思います。
ログインとアカウント登録の画面作成
- ログイン画面
/app/auth/login
配下に下記のファイルを作成します
const LoginPage = () => {
return <div>ログイン画面</div>
}
export default LoginPage
- アカウント登録画面
/app/auth/register
配下に下記のファイルを作成します
const RegisterPage = () => {
return <div>アカウント登録画面</div>
}
export default RegisterPage
トップ画面からそれぞれのページに遷移できればOKです。
まとめ
今回はNext.jsのセットアップ及びshadcnのセットアップを行いました。
その後、インストールしたライブラリを使ってトップ画面の作成と、ボタンをクリックして画面遷移の動作確認まで実施しました。
次回は再びこれらのライブラリを駆使してアカウント登録画面で使う入力フォームを作っていきます。
また作りながらTailwind CSSやshadcnの使い方をもう少し掘り下げていけたらと思います。
次の記事はこちら