Skip to content

Discordクローン作成 1. 環境構築〜Clerkの設定

公開日|更新日

表紙

1. 環境構築

環境構築

shadcn/ui を利用する。手順は公式にしたがう。

Next.js
Install and configure Next.js.
Next.js favicon https://ui.shadcn.com/docs/installation/next
Next.js

Next.jsプロジェクトの作成

terminal
pnpm create next-app@latest discord-clone --typescript --tailwind --eslint

作成したらプロジェクト内に移動する。

terminal
cd discord-clone

shadcn/uiのインストール

terminal
pnpm dlx shadcn-ui@latest init
 
 Which style would you like to use? » Default
 Which color would you like to use as base color? » Stone
 Would you like to use CSS variables for colors? ... no / yes

設定に応じたファイルが生成される。

components.json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "app/globals.css",
    "baseColor": "stone",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}

初期セットアップ

cssの設定

高さの設定を行う。

app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
 
html,
body :root {
  height: 100%;
}

pageの初期化

pages/index.tsx
export default function Home() {
  return (
    <p className="text-3xl font-bold text-indigo-500">Hello Discord Clone</p>
  );
}

Tailwindの補完を入れていない場合は以下を導入しておく

Tailwind CSS IntelliSense - Visual Studio Marketplace
Extension for Visual Studio Code - Intelligent Tailwind CSS tooling for VS Code
Tailwind CSS IntelliSense - Visual Studio Marketplace favicon https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
Tailwind CSS IntelliSense - Visual Studio Marketplace

ボタンコンポーネントの作成

https://ui.shadcn.com/docs/components/button shadcn/uiのボタンコンポーネントを利用する。 コンポーネントは作成するタイミングで components.json の設定を読み込み、設定に従った初期ファイルが生成される。

terminal
pnpm dlx shadcn-ui@latest add button

components\ui\button.tsx が生成される。ファイルの中身はtailwindベースでカスタマイズが可能となっているので、必要に応じて修正することができる。

cnライブラリについて

shadcn/uiのコンポーネントを追加すると以下のライブラリも合わせて追加される

lib\utils.ts
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

これはshadcn/uiのコンポーネントを利用する際に必要となるライブラリで、tailwindのクラスを結合してくれる。

sample
  <Button className={cn("bg-indigo-500", state && "bg-red-500")}>
    Click me
  </Button>

上記の例では、stateがtrueの場合に bg-red-500 が適用される。このような使い方ができるのが特徴。

2. ページ設定

フォントの設定

Open Sansに変更を行う。

layout.tsx
import type { Metadata } from "next";
import { Open_Sans } from "next/font/google";
import "./globals.css";
 
const font = Open_Sans({ subsets: ["latin"] });
 
export const metadata: Metadata = {
  title: "Team Chat App",
  description: "dicord clone",
};
 
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={font.className}>{children}</body>
    </html>
  );
}

フォルダ設定について

()を利用したフォルダ設定

Next.js では()を利用することでルーティングに影響しない形でフォルダを設定することができる。

app/(auth)/login/page.tsx
const LoginPage = () => {
  return <div>LoginPage</div>;
};
 
export default LoginPage;
 

http://localhost:3000/login でアクセスできる。

app/(auth)/signup/page.tsx
 

layoutの設定

フォルダを切り分けることでlayoutも制御することができる。

app/(auth)/page.tsx
const AuthLayout = ({ children }: { children: React.ReactNode }) => {
  return <div className="bg-red-500">{children}</div>;
};
 
export default AuthLayout;

3. 認証

Clerkの導入

Clerkは認証周りの機能を提供してくれるサービスです。Clerkを使うことで、認証周りの実装を簡単に行うことができます。 NextAuth(Auth.js)を使う選択肢もあります。

Clerk | Authentication and User Management
The easiest way to add authentication and user management to your application. Purpose-built for React, Next.js, Remix, and “The Modern Web”.
Clerk | Authentication and User Management favicon https://clerk.com/
Clerk | Authentication and User Management

Clerkにログインする

clerk-1

アプリケーションを作成する

clerk-1

クイックスタートにNext.jsへの取り込み方が表示される。

clerk-1

.envに追加する

env
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_
CLERK_SECRET_KEY=sk_test_

プロジェクトにClerkの追加

ドキュメントを確認するとNext.jsでの利用方法が記載されている。

Full Stack: Next.js Quickstart
Add authentication and user management to your Next.js app with Clerk.
Full Stack: Next.js Quickstart favicon https://clerk.com/docs/quickstarts/nextjs
Full Stack: Next.js Quickstart

手順に従って追加する

terminal
pnpm add @clerk/nextjs

プロバイダをマウントする

Full Stack: Next.js Quickstart
Add authentication and user management to your Next.js app with Clerk.
Full Stack: Next.js Quickstart favicon https://clerk.com/docs/quickstarts/nextjs#add-clerk-provider-to-your-app
Full Stack: Next.js Quickstart

layout.tsxにプロバイダをマウントする(手順どおりなので省略)。 Providerって何?というのは useContext のドキュメントを読むと理解が深まるはず。

clerkのミドルウェア設定の作成

デフォルト設定でauthMiddleware()を使用するとすべてのルートで認証が有効になる。 パブリックディレクトリ、認証が必要なディレクトリ等を管理するため、ミドルウェア設定を作成する。 (publicRoutes, ignoredRoutesを設定することで、認証が必要なルートを設定することができる)

middleware.ts
import { authMiddleware } from "@clerk/nextjs";
 
export default authMiddleware({
  // Routes that can be accessed while signed out
  publicRoutes: ['/anyone-can-visit-this-route'],
  // Routes that can always be accessed, and have
  // no authentication information
  ignoredRoutes: ['/no-auth-in-this-route'],
});
 
export const config = {
  // Protects all routes, including api/trpc.
  // See https://clerk.com/docs/references/nextjs/auth-middleware
  // for more information about configuring your Middleware
  matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};

サインアップ/サインイン ページの作成

以下ドキュメントの手順に従って準備 https://clerk.com/docs/references/nextjs/custom-signup-signin-pages

サインアップ

app/(auth)/(routes)/sign-up/[[...sign-up]]/page.tsx
import { SignUp } from "@clerk/nextjs";
 
export default function Page() {
  return <SignUp />;
}
 

サインイン

app/(auth)/(routes)/sign-in/[[...sign-in]]/page.tsx
import { SignIn } from "@clerk/nextjs";
 
export default function Page() {
  return <SignIn />;
}
 

環境変数に追加

.env
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/

画面レイアウト調整

これだけでclerkのログイン画面は表示されるが、画面中央に表示されるように調整する。

app/layout.tsx
const AuthLayout = ({ children }: { children: React.ReactNode }) => {
  return (
    <div className="h-full flex justify-center items-center">{children}</div>
  );
};
 
export default AuthLayout;

ここまででClerkによるログイン認証が表示されるようになる。

clerk-1

サインアウトボタンの追加

ログイン後にサインアウトできるようにボタンコンポーネントを追加する

app/(main)/(routes)/page.tsx
import { UserButton } from "@clerk/nextjs";
 
export default function Home() {
  return (
    <div className="">
      <UserButton />
    </div>
  );
}
 

ログアウト後にlocalhostにリダイレクトしないが現時点では正常。再び実行すると正常に動作する。 ※っぽいのだけど、ログアウト後にログイン画面にリダイレクトが動く場合と動かない場合がある。ひとまずそのまま