Open13
cather開発メモ
書籍レビューサイトの開発記録
目的:記録
方針:記述は頑張らない。しかし、途中でやめない
これ見ながらセットアップ
cssフレームワークは馴染みのあるzero-runtimeってことでtailwindを選択
ディレクトリ構成に悩む
Twitterで誰かの例が載ってたのでパクりたいのだがいいねしてなくて追えない・・・。
とりあえず微かな記憶を頼りに探る。
pandaが気になるのでこっちに乗り換え
参考記事
採用技術
- Next13.4.x
- pandacss
- vercel
作る理由
- ポートフォリオとして
- 自分が使いたい
- アイデアの検証
- 技術の検証
- 趣味
- 副業
- 表現の手段
tailwind intelisenseが聞かない
settings.json
"editor.quickSuggestions": {
"strings": true
}
Prisma
PlanescaleでDB立ててnpx prisma studiでポチポチデータ操作していく感じ
chakrauiだとsuspenseを使っているコンポーネントでhydration error
Hydration failed because the initial UI does not match what was rendered on the server.
上記エラーが出る
client componentをserver componentで呼び出しているのが原因?
このあたりよくわからない
コンポーネントでデータをfetchするのをやめるとエラーが出なくなることから恐らくこれが原因だと推測
解決策
ChakraUIをやめてzero-runtimeなpandacssを試す?
pandacss検証
これをpandacssで作ってみる
headerコンポーネントは以下のようになる。
import { css } from "@/styled-system/css";
import NextLink from "next/link";
export default function Header() {
return (
<header>
<div
className={css({
bg: "white",
color: "gray.600",
minH: "60px",
py: 2,
px: 2,
borderBottom: 1,
borderStyle: "solid",
borderColor: "gray.200",
alignItems: "center",
})}
>
<div
className={css({
display: "flex",
justifyContent: "space-between",
maxW: "5xl",
mx: "auto",
})}
>
<h1 className={css({ fontSize: "lg" })}>
<NextLink href="/">Blog App</NextLink>
</h1>
<NextLink
className={css({
fontSize: "sm",
fontWeight: 600,
color: "white",
bg: "orange.400",
_hover: { bg: "orange.300" },
})}
href="/articles/new"
>
記事を書く
</NextLink>
</div>
</div>
</header>
);
}
Chakra製だけあって書き味はほぼ同じ
route handlers
app routerを使っている場合Api routesではなくRoute handlersなるものが使えるらしい。Api routesと書き味が少し違う。if (method === "GET")とかしてハンドリングしないのでこちらのほうが可読性は高い印象。api/route.tsのようにしないと認識されない。この場合/apiに対してリクエストするとレスポンスが返る。
api/route.ts
import fs from "fs";
import { randomUUID } from "crypto";
import { NextRequest } from "next/server";
const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
export async function GET() {
await delay(1500);
const articles = JSON.parse(fs.readFileSync("articles.json", "utf8"));
articles.articles.sort((a: any, b: any) => {
return new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
});
return new Response(JSON.stringify(articles), {
status: 200,
headers: {
"content-type": "application/json",
},
});
}
export async function POST(req: NextRequest) {
await delay(1000);
const { title, content } = await req.json();
const articles = JSON.parse(fs.readFileSync("articles.json", "utf8"));
const id = articles.articles.length + 1;
const date = new Date();
const slug = randomUUID();
const newArticle = {
id,
title,
slug,
content,
createdAt: date,
updatedAt: date,
};
articles.articles.push(newArticle);
fs.writeFileSync("articles.json", JSON.stringify(articles));
return new Response(JSON.stringify(newArticle), {
status: 200,
headers: {
"content-type": "application/json",
},
});
}