🐱

【個人開発】猫のLGTM画像共有サービス、LGTMeowのデザインリニューアル + 多言語対応

2022/12/18に公開

はじめに

この記事は 個人開発 Advent Calendar 2022 の19日目の記事です。

猫のLGTM画像共有サービス、LGTMeow のデザインリニューアル + 多言語対応を行ないました。

最後まで読んで頂けると嬉しいです。(技術的な話がメインです。)

LGTMeowの紹介

猫のLGTM画像を共有できるサービスです。

https://lgtmeow.com

自分と同じく🐱好きのエンジニアの友人 kobayashi-m42 と共同開発・運用を行なっています。

サービスの概要に関しては以下の記事を見ていただきたいです。

https://zenn.dev/kobayashi_m42/articles/lgtmeow-idea

最初は集めた🐱画像をランダムに表示させていただけでしたが、途中でエンドユーザーが🐱画像をアップロードしてオリジナルのLGTM画像を作成できるようにしました。

Amazon Rekognition を使って🐱が写っていない画像がアップロードされないように制御しています。

https://lgtmeow.com/upload

過去に🐱画像を判定すとき時の内容も記事にしていますので興味があればこちらもご覧ください。

https://zenn.dev/keitakn/articles/amazon-rekognition-cat-image

デザイン変更の目的

リリース当初はリリースを最優先していたのもあり、CSSフレームワークの Bulma を使って作成したシンプルなデザインを採用していました。

ちなみに以下が以前のデザインのスクショです。

before-design

ありがたいことに海外ユーザーが割と増えていたので、さらに伸ばしたいという事で多言語化も考慮した新デザインにリニューアルしようと意思決定をしました。

プロジェクトの進め方

自分達はUIデザイナーではないので、多言語化も考慮した新デザインの作成はかなり厳しいと思いました。

そこで思い切ってプロのデザイナーの方にお願いすることにしました。

以下は最初の打ち合わせでデザイナーさんに見せたGitHub Discussionsのページです。

https://github.com/nekochans/lgtm-cat-frontend/discussions/144

こちらを元にプロトタイプを作成していただき、その後 Figma のデザインファイルを作成していただきました。

LGTMeow のフロントエンド側は lgtm-cat-frontend というリポジトリでNext.jsのアプリケーションとして運用していました。

新デザインの対応中もnpm packageのセキュリティアップデートや細かい機能改善などを継続して開発していました。

Gitのブランチの運用ルールの複雑化やマージ作業の煩雑さを避けるために @nekochans/lgtm-cat-ui というnpm packageを作成することにしました。

このnpm package内でFigmaのデザインを取り込んでComponentを作成していくことにしました。

開発の流れとしては以下の通りに進めました。

  1. https://github.com/nekochans/lgtm-cat-ui/issues にComponentごとにissueを作成する
  2. issueごとにPRを作成して Chromatic にデプロイされたStorybookをデザイナーさんに確認していただく
  3. レビューがOKだったら次にissueに取り掛かる

ちなみにこのサービス開発においては友人(kobayashi-m42)と役割分担を行なっており、自分の担当はフロントエンドの開発がメインなので、このプロジェクトの開発は自分がメインで進めました。

できたもの

新デザインで作成したReactComponentを提供するnpm packageとフロント側のNext.js製のアプリケーションになります。

これらに関して説明していきます。

npm package

@nekochans/lgtm-cat-ui という名称のnpm packageです。

技術選定

React

Next.js製のアプリケーションから利用するのでReactComponentを作っていくことになります。

デザインリニューアルプロジェクトを始めた時点でNext.jsがReact 18系に対応していたのでReact18で作成する前提で進めました。

TypeScript

現代のフロントエンド開発においてTypeScriptを採用しない理由が特にないのでTypeScriptを採用しました。

styled-components

ここは本当に悩みましたが、以下の理由で styled-components を採用しました。

  • CSS in JSで一番利用率が高い
  • Next.jsの公式Example が存在して公式サイトでも紹介されている
  • Figma のデザインを取り込みやすい

ただNext.js 13から登場したappディレクトリ(2022年12月19日時点ではBeta版)ではReact Server Componentsがデフォルトで利用されるようになっています。

今後React Server Componentsが Vercel Edge Runtime 上で動作するようになってくることも予想されます。

そうなるとJSランタイムが必要な styled-components は扱いにくくなってくると予想されます。

今後は CSS ModuleTailWindCSS に乗り換える、もしくは vanilla-extract などのゼロランタイムCSS in JSに乗り換えていく可能性があります。

このあたりは現時点では結論を出すことはできないので、今後の技術トレンドの動向なども確認しながら、意思決定をしていこうと思います。

Vite

npm packageなのでBuildしてpackageとして利用できる形で提供する必要があります。

このあたりは esbuildSWC などのツールが話題になっていますが、まだ情報が少なかったり、エコシステムが育っていないこともあり、最初は Rollup を使いました。

しかし次第に設定が複雑化していったので途中から Vite に乗り換えました。

設定もシンプルでBuildも高速なので良かったと思います。

GitHub Packages

OSS以外でnpm packageを公開する用途以外ではGitHub Packagesを使うのが簡単なのでGitHub Packagesを採用しました。

npmアカウントが不要でGitHubアカウントだけでpackageの公開ができるのが一番のメリットだと思います。

GitHub Packagesにpackageを公開する手順に関しては過去に記事を書いているので興味があれば見てください。

