microCMS + Next.js + Chakra UIでブログ作成
作成:2022.10.03
更新:2022.10.23
microCMSのサイトのチュートリアルとChakraUIの導入と追加するメモ書き
完全独学の非エンジニアなので間違ってることあったら教えて欲しいです。
チュートリアル何個かこなして、最後にChakraUIでデザイン整えてくのが良さそう。
yarn addするものメモっとく。
microCMS + Next.jsでJamstackブログを作ってみよう
https://blog.microcms.io/microcms-next-jamstack-blog/
microCMSのリッチエディタで記述した内容はHTML形式で取得することができます。
しかし、HTML内にclassを付与することが現状できないので、本文を囲うdivにclassを付与し、タグ指定でcssを書いていきます。
そのままこなす。
yarn create next-app --typescript
yarn add microcms-js-sdk
yarn add sass
ChakraUI Getting Started with Nextjs
https://chakra-ui.com/getting-started/nextjs-guide
そのままコピペ。
iconも一緒にいれとく。
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6
yarn add @chakra-ui/icons
Next.jsでカテゴリー機能を実装してみよう
https://blog.microcms.io/next-category-page/
そのまま。
Next.js(SSG)でページネーションを実装してみよう
https://blog.microcms.io/next-pagination/
これにプラスしてuseRouterからページ数参照して今いるページは目立つように直したい。
カテゴリ別のページネーションをしようとすると面倒。
サーバサイドでシンタックスハイライトを行う
https://blog.microcms.io/syntax-highlighting-on-server-side/
Nuxtjsの見本だけど、Nextjsもほとんど一緒
yarn add highlight.js
yarn add cheerio
export const getStaticProps = async (context: any) => {
const id = context.params.id;
const data = await client.get({
endpoint: "articles",
queries: { limit: 10},
contentId: id,
});
const $ = cheerio.load(data.body);
$("pre code").each((_, elm) => {
const result = hljs.highlightAuto($(elm).text());
$(elm).html(result.value);
$(elm).addClass("hljs");
});
data.body = $.html();
return {
props: {
article: data,
},
};
};
dataの中身をconsole.logで確認しておくとよさそう。
aタグはrel="noopener noreferrer"ついてる。
Next.jsで月別アーカイブを実装してみよう
https://blog.microcms.io/monthly-archive/
デフォルトで返ってくる日付が使いにくいので変換する。
アーカイブは実装しないけど、記事の作成日や更新日の日付の表示を整えるのに使う用の関数を作っておく。
yarn add dayjs
//utils.ts
export const formatDate = (date: any) => {
const formattedDate = dayjs
.utc(date)
.tz("Asia/Tokyo")
.format("YYYY/MM/DD HH:mm");
return formattedDate;
};
ここまでチュートリアルこなすとだいたいの形になったのでデザイン整えてく。
参考
Chakra Templates
https://chakra-templates.dev/
Chakra UIの歩き方 & Tips集
https://zenn.dev/terrierscript/books/2021-05-chakra-ui
Chakraで困ってググってるとだいたいここに行き着きました本当に感謝
最初に導入したscssに関して。
https://blog.microcms.io/microcms-next-jamstack-blog/
microCMSのリッチエディタで記述した内容はHTML形式で取得することができます。
しかし、HTML内にclassを付与することが現状できないので、本文を囲うdivにclassを付与し、タグ指定でcssを書いていきます。
上記はリッチエディタで引用設定だが、表示上かわらないのでscssでblockquoteを追加する。
.post {
~~~~~
& > blockquote {
margin: 20px;
border-left: 3px solid #f86c3d;
padding-left: 10px;
}
}
Chakraのglobal stylesでもいける。
import { extendTheme } from "@chakra-ui/react";
const theme = extendTheme({
styles: {
global: {
body: {
backgroundColor: "white",
color: "gray.800",
},
blockquote: {
m: "20px",
pl: "10px",
borderLeft: "4px",
borderLeftColor: "#f86c3d",
},
},
},
});
export default theme;
同様に、global stylesでh1やh2も定義すればdangerouslySetInnerHTMLの部分にも適用される。
ChakraのHeadingはh2タグ、Textはpタグになる。
だいたい記事詳細ページはこんな感じになるので、リッチエディターで見出し2使ってたりすると訳わからなくなる。
<Heading fontSize={{ base: "2xl", md: "3xl" }}>{article.title}</Heading>
<Text fontSize={{ base: "sm", md: "sm" }}>作成:{formatDate(article.publishedAt)}</Text>
<Box>
<div
dangerouslySetInnerHTML={{
__html: `${article.body}`,
}}
className={styles.post}
/>
</Box>
チュートリアル通りに、dangerouslySetInnerHTML内だけはscssのほうが管理しやすいかなと思ったけど、とりあえずはカスタムテーマにまとめてみた。
html-react-parser使う方法もあるみたい。
globalスタイルはここ参照。
Customize Theme
https://chakra-ui.com/docs/styled-system/customize-theme#customizing-global-styles
NextjsのLinkとChakraUIのLinkの使い方
https://chakra-ui.com/docs/components/link#usage-with-nextjs
passHrefがChakraUIの<Link>にhrefプロパティを渡してくれる
import NextLink from "next/link"
<NextLink href='/home' passHref>
<Link>Home</Link>
</NextLink>
Google Analyticsの追加
参考
Nextjsのサンプル
https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics
Next.jsでGoogle Analyticsを使えるようにする
https://panda-program.com/posts/nextjs-google-analytics
現在のIDは測定ID(Gから始まるやつみたいです)
左下の管理>データストリーム>対象サイト>測定ID
反映までに少し時間かかるので焦らない。
環境変数も登録忘れずに。
戻るボタンの追加
useRouter で簡単にできる
+import { useRouter } from "next/router";
const BlogId = ({ article, parentCategory }: Props) => {
+ const router = useRouter();
return (
~~~~
<Button
alia-label="戻る"
onClick={() => router.back()}
m={"20px"}
p={"20px"}
colorScheme={"blue"}
variant="outline"
>
戻る
</Button>
);
};
export default BlogId;