Next.js13での対応記録

API Routes
公式ドキュメントだといかがApp RouterでのAPIの部分
Routing: Route Handlers | Next.js
基本的なルール
route.js|ts
ファイルがAPIのルートとして認識されるっぽい。
具体例で言うとこんな感じ。
app/api/route.ts
→ /api
app/api/user/route.ts
→ /api/user
Request, Response
Fetch APIのRequest, Responseの他に、それを拡張したNextRequest, NextResponseを使うことができる
こんな感じ
import { NextResponse } from "next/server";
export async function GET(request: Request) {
return NextResponse.json({ data: "aaaa" });
}
Responseではこんな感じでstatusの設定とかができる。
if (process.env.OPENAI_API_KEY) {
const errorMessage = {
error: {
message:
"OpenAI API key not configured, please follow instructions in README.md",
},
};
// https://stackoverflow.com/questions/43997163/how-to-make-request-body-type-compatible-with-requestinit-or-bodyinit-when-using
return new NextResponse(JSON.stringify(errorMessage), { status: 500 });
}
PathParameter
pageと同じようにapp/items/[slug]/route.ts
のように定義して、同じようにparamsの形でアクセスできる
export async function GET(
request: Request,
{ params }: { params: { slug: string } }
) {
const slug = params.slug // 'a', 'b', or 'c'
}
RequestBody
こんな感じでrequest bodyの値を取得できる
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const res = await request.json();
return NextResponse.json({ data: res });
}
% curl -X POST -H "Content-Type: application/json" -d '{"name":"太郎", "age":"30"}' localhost:3000/api
{"data":{"name":"太郎","age":"30"}}
参考にした資料

Layout
_appや_documentのファイルは作らず、レイアウトファイル(app/layout.*)に共通処理を書いていくのが正解っぽい
Providerの設定とかもapp/layout.*に書いていく
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<ChakraProvider>
<AuthProvider>
<>
<Hedaer />
{children}
</>
</AuthProvider>
</ChakraProvider>
</body>
</html>
);
}

Dynami Route
Path Parameterの取得方法
基本的には以下の通りにすればOK
Routing: Dynamic Routes | Next.js
まずファイルの構成をapp/blog/[slug]/page.js
のようにする。
あとはpropsの中で受け取りたいpath parameterを定義すればOK
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}

Storybookの導入
% npx storybook@latest init
ChakraUI
npm i -D @chakra-ui/storybook-addon

CHakraUI

Copy機能の実装
ChakraUIではカスタムフックがあるが、単純にinputと1対1の関係で紐づかなかったので独自に実装が必要だった
クリップボードにコピーする仕組み
以下がわかりやすかったが、Clipboard APIを使う。
navigator.clipboard.writeText(text)
【JavaScript】クリップボードのテキストをコピー・ペーストする【Clipboard API】|Into the Program
コピーボタンの実装
焼き直しにはなっちゃうが、useStateを使ってコピーボタン押下後3秒間は表示内容を変更。
ボタンクリック時に呼ばれるonCopyでフォームの内容をいい感じにまとめてクリップボードにコピー
const [hasCopied, setHasCopied] = useState(false);
...
const onCopy = () => {
setHasCopied(true);
const text = "inputを適用にここに整形して渡す";
navigator.clipboard.writeText(text);
setTimeout(() => {
setHasCopied(false);
}, 3000);
};
...
<Button
onClick={onCopy}
>
{hasCopied ? "Copied!" : "Copy"}
</Button>