PMのAI日記
はじめに
転職活動中のある日、『LOST』という海外ドラマを見ていました。乗客を載せた飛行機が無人島に墜落し、生存者同士が助け合いながら化け物と戦い、サバイブする、そんな話です。その時あることに気がつきました。どんなドラマにも登場する職業があるなと。
それは「医者」でした。では、なぜ「医者」はそんなに登場機会が多いのでしょうか?それは、人の命が大切なものであり、この世界において「価値」があるからだと思います。『LOST』の中でも、ジャックという医者を中心として物語が進行します。
私は当時20代半ばでしたので、今から医者を目指そうというのは現実的には想像できませんでした。ただ『LOST』には、もう1人脇役的ながらも活躍する人物がいて、その名はサイードと言う、アラブ系のエンジニアでした。無人島の中で、怪我した人を治せるのは貴重な「価値」ですが、外界と通信ができるというのもまた「価値」だったのです。Huluというストリーミングサービスでその作品を見ていたのもあり、TSUTAYAにわざわざ貸し借りの為に移動しなくても良くなり、かつ価格も下がるという、その「価値」に魅力を感じていました。
シェイクスピアの名言に「この世は舞台、人はみな役者」というのがありますが、どうせ一度きりの人生ならば、この日本列島でサイードとして生きることで活躍できるかもしれない、そう思い立って、ITエンジニアの道を歩むこととなります。
就職氷河期の真っ只中、かつ第二新卒という条件でITエンジニアに転職した為、大企業などは箸にも棒にもかからず、派遣主体の下請け会社からのスタートとなり、上京します。私はサイードを目指していたので、遅れてスタートした分1時間早く出社したり、毎週末ITの勉強をしました。でも3年経っても給与は努力の反映など無情にもなく、このままの人生で良いのか?と無力感を感じるようになっていきました。
これはおそらく派遣という日本の見えない身分制度で冷遇されているだけではないか?と疑問に思うようになったのと、当時スタートアップが流行しはじめていたので、たまたま出向先の隣にあった会社に、腕試しがてらお昼休憩時に面接に向かったところ、物流管理者の正社員として即採用となりました。
それもそのはず。人が次々と辞めていくような、とんでもない仕事量が待っていました。まさにカオス。ダンボールの開け方も知らず、商品をカッターで傷つけてほったらかしになっていたり、ロケーション管理もグチャグチャで、入荷した商品が見つからず出荷できないというのが日常茶飯事。アルバイトも新人社員の言うことは聞かないし、そもそも外国人が多いので言葉が通じない。物流の現場でITの知識を持っていることは珍しく、ロジカルに優先度をつけて問題を一つ一つ解決し、私はマネージャーへと昇格しました。給与もいつのまにか以前の倍になっていました。
ただまた3年くらいも経つと、自分が井の中の蛙ということに気付かされるようになります。ヘッドハンティングされた社員は、私の倍の給与レンジでした。スタートアップの初期からコミットしてきた人間にとってはやっていられないという思いが募り、徐々に腐っていきました。退職ラッシュが社内で始まります。私もその流れの中で、ITx物流の知見を生かして、大企業への転職を成功させ、物流ロボットの世界へとキャリアを移します。
こう言ってはなんですが、スタートアップに比べてびっくりするくらい生ぬるい環境だったように思います。それでも前より待遇が良い。世の中は、稼ぐだけなら過去のキャリアの美しさやコミュニケーションの方がずっと重要なのだと身に沁みて感じました。ただ同時に、成長していない自分に苛立ちを覚えるようになります。このままでは終われない、挑戦したい。そして、フリーランスとして独立し、現在に至ります。
様々なプロジェクトに参画しました。物流のリアルな現場経験に加え、システム開発の全工程及び全ポジションを経験したと言っても過言ではないと思います。そんな中で他業界にも当てはまるビジネスルールやフローを学習しました。ビジネスは、売上さえ上がれば勝てる単純なゲームではありません。コストを抑え、利益を出す。利益を最大化していく、その流れを作る必要があります。そして、オンラインシフトしていく現代でその流れの基軸となるのは、間違いなくホームページ(以降HP)だと考えます。
本著では「PMのAI日記」と題し、プロダクトマネージャー(PM
)である私が、オンラインで存在感(プレゼンス)のある「集客できるホームページの作り方」をログ形式で紹介していきます。実際に行ったログの形を取りますので、途中トラブルにも遭遇します。それを一つ一つ生成AIを使って解決していくことで、最新技術の使用方法が皆様に伝わればという思いで書きました。また、ビジネスで活かせるホームページでなければ意味がないとも思い、IT技術の説明だけではなく、マーケティング要素をふんだんに散りばめました。
ただし、マーケティングは私のメインドメインではない為、下記youtubeを参照してエッセンスを取り込み、「ビジネスで使えるオンラインプレゼンスの高い」ホームページ(以降HP)を制作したいと思います。
あなたのHPの「オンラインプレゼンス」を向上させることに貢献できるのであれば、この上ない喜びです。
0.システムの本質は龍が如く
いきなり開発に入っていく前に、システムの本質について話をさせてください。システムはよく難しいと言われますが、それはある意味本当で、ある意味嘘です。何がその難しさを感じさせるのでしょうか?それはおそらく横文字の専門用語かもしれません。でも、私がよく感じるのは、全てが「擬似的」であるということこそが、そう思わせてしまっている一番強い要因のように思います。一時期「仮想化」という言葉が流行りましたが、まさにコンピュータの世界は仮想化のオンパレードです。
例えば、ゴミ箱。きっとあなたのデスクトップに存在することでしょう。では、あなたのそのコンピュータ内に物理的に存在するのでしょうか?それは、当然Noです。穿った言葉の取り方をすれば、ストレージには物理的に存在するということになりますが、ゴミ箱そのものが存在するわけでは決してありません。これと同じことが、クラウドにも言えます。クラウドサーバーは本当に雲の上に存在するのでしょうか?この答えも、当然Noです。どこかの倉庫の中にサーバーが存在し、その中でコンピュータを細かく分けて割り当て管理しているにすぎません。したがって、クラウドも嘘であり、ゴミ箱も嘘です。ただ、便宜上そう伝えると人に伝わりやすいので、あくまでそう呼称しているにすぎないのです。
物事の本質というのはどんなにファンシーに見えたり聞こえたりしても、実態は泥臭いというのが真理のように思います。ITを学ぶ上でこの点を抑えることが最初のステップです。どんなに難しい物言いをしても、あくまでそれは疑似的であり、実態を理解すると高尚そうに言うのがあくまで上手いだけであって、とてつもなく簡素な話をしていることに気付くようになります。
そして、もう3つ重要な概念があります。その一つは「プログラムは一方向に電気のように走る」ということです。だから、chatGPTは即時返答ができるし、ITによって業務スピードが劇的に向上するのも電気が流れるスピードで情報処理をするからです。その一方で、「目に見えない鉄砲を作るようなもの」ということも忘れないでいていただきいのです。システムで「あぁしたい、こうしたい」と自由に要求を並べてみてもそれを実装する時間は、その言葉の比べ物にならないくらい、何百倍の時間がかかる。それはなぜでしょうか?それは例えば鉄砲を作ってと言って、2〜3日ですぐ作れるのか?というのと、ほぼ同義と捉えていただきたいのです。ただ、一度作ってしまえば、それはとてつもない強力な武器となり、このビジネスという戦場で生き残る上で、あなたの助けとなります。
そして、最後に最も核となる概念である「関数」を理解することで、あなたもコンピュータとお友達になれると言っても過言ではありません。最も有名かつ便利な関数は「VLOOKUP」関数でしょうか?私がエンジニアに成りたての時、これは魔法だと感動しました。尚、関数の「関」は、「箱」を意味していて、この「箱」に変数を与えることによって、結果が変わります。眠たくなってしまったでしょうか?でも、先に伝えた通り、物事の本質は単純です。安心してください。箱にどんな値を入れるのか、「変わる」ので、変数というだけの話です。
「VLOOKUP」は完成された一つの「鉄砲」です。インプットする値が4つという特殊な「関数」ですが、実際にあなたのエクセルやスプレッドシートで入力して確かめてみると理解が進みますが、ここでは下記のようにデータが存在した時の「VLOOKUP」の使用例を一つ示しておきます。
「VLOOKUP」内にカンマで区切っているのが、4つに分かれているのに気づくでしょうか?「A2・A:B・2・0」で分かれています。
本例では、A2の値(りんご)をA列とB列から探して、見つかったらその2番目の値を持ってきてと依頼している関数となります(最後の0はおまじないと思っていただいて構いません)。答えはそう、「赤」です。これが何になるの?と不思議に思う方もいるかもしれません。ですが、これは英語で言うと「This is a pen.」を伝えているようなものだと思っていただきたいのです。それをまず知ることによって、コンピュータの基本の「キ」が伝わり、応用が効く知識となります。
まとめると、システムは「擬似的」で「関数」という「鉄砲」の形で「電気」を放ち、新しい解を返す。これは押し並べて、自然言語で解を返すchatGPTも「関数」の一種であることが伝わるでしょうか?
それはまるで我々に刻まれたDNAの形のように、龍が如く螺旋を描き、人類を高次へと導きます。
1.海外テンプレート活用方法
時短開発する為、今回はenvatoelementsという海外のテンプレート屋さんのソースを利用します(先の表現で言うと、「鉄砲」を仕入れて、改造します)。理由は、英語圏の方が開発人口が多く、選択できるテンプレートが豊富であるからです。そして、日本企業が手を出さない可能性が高くなる為、他社と被るリスクが下がり、「オンラインプレゼンス」を保持できるからです。
今回はサンプルとして、「react」と「nextjs」という技術を使用して行いますが、もしご自身の得意な技術があれば、適宜envatoelementsの検索窓に別キーワードを入れて、ご活用されることをオススメいたします。また、私の利用しているOSがmacとなる為、以降の写真もmacのキャプチャとなりますこと、あらかじめご容赦いただけますと幸いです。
nodeバージョンはv16.18.0を使用しています。yarnコマンド実行後は、yarn devコマンドでローカルの立ち上げができるようになります。
このテンプレートは上の写真のように、それぞれのデザインでURLが異なり、そのままでは活用できませんので、不要部分をコメントアウトしていきます。
以下、デフォルトでこのページが開くように調整していきます。
"homepage/home2-light/"のソースがどこにあるか不明なので、grepコマンドを使って探索します(grepコマンドの使用方法が不明な方は検索して調べてみてください。windowsだとfindコマンドになります)。
事前準備をすれば、このような手法を説明する必要はないのですが、「現場で使えるリアルな情報」が価値を持つと思いますので、壁にぶつかり、都度どう乗り越えるのかを具体的に記載していきます。
grep -lr "Digital Consulting"
./src./src/components/Headers/Header3.jsx
./src/components/Headers/Header2.jsx
"Digital Consulting"で検索すると、2つのファイルに絞られました。どちらが使用されているのか不明なので、中のファイルを"①"と入力し、識別します。
これによって、トップページが完成しました。ただし、メッセージが英語なのと、背景色が黒となってしまったので、写真も含めて調整していきます。
"About Us"となっていたところは、「お問い合わせ」に変更しました。これは先のyoutubeのマーケティング講師りゅう先生が、「メディアからの問い合わせ先を載せること」が最重要だと仰っていたので、まず最も重要なアクションにつながりやすいようにする考えに基づいています。
もちろんテンプレートを利活用していますので、モバイル対応もデフォルトで行われます。
ただ、このままだと「お問い合わせ」ボタンはリンクにすぎませんので、実際にその機能を追加していきます。
同様に英語を日本語化し、twitterなど古いサイトだと思われないように一次的にコメントアウトします(必要であればXに変更してください)。りゅう先生曰く、ホームページは更新されているのがマーケティングにおいても重要要素となるそうです。逆に更新されていないと信用を獲得できないと考えると、月1のアップデートはマスト要件とのことでした。
それから、cssを強制変更した為、入力文字の色が白となってしまった為、入力しても表示されないので、これを黒へと変更します。
"option + command + i"を同時に押下することによって、Chromeブラウザでは、使用されているcssの確認を取ることができます。
#fffとlight.cssになってしまっていますので、これを#000に変更します。
続いて、先ほどのお問い合わせボタンを押下した時に、この画面にスクロールするように変更します。
Linkタグからaタグに変更し、href内も#contact-formとすることによって、id=contact-formの地点に、ボタン押下でトップページ内で画面遷移するようにします。
ここでりゅう先生のポイントは、世の中のほとんどの会社が自分の会社が「取材される」って思ってなかったりするそうです。なので、お問い合わせフォームには必ず「取材」を追加する必要があり、そうしないと、取材を受け付けしているかどうかもわからなくなってしまうので、常にウェルカムな状態を作っていないと勿体無いとのことでした(コピーしても使用できるようにContactForm.jsxを下記のように変更しました)。
import React, { useState } from "react";
//= Components
import Split from "@/components/Common/Split";
//= Static Data
import contentFormData from "@/data/contact-form.json";
function ContactForm({ theme }) {
const [inquiryType, setInquiryType] = useState("general");
return (
<section className="contact section-padding">
<div className="container">
<div className="row">
<div className="col-lg-6">
<div className="form md-mb50">
<h4 className="fw-700 color-font mb-50">お問い合わせフォーム</h4>
<form id="contact-form">
<div className="messages"></div>
<div className="controls">
<div className="form-group">
<div className="radio-buttons">
<label>
<input
type="radio"
value="general"
checked={inquiryType === "general"}
onChange={() => setInquiryType("general")}
/>
一般的なお問い合わせ
</label>
<label>
<input
type="radio"
value="interview"
checked={inquiryType === "interview"}
onChange={() => setInquiryType("interview")}
/>
取材
</label>
<label>
<input
type="radio"
value="other"
checked={inquiryType === "other"}
onChange={() => setInquiryType("other")}
/>
その他
</label>
</div>
</div>
2.お問い合わせフォーム実装方法
次にこのお問い合わせフォームも機能しなければ意味がありませんので、newtというサービスを使って、お問い合わせがあった時にメール通知する機能を実装します。これによって、自動返信もできますし、開発工数も大幅削減することができますの。尚、設定方法詳細は、以下を参照してください。
マーケティング視点では、ホームページを作成する目的は1〜2に絞った方が良いので、「メディアの実績掲載と取引先を増やすこと」と定めます。なので、採用要素やLP的な要素は排除し、文言をリニューアルします。
3.メディア実績欄の実装方法
「メディアの実績掲載」が必要となってきますので、下記のポートフォリオを組み込んで、改造することにします。
以前やったのと同様に上のページの"Past Projects"を持つソースをgrepします。Portfolioを発見しました。
grep -lr "Past Projects" ./src
./src/components/Works/WorksStyle2.jsx
./src/components/Works/Works5.jsx
./src/components/Works/Works2.jsx
./src/components/Works/Works3.jsx
./src/components/Portfolio/index.jsx
code ./src/components/Portfolio/index.jsx
画像が大きくなってしまいました。システム開発していると、こういうトラブルが連続的に発生します。こういったリアルなところも含めて本書ではご紹介し、皆様のトラブルシューティングにも応用いただけますと幸いです。
grep -lr "Portfolio" ./src
./src/app/(light)/homepage/home2-light/page.js
./src/app/(light)/homepage/home4-light/page.js
./src/app/(mobile-app-dark)/mobile-app/portfolio-dark/page.js
./src/app/(mobile-app-light)/mobile-app/portfolio-light/page.js
./src/app/(dark)/homepage/home4-dark/page.js
./src/app/(dark)/homepage/home2-dark/page.js
./src/components/Mobile-app/Navbar.jsx
./src/components/Common/Navbar.jsx
./src/components/Common/NavbarFullMenu.jsx
./src/components/Works/WorksStyle2.jsx
./src/components/Works/Works5.jsx
./src/components/Works/Works3.jsx
./src/components/Portfolio/index.jsx
./src/components/Demos/MainContent2.jsx
./src/components/Demos/Services.jsx
code ./src/app/(light)/homepage/home2-light/page.js
上記の"./src/app/(light)/homepage/home2-light/page.js"のディレクトリから呼ばれている時には、問題が発生していませんので、その差分を調査していきます。
また例によって英語になってしまっていますので修正していくのに加え、メディア実績がまだホームページ開発中の現在は当然存在しませんので、ニュース1〜6に名称変更していきます。ちなみに、jsxタグにカーソルを合わせ、「fn +F12」を押下することによって、visual studioのテキストエディターでは、そのソースに遷移してくれる便利機能がありますので、ぜひぜひご活用ください。
デフォルトの写真がおしゃれなので、それっぽくなってきましたね。SNS全盛のこの時代でも、ホームページでメディア実績を定期的に更新し、歴史を積み重ねることが、信頼獲得につながる「最強のツール」となるそうです。また、プレスリリースはPR Timesなど出稿で3~5万円で行うことができるそうで、三冠バッジは30~50万円で購入できるそうです。また、150万~200万円の予算があれば、テレビや雑誌にPRして実績を買うこともできると説明されていました。
ここまで、トップページ用に「キャッチコピー・お問い合わせフォーム・メディア実績」のページを開発してきました。あとは、「基本情報・事業概要・IR・採用情報・Q&A」などのページを作成するのが効果的だそうですが、目的は必ず絞るべきということを同時にりゅう先生は、ご主張されていました。先程申し上げた通り、今回は「メディアの実績掲載と取引先を増やすこと」と定めましたので、次に「基本情報・事業概要」のページを追加することにします。
不要部分を削除し、アップデートします。
4.ロゴの実装方法
vieというロゴが、このビジネスを想起させないので、変更します。Canvaを使います。
上のメニューの"Resize & Magic Switch"を押下することによって、500 x 284にリサイズできます。また、右上の"Share"ボタンを押すことでダウンロードができ、その時に背景透過を選択することができます。
ロゴつながりでナビゲーションバーがまだ存在しないので、追加します。
ロゴは変更されたものの、メニューを開いてクリックすると、画面遷移するようになってしまっていますので、現時点ではコメントアウトしておき、後でページが全て揃った時に調整します。ちなみにコメントアウトは範囲にカーソルを当てた状態で、「command + /」を押下することによっても可能です。
5.縦型動画の実装方法
基本情報は「住所・メールアドレス・電話番号」などのみと思っていましたが、ちょっと違いました。りゅう先生の動画をもう一度見直したところ、動画による代表挨拶や企業理念のこともでした。動画は最近流行りの縦型にした方が良いようです。<Video />タグを追加していきます。
3k+のハッピークライアントと14k+の成功プロジェクトというラベルがありますが、「代表挨拶や企業理念」では数字部分は不要ですので、コメントアウトします。
私自身が現在個人事業主であって、DAO的な形式で働くような形であったので、あえてDAO理念としました。DAOとは何かというと、非中央集権的組織のことで、トップ不在で、個々人が自立して一つのプロジェクトに取り組む組織のことです。私が代表であり、実質上はチームのトップなのですが、会社組織よりは序列がないので、時流に乗ってDAO理念を創造します。
再生ボタンを押すと、どうやら縦型動画ではないので、これが変更できないかトライしてみますが、やり方が不明なので、ChatGPTとBardに聞いてみました。Bardの方が良い回答をしてくれたので、以下に引用します。
一番簡単そうな「2. iframe のアスペクト比を調整する」をトライしてみましたが、何も変化がありませんでした。
以前説明したように、"option + command + i"を同時に押下することによって、Chromeブラウザでは、使用されているcssの確認を取ることができます。この開発モードはそれに加えて、画面のサイズを調整することができます。これによって、縦型動画対応できているか識別できるようになります。
続いて、「3. 外側のコンテナを調整する」にチャレンジしてみましょう。
grep -lr "modal-video-movie-wrap" ./src
./src/styles/modal-video.css
./src/components/Common/ModalVideo.jsx
code ./src/styles/modal-video.css
cssをヒューマンリードせずに、bardに修正してもらうように依頼しましょう。
.modal-video-body {
max-width: 1100px;
width: 100%;
height: 100%;
margin: 0 auto;
display: table;
}
.modal-video-inner {
position: relative;
display: table-cell;
vertical-align: middle;
width: 100%;
height: 100%;
}
.modal-video-movie-wrap {
width: 100%;
height: 100%; /* 縦方向の伸びに追従させる場合 */
position: relative;
background-color: var(--modal-bg-color);
animation-timing-function: var(--animation-function);
animation-duration: var(--animation-speed);
animation-name: modal-video-inner;
transform: translate(0, 0);
transition: transform var(--animation-speed) var(--animation-function);
}
.modal-video-movie-wrap iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
大体それっぽい回答を返してきて、うまくいかないケースがほとんどですので、何の期待もせずに言う通り修正していきます。
やはり何も変更されないので、「4. ライブラリを利用する」に移行します。yarn add react-playerをターミナルで打ちます。
成功しました。追加したライブラリを使用して、使用するようにbardにコード修正を依頼し、結果を反映します。
流石に2~4をやればと思いましたが、難しいようです。最後の「1. 縦型動画の埋め込み URL を用意する」に希望を託します。
下記のサイトを参考にして、埋め込みを行いました。
現在私はマーケティング学習に力を入れており、マーケティングの著名人ばかりご紹介しているのは、ご容赦いただければと思います(笑)。結果、Bardは嘘はついてはいなくて、「1. 縦型動画の埋め込み URL を用意する」と「3. 外側のコンテナを調整する」ことによって実現できましたので、「4. ライブラリを利用する」を元に戻しておきます(2は不要です)。
yarn remove react-player
yarn remove v1.22.17
warning ../../../package.json: No license field
[1/2] 🗑 Removing module react-player...
[2/2] 🔨 Regenerating lockfile and installing missing dependencies...
warning "eslint-config-next > @typescript-eslint/parser > @typescript-eslint/typescript-estree > ts-api-utils@1.0.3" has unmet peer dependency "typescript@>=4.2.0".
success Uninstalled packages.
✨ Done in 1.10s.
6.高齢化社会とCSS調整方法
「基本情報」を出す枠組は揃いましたので、あとは「事業概要」のページを追加します。事業概要サンプルページは元々それっぽいのがありますので、それを加えて日本語に変更していきます。
最後のアイコンがグラフィックになっていて、どうも事業概要のパズルに当てはまらないので、変更することにします。
pe-7s-paint-bucketで検索してところ、以下のサイトが表示されました。
これで「事業概要」もOKかと思いきや、高齢化社会の昨今、文字が薄いことは、実はあまり好まれません。センスという自己満足は一旦置いておいて、マーケティング視点で顧客に伝わりやすいデザインにしていく必要があります。
3回目ですが、そろそろ開発コンソールの開き方は、覚えましたでしょうか?大丈夫です。何度でも復習をしましょう。
そしたら次は何をするか?そう、grepですね。
grep -lr "#888" ./
.//public/css/light.css
code .//public/css/light.css
他に同様に薄いところがないかチェックしてみます。
あの値がここにも影響を受けていたので、フッターのCSSを白に調整していきます。方法をchatGPTに聞いてみましょう。
<p style="color: white;">東京都千代田区東神田1-7-10</p>
.white-text {
color: white !important;
}
今回は「インラインスタイル」を適用します。複数箇所ありますので、置換することにします。
JSXだと{{}}で囲んでくれよとのことですので、やはり「CSSクラスを使用する方法」にシフトしましょう。
これで全要素を網羅したでしょうか?ただ順番が適切ではないので、今一度マーケティング視点でどの順番が良いのか調整していきます。
トップページに実績を掲載していくことが最重要ですので、問い合わせの前にそれを持っていきます。また、何を解決したいのかなどの理念や事業概要を説明した後に、実績が来るようにすると効果的ですので、さらにそれを前に持っていくようにします。
あとは、理念のショート動画を撮影してから差し替え、実績を更新していけば、マーケティング視点を抑えたホームページの土台は完成です。そして、タブ表示時の文言修正とGoogleアナリティクス対応ができていないのと、その修正を行っていきます。ちなみに、KPIはブックマーク登録者数です。
例によって、grepします。
grep -lr "Preview" ./src
./src/app/page.js
code ./src/app/page.js
7.faviconの調整方法
favicon.icoが使用されていますが、現時点では反映されていないので、パスが読み込めていない可能性があります。一旦chatGPTに聞いてみましょう。
export const metadata = {
title: "ブルテナサス - 基幹システム開発DAO",
icons: {
icon: "/img/favicon.ico",
shortcut: "/img/favicon.ico",
other: generateStylesheetObject([
"https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900&display=swap",
"https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@100;200;300;400;500;600;700;800;900&display=swap",
"https://fonts.googleapis.com/css2?family=Manrope:wght@200;300;400;500;600;700;800&display=swap",
"/css/light.css",
]),
},
};
要するに「"/img"を入れてみて」ということですので、入れてみます。
シンプルにテンプレートがディレクトリを間違っていたようです。でも、このfaviconでは意味を成さないので、せめて「B」にしたいので、chatGPTにお願いしてみました。
なので、今度は下記のサイトを利用することにします。
簡単にfaviconが生成できました。
ロゴと本当は同一性を打ち出した方がマーケティング視点では良いのかもしれませんが、無料領域で極力走り抜け、サービスが立ち上がってきた時に、プロの力でリブランディングしても良いという方向性で今回は進行します。
8.Googleアナリティクスの実装方法
次はGoogleアナリティクスです。page.jsと他のサイトでうまくアナリティクスが動いているコードを合体させます。
import { useEffect } from 'react';
import Script from 'next/script';
//= Common Components
import LoadingScreen from '@/components/Common/Loader';
import Cursor from '@/components/Common/Cursor';
import ProgressScroll from '@/components/Common/ProgressScroll';
//= Page Components
import CircleBg from '@/components/Demos/CircleBg';
// import Header from '@/components/Demos/Header';
import MainContent2 from '@/components/Demos/MainContent2';
export const metadata = {
// ... your metadata
};
export default function LandingPreview() {
useEffect(() => {
// Initialize gtag.js
window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'YOUR_GA_TRACKING_ID'); // Replace with your Google Analytics Tracking ID
}, []);
return (
<>
<LoadingScreen />
<Cursor />
<ProgressScroll />
<CircleBg />
{/* <Header /> */}
{/* <MainContent /> */}
<MainContent2 />
<Script strategy="beforeInteractive" src="/js/wow.min.js"></Script>
<Script strategy="beforeInteractive" src="/js/splitting.min.js"></Script>
<Script strategy="beforeInteractive" src="/js/simpleParallax.min.js"></Script>
<Script strategy="beforeInteractive" src="/js/isotope.pkgd.min.js"></Script>
<Script strategy="lazyOnload" src="/js/pace.min.js"></Script>
<Script strategy="lazyOnload" src="/js/wowInit.js"></Script>
{/* Add additional external scripts here if needed */}
</>
);
}
英語になってしまいましたが、そのまま適用してみます。
このエラーメッセージ自体をchatGPTに投げてみます。
// src/components/GoogleAnalytics.js
import { useEffect } from 'react';
const GoogleAnalytics = () => {
useEffect(() => {
// Initialize gtag.js
window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'YOUR_GA_TRACKING_ID'); // Replace with your Google Analytics Tracking ID
}, []);
return null; // This component doesn't render anything
};
export default GoogleAnalytics;
// ./src/app/page.js
import GoogleAnalytics from '@/components/GoogleAnalytics'; // Adjust the path as necessary
export default function LandingPreview() {
return (
<>
<GoogleAnalytics />
{/* Rest of your components */}
</>
);
}
'use client';を使用してほしいそうなので、そのように修正していきます。YOUR_GA_TRACKING_IDはあなたのGタグに合わせて変更してください。
本件はnextjsのアーキテクチャ特有の事象であり、サーバーサイドとクライアントサイドで分けて処理されていることが起因していました。クライアントサイドで処理されることによって、エラーが発生しなくなります。ちなみに、「Gタグって何?」という方は下記から取得してみてください。
9.ブックマークをKPIにする方法
これでKPIもバッチリ取れるようになるのですが、ブックマークってどこで参照できるのか、またchatGPTに聞いてみましょう。
ブックマークはKPIにできない。。りゅう先生どういうことでしょうか?と突っ込みたいところですが、検索して調べてみると答えっぽいのを発見しました。
ということで、「タブ表示時の文言修正とGoogleアナリティクス」対応が完了しました。あと忘れていけないのは、メタデータと言語変更です。Googleに適切にクローリングして頂かないと、検索されませんので、ここは力を入れて修正していきます。
10.テストテストテスト
大体できてきたので、ユーザー目線でテストしながら文言の見直しと簡易修正を行なっていきます。
下記3点を修正していきます。
ニュースはまだないので、サンプルで1つだけにし、リンクをhref="#0"にする
モバイル画面においてラジオボタンが整っていないので整理が必要
フッターにスペースがあるので沿革情報を入れる
1は速攻で、次は2です。chatGPTとBardに聞いてみたところ、Bardが良い回答をしてくれました。ちなみに、日本語の質問を最後に持ってくることによって、回答を日本語でしてくれます。
.radio-buttons {
/* デフォルトのレイアウト */
}
@media (max-width: 768px) {
.radio-buttons {
display: flex;
flex-direction: column;
}
.radio-buttons label {
margin-bottom: 10px; /* ラジオボタンの間の余白 */
font-size: 14px; /* ラベルのフォントサイズ調整 */
word-wrap: break-word; /* ラベルの改行 */
}
.radio-buttons input[type="radio"] {
width: 20px; /* ラジオボタンのサイズ調整(例) */
}
}
続いて、フッターにスペースがあるので沿革情報を入れます。
沿革に写真やメルマガ用のEmailはいらないのでコメントアウトし、後は日本語化していきます。
ということで、「メディア実績と協業」の2つを目的としたホームページができましたので、いよいよインターネット空間に解き放ちます。
11.インターネット空間へのデプロイ方法
まずその準備として、手元でビルドを行います。
yarn build
yarn run v1.22.17
warning ../../../package.json: No license field
$ next build
Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled
Using external babel configuration from /Users/takayamasashi/Desktop/vie/vie_nextjs_13/.babelrc
⚠ It looks like there is a custom Babel configuration can be removed .
Failed to compile.
./src/components/Contact/ContactForm.jsx
ReactServerComponentsError:
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
Learn more: https://nextjs.org/docs/getting-started/react-essentials
╭─[/Users/takayamasashi/Desktop/vie/vie_nextjs_13/src/components/Contact/ContactForm.jsx:1:1]
1 │ import React, { useState } from "react"; //= Components
· ────────
2 │
3 │ import Split from "@/components/Common/Split"; //= Static Data
╰────
Maybe one of these should be marked as a client entry with "use client":
./src/components/Contact/ContactForm.jsx
./src/app/(dark)/contact/contact-dark/page.js
> Build failed because of webpack errors
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn build
yarn run v1.22.17
warning ../../../package.json: No license field
$ next build
Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled
Using external babel configuration from /Users/takayamasashi/Desktop/vie/vie_nextjs_13/.babelrc
⚠ It looks like there is a custom Babel configuration can be removed .
✓ Creating an optimized production build
✓ Compiled successfully
Linting and checking validity of types .. ⨯ ESLint: Failed to load config "next/babel" to extend from. Referenced from: /Users/takayamasashi/Desktop/vie/vie_nextjs_13/.eslintrc.json
✓ Linting and checking validity of types
✓ Collecting page data
✓ Generating static pages (56/56)
✓ Finalizing page optimization
Route (app) Size First Load JS
┌ ○ / 6.01 kB 105 kB
├ ○ /_not-found 883 B 88.3 kB
├ ○ /about/about-dark 151 B 130 kB
├ ○ /about/about-light 150 B 130 kB
├ ○ /blog-details/blog-details-dark 905 B 96.7 kB
├ ○ /blog-details/blog-details-light 905 B 96.7 kB
├ ○ /blog-grid/blog-grid-dark 905 B 96.7 kB
├ ○ /blog-grid/blog-grid-light 905 B 96.7 kB
├ ○ /blog-list/blog-list-dark 905 B 96.7 kB
├ ○ /blog-list/blog-list-light 905 B 96.7 kB
├ ○ /blog/blog-dark 905 B 96.7 kB
├ ○ /blog/blog-light 905 B 96.7 kB
├ ○ /contact/contact-dark 142 B 98 kB
├ ○ /contact/contact-light 142 B 98 kB
├ ○ /homepage/home1-dark 154 B 135 kB
├ ○ /homepage/home1-light 155 B 135 kB
├ ○ /homepage/home2-dark 2.54 kB 129 kB
├ ○ /homepage/home2-light 2.54 kB 129 kB
├ ○ /homepage/home3-dark 151 B 134 kB
├ ○ /homepage/home3-light 150 B 134 kB
├ ○ /homepage/home4-dark 2.56 kB 132 kB
├ ○ /homepage/home4-light 2.56 kB 132 kB
├ ○ /homepage/home5-dark 155 B 132 kB
├ ○ /homepage/home5-light 154 B 132 kB
├ ○ /homepage/home6-dark 151 B 134 kB
├ ○ /homepage/home6-light 151 B 134 kB
├ ○ /homepage/home7-dark 154 B 139 kB
├ ○ /homepage/home7-light 155 B 139 kB
├ ○ /homepage/home8-dark 151 B 137 kB
├ ○ /homepage/home8-light 151 B 137 kB
├ ○ /mobile-app/mobile-app-dark 142 B 129 kB
├ ○ /mobile-app/mobile-app-light 142 B 129 kB
├ ○ /mobile-app/portfolio-dark 142 B 98.2 kB
├ ○ /mobile-app/portfolio-light 142 B 98.2 kB
├ ○ /mobile-app/pricing-plan-dark 142 B 98.3 kB
├ ○ /mobile-app/pricing-plan-light 142 B 98.3 kB
├ ○ /mobile-app/services-dark 141 B 98.3 kB
├ ○ /mobile-app/services-light 142 B 98.3 kB
├ ○ /mobile-app/shop-dark 142 B 98.1 kB
├ ○ /mobile-app/shop-light 142 B 98.1 kB
├ ○ /project-details2/project-details2-dark 1.68 kB 97.5 kB
├ ○ /project-details2/project-details2-light 1.68 kB 97.5 kB
├ ○ /showcase/showcase-dark 1.37 kB 128 kB
├ ○ /showcase/showcase-light 1.37 kB 128 kB
├ ○ /showcase2/showcase2-dark 1.58 kB 128 kB
├ ○ /showcase2/showcase2-light 1.58 kB 128 kB
├ ○ /showcase3/showcase3-dark 1.67 kB 129 kB
├ ○ /showcase3/showcase3-light 1.67 kB 129 kB
├ ○ /works/works-dark 1.84 kB 97.6 kB
├ ○ /works/works-light 1.84 kB 97.6 kB
├ ○ /works2/works2-dark 142 B 98.1 kB
├ ○ /works2/works2-light 142 B 98.1 kB
├ ○ /works3/works3-dark 141 B 98.1 kB
└ ○ /works3/works3-light 142 B 98.1 kB
+ First Load JS shared by all 87.4 kB
├ chunks/2503-74392824140ec6c8.js 34.4 kB
├ chunks/fd9d1056-8ea860660145e754.js 50.9 kB
├ chunks/main-app-37bdeff11a8b0c49.js 234 B
└ chunks/webpack-f0c5cd87759e5799.js 1.85 kB
○ (Static) automatically rendered as static HTML (uses no initial props)
✨ Done in 14.52s.
成功しました。では、githubに入って、リポジトリを作成し、このソースをプッシュしていきましょう。
ちなみにビルドすると、サイズの大きい.nextフォルダがその時に作成されてしまいますので、.gitigonreファイルを作成し、.next/とnode_modules/をプッシュ条件から避けるように設定しておきます。viコマンドの使用方法が不明な方は以下を参考にしてみてください。
vi .gitignore
.next/
node_modules/
:wq
echo "# bletainasus" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:takayanomasashi2/bletainasus.git
git push -u origin main
vercelのサービスを利用して、デプロイしていきます。
下記のテストURLで既に参照できるようになりましたが、ドメインを与えていきます。
https://bletainasus-zhxt-3ldgu3xno-takayanomasashi2.vercel.app/
12.メタデータの修正方法
この時点では下記のように写真がなかったり、「ブルテナサス - 基幹システム開発DAO」と説明が繰り返してしまっているので、メタデータの修正を行っていきます。
git add . ; git commit -m "fix meta" ; git push
このコマンドでgitの更新をかけます。vercelはgitの更新を自動で検知し、再度vercel環境でbuildしてくれます。
buildした後もキャッシュクリアされないと反映されないので、今度はslackにURLを貼付して確認しました。
ちなみに、ロゴは躍動感があり、色が鮮やな方が好印象という、早稲田大学の研究で発表されているそうです。躍動感とは、牛乳をコップに注いでいる写真のような動きのことです。デフォルトでこのロゴは両方を満たしている形なので、マーケティング的にも悪くはないのかもしれません。
13.実機でもテストテストテスト
ということで、PC上でできることはほぼ完結しましたので、次はスマホでの確認をしていきます。できれば、iPhoneとandroidの両方で確認した方がベターです。
ラジオボタンが上記のようにやはり少しずれていたり、横へのスライドが動いたりするので、これを固定するように修正します。
chatGPT4.0では課金2,000円/月が必要ですが、写真添付も可能になりましたので、上記の写真を添付した上で下記のメッセージをプロンプトに投げます。
@media (max-width: 768px) {
.radio-buttons {
display: flex;
flex-direction: column;
}
.radio-buttons label {
margin-bottom: 10px; /* ラジオボタンの間の余白 */
font-size: 14px; /* ラベルのフォントサイズ調整 */
word-wrap: break-word; /* ラベルの改行 */
vertical-align: middle; /* ラベルを中央揃えにする */
}
.radio-buttons input[type="radio"] {
width: 20px; /* ラジオボタンのサイズ調整 */
height: 20px; /* ラジオボタンの高さを調整 */
vertical-align: middle; /* ラジオボタンを中央揃えにする */
margin-right: 5px; /* ラベルのテキストとの間に余白を作る */
}
}
この修正でラジオボタンのズレは修正されました。
androidでは横へのスライドは発生しないのですが、"overflow-x: hidden;"のCSSを足してもiPhoneでは発生してしまいます。調査した結果、下記に答えが載っていました。
html {
overflow-x : hidden;
-webkit-overflow-scrolling: touch;
}
body {
overflow-x : hidden;
-webkit-overflow-scrolling: touch;
}
さいごに
以上「オンラインプレゼンス」の高いホームページの作成方法となります。あとは、代表挨拶とDAO理念を紹介する動画を更新するなどして、PR TIMESなどに投資し、SNSと繋ぎながら、ブックマーク登録(ノーリファラル)をKPIとして、このサイトを成長させていけば、事業も同時に成長していくという流れです。
こんなにたくさんやるのは面倒くさい?
そんな方は、今まさに開発した下記のお問い合わせフォームにメッセージをいただけましたら、御見積及び代行業務させていただきますので、どうぞよろしくお願いいたします。
最後まで読んでいただき誠にありがとうございました。
この記事が気に入ったらサポートをしてみませんか?