はじめに
当ブログでは、前の記事も更新があれば、ちょこちょこ手を加えようと思い、あらかじめ記事の作成日と更新日をそれぞれ管理していました。
せっかく管理しているので、新規投稿や更新を一目で分かるように、記事一覧に「New」と「Update」のラベルを追加することにします。
実装方法
基本的な考え方
ラベルの表示条件は以下のとおりです。
- New:記事の作成日が、ビルド時点で14日以内の場合
- Update:過去記事のみ。記事の更新日が、ビルド時点で14日以内の場合
実装
記事はマークダウン形式なのですが、パースする際に、各記事に対して isNew
と isUpdate
の2つのフラグを追加します。
1export function getAllPosts(): Post[] { 2 ⋮ 3 4 const today = new Date() 5 const twoWeeksAgo = new Date(today) 6 twoWeeksAgo.setDate(today.getDate() - 14) 7 8 const isNew = new Date(data.createdAt) > twoWeeksAgo 9 if (isNew) { 10 formattedData.isNew = true 11 } 12 13 const isUpdated = new Date(data.updatedAt) > twoWeeksAgo 14 if (isUpdated && !isNew) { 15 formattedData.isUpdated = true 16 } 17 18 ⋮ 19}
JSX側での表示
記事一覧のコンポーネントで、フラグに応じてラベルを表示します。
1function PostCard({slug, formattedData}) { 2 return ( 3 <article> 4 ⋮ 5 {isNew && <LabelNew />} 6 {isUpdated && <LabelUpdate />} 7 ⋮ 8 </article> 9 ) 10}
スタイリング
TailwindCSSを使用し、ベースとなるスタイルは共通化しています。
1const baseClass = 2 'absolute inline-flex items-center justify-center p-2 h-5 text-xs text-white rounded-md md:start-2 md:top-2 top-1 start-1' 3const LabelNew = () => { 4 return <div className={`${baseClass} bg-red-500`}>new</div> 5} 6const LabelUpdate = () => { 7 return <div className={`${baseClass} bg-blue-500`}>update</div> 8} 9 10export { LabelNew, LabelUpdate }
かなりシンプルですが、見た目は以下のとおりです。
注意点
基本的に日付の計算には注意が必要です。意図しないタイムゾーンの場合、表示結果に差が出る可能性があります。
また、本ブログはNext.js でSSGを使用しています。当たり前ですが、ビルド時点で計算されるため、その日で固定されます。
私のブログは2週間に一回程度は手をいれるので、ひとまずこれで良いかなと思います。
気になるようなら定期的なビルドやISRの活用を検討するかもしれません。
まとめ
「New」と「Update」のラベルを追加する実装方法を紹介しました。
シンプルな実装ですが、新着情報や更新情報が一目で分かるようになります。
今後は、ラベルのアニメーション効果や、より柔軟な更新情報(n日前に更新など)の表示も検討していきたいと思います。
ではまた。