👻

NextjsでFaviconを動的に生成し、Faviconを見るだけで天気がわかるようにしました

2023/10/12に公開

Favicon見て天気確認するやつおる?

すぐ答え見たい人向け

これ置いたら動くよん

src/app/icon.tsx
import { ImageResponse } from 'next/server';

// Route segment config
export const runtime = 'edge';

// Image metadata
export const size = {
  width: 32,
  height: 32,
};
export const contentType = 'image/png';

const url =
  'https://api.open-meteo.com/v1/forecast?latitude=35.6895&longitude=139.6917&current=weathercode&timezone=Asia%2FTokyo&forecast_days=1';

/**
 * @see https://open-meteo.com/en/docs Weather variable documentation
 */
const getWeatherIcon = (weathercode: string) => {
  switch (true) {
    case Number(weathercode) === 0:
      return '☀';
    case Number(weathercode) >= 1 && Number(weathercode) <= 3:
      return '⛅';
    case Number(weathercode) >= 40 && Number(weathercode) <= 49:
      return '🌫';
    case Number(weathercode) >= 50 && Number(weathercode) <= 59:
      return '🌧';
    case Number(weathercode) >= 60 && Number(weathercode) <= 69:
      return '☔';
    case Number(weathercode) >= 70 && Number(weathercode) <= 79:
      return '☃';
    case Number(weathercode) >= 80 && Number(weathercode) <= 84:
      return '🌦';
    case Number(weathercode) >= 85 && Number(weathercode) <= 89:
      return '🌨';
    case Number(weathercode) >= 90 && Number(weathercode) <= 99:
      return '⚡';

    default:
      return '👻';
  }
};

// Image generation
export default async function Icon() {
  const json = await fetch(url).then((res) => res.json());

  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 24,
          borderRadius: '50%',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          color: '#333',
        }}
      >
        <span>{getWeatherIcon(json.current.weathercode)}</span>
      </div>
    ),
    {
      ...size,
    }
  );
}

使ったもの

やり方

https://nextjs.org/docs/app/api-reference/file-conventions/metadata/app-icons

上記の通り、NextjsのApp Router以降は icon.tsx みたいなファイルに適切な実装配置するとfaviconとか色々生成してくれる。読んでくれ。

ImageResponseっていうOGPに利用するような動的な画像生成にも使えるAPIを利用して作成しているようです。そのへんは以下を見てくれ。

https://nextjs.org/docs/app/api-reference/functions/image-response

自分が書いたコードでは絵文字を多用しているが、openな絵文字に勝手に解釈してくれている。ImageResponseの第二引数のoptionにemojiの設定を渡すとopenな絵文字の中でいくつかの種類に変換してくれる(Twemojiとか)

特にFavicon見て天気確認するやつはおらんので、この実装はボツになりました

https://x.com/ksyunnnn/status/1712422086491431275?s=20

以上です。

Discussion