制作期間の7日のうち、3日はReact化だけで消えました。
前回は、Showcasesという棚に、本文を読む場所がなかった話を書きました。その後、詳細ページを用意して、今回、棚に3つ目を並べました。Figma Communityで公開されているLPテンプレートをReactにして、Payloadに載せ、Supabaseまで通した、経費管理SaaSの架空LP「Ledgerly」です。
1枚の絵は、部品の集まりでした
LPを分けていくと、ヘッダー、ヒーロー見出し、Bentoカード、お客様の声、料金表、CTA、フッターになります。Figmaでは1枚に見えていたものが、コードでは8つほどのコンポーネントでした。
既製の部品を使うのとは、別の仕事でした
これまでのLPは、Preline UIのような既製のReactコンポーネントを組み合わせて作っていました。部品はすでにコードになっているので、選んで並べる作業です。
今回は、絵をコードにするところから始まります。大変だったのは、次の3つです。
フォント:next/font/googleでDM SansとInterを読み込みました。DM Sansはオプティカルサイズ軸ごと読み込み、Tailwindの任意値で14に固定しています。Figmaの見た目に合わせるためです。
カラー:CSS変数やTailwindのthemeには登録せず、HEXをそのまま書く方式にしました。背景色はヒーローとページ側の両方に書いてあるので、変えるなら2か所を直します。整理は宿題です。
グラフ:Figmaから書き出したSVGとPNGをimgタグで表示しています。チャートライブラリもcanvasも使わず、点の座標はSVGの中に固定です。
Figmaから実装するのは初めてで、正直、無我夢中でした。グラフを画像のまま使っているのも、深く考えた末の判断ではなく、動くところまで持っていく中でそうなりました。既製の部品を使っていたときには見えなかった、LPほどの規模のコード化の大変さを、ここで知りました。
Payloadに載せる
コードになった部品を、Payloadのブロックにしました。LandingPagesのlayoutに、Feature、Testimonial、Pricing、そしてLedgerlyの特徴セクションが選択肢として並びます。管理画面でブロックを選べば、ページが組み上がります。
特徴セクション(Bento)は、配列ではなく、card1〜card5の固定フィールド(group)で持たせています。
Supabaseの中を見てみた
入力したデータが実際にどうなっているかを、読み取り専用で確認しました。
groupフィールドは別テーブルにならず、card1_headingのように、親テーブルのカラムとして平らに展開されていました。
既定値の文言は、DB側のDEFAULTにも入っていました。
コード上は必須の見出しも、DBではNULLを許可しています。下書き(autosave)を有効にしているため、必須チェックはDBではなくアプリ側で行われます。
公開版のテーブルは1行、下書き・バージョン用のテーブルは10行でした。バージョンの保持上限は50件です。
マイグレーションファイルは持たず、pnpm devの起動時にPayloadがテーブルを作っています。
ローカル、Preview、本番は、同じSupabaseを見ています。ローカルでブロックを追加してpnpm devを起動すると、本番のDBにもテーブルができる構成です。
コンポーネントの設計が、そのままテーブルの列になっていました。
データにしたもの、絵のまま残したもの
Supabaseの表に入っているのは、Bentoの5枚のカードの見出しと説明文、5枚目のボタンです。ヒーローのダッシュボード画像も、mediaコレクションを参照していて、管理画面から差し替えられます。
カードの中のグラフ、金額、人名は、管理画面から編集できず、DBにも入っていません。コード側でも「飾り」として扱い、すべてaria-hiddenにしてあります。
Figmaのテンプレートを丸ごとデータにしたわけではありません。文章と画像の参照はデータに、見た目を成り立たせる飾りは絵のまま。この線引きが、今回の型の中身になりました。
途中だったこと
今回は、途中だったことが2つありました。
1つ目は、本番の特徴セクションです。 ローカルでは「崩れなし」と判断していたのに、本番では特徴セクションが抜けて、白い背景が出ていました。特徴セクションのコードと背景の指定が、ローカルに未コミットのまま残っていたためです。ローカルの画面は、未コミットの変更を含みます。ブランチを切ってコミットし、PRを作り、Vercel Previewで確認してからマージして、本番でも確認しました。
2つ目は、帰属表示です。 使ったテンプレートは、Figma Communityの、sahin Alom氏の「SaaS Landing Page - Bento UI」で、ライセンスはCC BY 4.0です。作者名、ライセンス名とそのリンク、元素材へのリンク、改変した旨を示すことが条件になります。
フッターには、作者名の1行だけを入れてありました。確認すると、その行はコードへの直書きで、リンクも、ライセンス名も、改変した旨もありませんでした。入れたつもりの表記が、条件の一部だったのです。次のように直しました。
Design based on "SaaS Landing Page - Bento UI" by sahin Alom (Figma Community), licensed under CC BY 4.0. Modified.
フッターの文字はほぼ白なので、既存のリンクと同じ書き方だと、リンクだと気づけません。そのため、下線を足しました。Previewと本番の両方で、表示と、2つのリンクが新しいタブで開くことまで確認しています。
苦労した分、得たもの
Figmaの1枚が、文言を入れ替えられるLPの型になり、その文言と画像の参照は、Supabaseの表として保管できました。コンテンツをデータとして持つことの意味を、手を動かして実感しました。苦労は多かったのですが、次のLPでは、この型を使えます。
次にやること
READMEにも、同じ帰属表示を足します。そして、この型を使った次のLPです。
Payloadバックエンド型録#1(フロントにコンポーネントがあるなら、バックエンドにあってもいい)
Payloadバックエンド型録#2(コーポレートサイトの型は、有限である)
Payloadバックエンド型録#3(棚は作った。読む場所が、まだない。)
拡張ログ#1(SMTPを使わずn8n×Slack)
拡張ログ#2(テンプレートをやめてReactコンポーネント)
拡張ログ#3(SaaSを1つ増やすたびに、時間を溶かすリスクも増える)
この記事のLPは、sahin Alom氏の「SaaS Landing Page - Bento UI」(Figma Community、CC BY 4.0)をもとに、改変して作っています。
元のテンプレート:https://www.figma.com/community/file/1360683197038417365/saas-landing-page-bento-ui
実際に構築したコーポレートサイトは、以下で公開しています。
https://www.kuros-works.com/
実際に構築したコーポレートサイトのソースコードは、GitHubで公開しています。
https://github.com/kuros-works/kuros-corporate-site