isirmtブログ
タグシリーズ投稿
お気に入りのタグ

ブログを書いている人

isirmt

ホームページ

GitHub
github_user_icon
isirmt
Software & Web
@isirmt

(管理者用)ダッシュボード

© isirmtBuild with NextjsBlogWithGitPAT  (bbf84c2)
  1. 【Next.js】日付カードコンポーネントとHydrationWarning
  2. 完成物
  3. 作成
  4. イメージ
  5. コンポーネンの作成
  6. フォントについて
  7. HTML/CSS 設計について
  8. HydrationWarning (Error)について
  9. 良い修正案はあるか?
共有
2024
9
13

【Next.js】日付カードコンポーネントとHydrationWarning

コメント: 0件
Next.js
Tailwind CSS
HydrationWarning
当ブログのCSS設計 (2件)

前の投稿

2024
8
10

シリーズ【Next.js】両サイドにメニューがある場合のCSS設計

目標 左 :共通メニュー 中央:メインコンテンツ 右 :関連メニュー 左・右のどちらかは、お気に入りの表示や履歴といった常に...

読み込み中
シリーズを表示
Tailwind CSS
CSS
Next.js

次の投稿

最新の投稿です

完成物

上のようなものを作ります。当ブログにもある年・月・日を表示します。

作成

イメージ

イメージは「日めくりカレンダー」を意識しています。日付を横書きで記すだけでも良いと思いましたが、アクセントを付けたいということから始まりました。

コンポーネンの作成

執筆時のソースコードを用います。

まずは全文から。

/src/components/post/DateCard.tsx
import { mplus2 } from '@/lib/font';

export default function DateCard({ date }: { date?: string }) {
  const formattedDate = date ? new Date(date.replace(/-/g, '/')) : undefined;

  return (
    <time className={mplus2.className} dateTime={formattedDate?.toISOString()}>
      <div title={formattedDate?.toISOString()} className='flex items-center'>
        <span className='ml-2 w-6 translate-y-4 -rotate-90 text-sm leading-4'>
          {formattedDate ? formattedDate.getFullYear() : ''}
        </span>
        <div className='mr-4 flex size-16 flex-col items-center justify-center rounded-xl bg-gray-100 transition-colors dark:bg-slate-700'>
          {formattedDate ? (
            <div className='text-center'>
              <div className='text-sm leading-4'>{formattedDate.getMonth() + 1}</div>
              <div className='text-2xl leading-6'>{formattedDate.getDate()}</div>
            </div>
          ) : (
            <span className='text-3xl'>🎉</span>
          )}
        </div>
      </div>
    </time>
  );
}

フォントについて

まずはフォントから、M PLUS 2を使っています!

import { M_PLUS_2 } from 'next/font/google';

export const mplus2 = M_PLUS_2({
  subsets: ['latin'],
  weight: '400',
});

このように、next/font/googleからフォントをインポートし、インスタンスを作成することで使用可能になりexportで他のファイルで利用可能にします。

HTML/CSS 設計について

まずは、timeタグで括ります。ここで、datetime属性を付与しておくことでSEO効果が..?

渡す値はISOフォーマットで問題ないでしょう。

ここによると、以下の記載があります。

明確な日付を表示する: ページ上で目立つように日付を表示します。

HTML内で明確な記載があることに越したことはありません。

実際、このように出力されている状態は正確です。

次に、表示の設計です。大きなdivで2つの要素を並べます。1つは「年」を回転した状態で表示する。もう1つはカレンダー形式で表示する、です。

「年」の表示
<span className='ml-2 w-6 translate-y-4 -rotate-90 text-sm leading-4'>
  {formattedDate ? formattedDate.getFullYear() : ''}
</span>

ここで、leading-4は1行あたりの高さを表しており、複数行ある場合の間の調整に使うオプションです。90度回転し、inline-blockとして判定を持っているので直接横のカレンダーとの隙間に響きます。

「月」「日」の表示
<div className='mr-4 flex size-16 flex-col items-center justify-center rounded-xl bg-gray-100 transition-colors dark:bg-slate-700'>
  {formattedDate ? (
    <div className='text-center'>
      <div className='text-sm leading-4'>{formattedDate.getMonth() + 1}</div>
      <div className='text-2xl leading-6'>{formattedDate.getDate()}</div>
    </div>
  ) : (
    <span className='text-3xl'>🎉</span>
  )}
</div>

まずは、formattedDateの定義によって分岐します。日付が存在しない場合を考慮して、取り敢えず🎉を表示するようにしました。

日付を中央ぞろえで表示し、formattedDate.getMonth() + 1のように、月は+1で表示します。そのままでは0~11の出力になるので注意です。

あとは、leadingで表示間を調整して完成です!

HydrationWarning (Error)について

今回のブログ作成で個人的に一番遭遇したエラーです。サーバーサイドとクライアントサイドのレンダリングに差があると生じます。

今回の件では同じ引数でも面白いことが起こります。

とPCでは表示されて、iPhoneでは、

まさかの NaN 出力!

スマホでローカルサーバにアクセスしたとき驚きました。原因解決を図っていたところ、違う表記にすればPCと同様の結果が得られました。

それが今回の

const formattedDate = date ? new Date(date.replace(/-/g, '/')) : undefined;

ですね。-を/に置き換えただけです。つまり、-が無ければ問題回避ができました。そのため、現状はこのまま運用しています。

良い修正案はあるか?

しかし、あまり美しい修正方法とは言えません。今回の発生原因はクライアントサイドでコンポーネントを呼び出すことで発生します。サーバーサイドレンダリングでは完成済みで提供してくれますからね。

つまり、-が無ければ問題回避ができました。

電話番号として認識されたりするのでしょうか。

<meta name="format-detection" content="telephone=no"/>

iOSの親切な設計が表示を変えてしまいエラーを起こすならこれで解決するかも...?

もしくは、inline-blockとして確立してもらうために<span>で挟めば解決するかも...?

また検証した際に執筆しようと思います。

コメント

自動更新
コメントはまだありません
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
GitHub - isirmt/Next...Markdown blog u...https://github.com/isirmt/NextjsBlog...thumb
ウェブページの最適な日付を Google...https://developers.google.com/search...thumb
失敗例
Google 検索結果
完成物
完成物
M PLUS 2 - Google Fo...M+ FONTS is a l...https://fonts.google.com/specimen/M+...thumb