https://zenn.dev/keitakn/articles/github-packages-private-react-npm

Storybook + Chromatic

ReactComponentを提供するUI Packageにおいては Storybook はかなり有効に機能します。

各Componentの使い方は Storybook を見ればわかりますし、Chromatic というサービスを利用することで静的Buildされた Storybook をデプロイできます。

ビジュアルリグレッションテスト(VRT)も可能になるので、前回のUIとの差分を確認できるようになります。

VRT

フロントエンド側のアプリケーション

フロントエンドのアプリケーション側です。

以下がリポジトリになります。

https://github.com/nekochans/lgtm-cat-frontend

UI構築はさきほど紹介した @nekochans/lgtm-cat-ui のnpm packageに任せているので、Componentの実装はほとんど含まれていません。

バックエンドのAPIに通信する処理やSEO対策用のMetaタグの設定、多言語化対応の設定などがメインになります。

技術選定

Next.js

リリース当初から Next.js を利用していたので引き続き Next.js を利用しています。

開発体験も良いので個人開発においても有力な選択肢だと思います。

多言語化対応にも標準で対応しているので多言語化対応もあっさりと対応できました。

Vercel

Vercel に乗せると Next.js の性能をフルに発揮できます。

開発体験も良いので気に入っています。

TypeScript

現代のフロントエンド開発においてTypeScriptを採用しない理由が特にないのでTypeScriptを採用しました。

SEO対策

Googleのドキュメント を参考にSEO対策を行ないました。

言語を表すURLは以下のようにパスで表すようにしました。

IPアドレスで国を判定してコンテンツ内容を変える方法はGoogle的には非推奨のようなのでこれは行ないませんでした。

(参考)https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites?hl=ja

hreflang の設定が必要なのでページごとに設定を行なっています。

またこれだけだと、英語と日本語のトップページが重複コンテンツと見なされてしまったので、canonicalタグも追加してあります。

以下はトップページの設定例です。

<link rel="canonical" href="https://lgtmeow.com/">
<link rel="alternate" hreflang="en" href="https://lgtmeow.com/en/">
<link rel="alternate" hreflang="ja" href="https://lgtmeow.com/">
<link rel="canonical" href="https://lgtmeow.com/en/">
<link rel="alternate" hreflang="en" href="https://lgtmeow.com/en/">
<link rel="alternate" hreflang="ja" href="https://lgtmeow.com/">

一応この対応で日本語、英語のページともにGoogleにインデックスされるようになりました。

他にも基本的なSEO対策であるtitle, descriptionの設定、sitemap.xml の追加、OGP画像の設定なども行なっています。

プロジェクトのふりかえり

良かったこと

以下の通りです。

  • UI部分をnpm package化したことでUI部分とロジック部分の責務が明確になった
  • npm packageそばにStorybook + Chromaticを導入したらコミュニケーションが円滑に進んだ事
    • デザイナーさんとのコミュニケーションが円滑に進んだ
    • ビジュアルリグレッションテスト(VRT)機能がかなり使いやすかった
  • PageSpeed Insightsのスコアが3割ほど改善した
  • ドラッグ&ドロップで🐱画像をアップロードができるようになる等アクセシビリティが向上した
  • 多言語化対応により海外からの検索流入が増えた

まとめるとアプリケーションの基本性能が向上してアクセシビリティが向上、ユーザー数も増えたのでやって良かったと思っています。

良くなかったこと

以下の通りです。

  • @nekochans/lgtm-cat-ui でUI部分を分離したことで開発コストが増大した
    • 開発当時はやりやすかったが運用コストが高い
    • 動作確認時にローカルでnpm installを行なうことで一応動作確認はできるが、それだとわからない不具合もあった
    • Next.jsの next/imagenext/link に依存したComponentは @nekochans/lgtm-cat-ui での動作確認が大変だった
      • Storybookの storybook-addon-next で表示確認はできるが実際にnpm installで入れないと動きがわからないのでこれが結構苦労した

やはりnpm package化による開発コストの増大が気になります。

特定のアプリケーションでしか使わないUIをPackage化するというのは本来必要ないことです。

さきほども書きましたが、新デザインの対応中もnpm packageのセキュリティアップデートや細かい機能改善などを継続して開発していました。

その為、Package化することで最初はやりやすかったのですが、現状ではnpm packageの管理コストがかかってしまっている状態です。

Next.js 13から有効になったappディレクトリだとServer ComponentsとClient Componentsを意識して設計する必要があるので今後はこの形でないほうが良いかもしれないと思っています。

今後について

今後も改善を続けていきます。

直近だと以下の機能を改善を行なっていく予定です。

  • LGTM画像の作成機能の改善
    • 画像の明るさによって「LGTMeow」の文字を黒色と白色で使い分けるようにする
    • 猫の顔が写っている位置に「LGTMeow」の文字を被せないように対応
    • 利用できる画像拡張子の種類を増やす
  • GitHubでのログイン機能追加
    • お気に入りのLGTM画像をブックマークできる機能
    • 自分がアップロードした画像を一覧で確認できる機能

他にも細かい機能改善やアクセシビリティの改善等も随時行なっていく予定です。

おわりに

いつも LGTMeow をご利用の皆さま、本当にありがとうございます。

自分の好きな🐱関連のサービスを開発するのは楽しいですし、技術的にも学びになったのでとても良かったです。

今後も開発を継続していきますので、よろしくお願いします。

最後まで読んでいただきありがとうございました。

Discussion