Vercelの生成AIサービス「v0」で簡単なWebページデザインを始めてみる


※ 当ページには【広告/PR】を含む場合があります。
2024/01/07
蛸壺の技術ブログ|Vercelの生成AIサービス「v0」で簡単なWebページデザインを始めてみる

昨年2024年はプログラミングして実用的なソースコードを自動で出力する生成AIサービスが多く発表・リリースされた年になりました。

これからの時代は、生成AIにプログラミングの補助をしてもらうことが普通の世の中になっていくのかもしれません。

ということで、これまでの当ブログの内容とは少し違った話題として、「プログラミング補助ツール」としての生成AIサービスを紹介してみます。

最初は、フロントエンド開発が非常に楽になる、という噂の
「Vercel v0」を個人的に導入してみた手順を以降で説明していきます。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

超JavaScript 完全ガイド 2024

Vercel v0への新規登録

v0を利用するためには、Vercelのアカウントが必要になります。

以下の公式ページから自身のアカウントを登録するところから始めます。

公式|v0 by Vercel

トップページにある
「Sign Up」をクリックします。

合同会社タコスキングダム|蛸壺の技術ブログ

次に、サイン方法を選択するのですが、Eメールか、GitHub・GitLab・Bitbucketの提携アカウントを利用することになります。

Eメールでも良いのですが、おそらくv0を利用したいと考えられるユーザーのほとんどが、これらのGitサービスのうちどれかはお使いになっていると想像します。

ということで、ここではGitHubアカウント経由からVercelアカウントを作成してみます。

合同会社タコスキングダム|蛸壺の技術ブログ

アカウント提携を用いると、認証と登録もすこぶる簡単に完了します。

合同会社タコスキングダム|蛸壺の技術ブログ

GitHubからの認証後に、v0のページのv0利用規約をAcceptすると、利用準備が完了です。

合同会社タコスキングダム|蛸壺の技術ブログ

登録直後はFreeプランのアカウントからv0を即時使うことができます。

合同会社タコスキングダム|蛸壺の技術ブログ

デフォルメは英語ですが、ダッシュボードを日本語にしたい場合には、左下の設定ボタンから切り替えることもできます。

合同会社タコスキングダム|蛸壺の技術ブログ

なお、Freeプランは
200クレジット/月といった上限があります。

v0での生成コードの目安となる「クレジット」は、おおよそ「1クレジット 〜 1コードブロック生成」のようにある程度のコードの長さの基準として設けられているようです。

当然、複雑なコード、長めのコードで出力させた場合、数十クレジットが一気に消費されてしまうことにも注意が必要です。

目安として、初回のプロジェクト全体の生成で〜30クレジット、典型的なWebサイトのLP(ランディングページ)の生成で、〜10クレジット程度が消費されると言われています。

フリープランの場合、SPAのように1つのページにカレンダーのような付加的な機能マシマシにしていくたびに、結構あっという間にクレジットが無くなっていくので、プロンプトの無駄撃ちはせずに、限りなく少ない手数で、目的のコードを出力させることを心がけましょう。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

超JavaScript 完全ガイド 2024

Webページの生成

せっかくですので、ECサイトの1つのLPを想定して、ページのデザインを出力させてみましょう。

実際のところ、著者自身は
SveltekitでWebサイトを作っている人間ですので、現在のv0のサポートするNext.js/Reactでプロジェクトが出力されてもそのままだと使えない状況です。

なので、"ダメもと"とはわかっているとはいえ、最初から
素のHTML/CSSプロジェクトを要求してみます。

まず始めにページのデザインやレイアウトは単語表現だけでは伝えづらいかもしれないので、完成品のイメージや、サンプルWebページを画像として準備しておくほうが良いでしょう。

合同会社タコスキングダム|蛸壺の技術ブログ

次にもっとも重要になるのがプロンプトの文言です。

単にイメージを与えて、あとは生成AIが意図を汲んでくれるのを期待して全てお任せ、というのもよいかもしれませんが、なんとなくダラダラと細かいプロンプトを重ねて生成していくより、ズバッと一発で決めるつもりで、具体的なデザインの仕様書を書き出すスタイルで認めておきましょう。

            
            この画像を参考に、以下の要件を満たす、シンプルな小規模事業者向けのECサイトの商品一覧のためのランディングページのデザインを作成してください:

ページを構成するレイアウト:
ヘッダーと、そのヘッダーのメニューに、HOME/SHOP/Contact Us/Loginページのナビゲーション
バーナー画像を表示するエリア
商品検索のテキストインプット
2行x3列の商品カードをグリッド表示するエリア
商品カードには、商品画像・タイトル・説明文・商品紹介ページへのリンクボタンを含む

デザインの指針:
ECサイトの客層としては、個人で電子工作や日曜プログラミングを趣味とする30代〜50代のエンジニアなどをバックボーンにもつ人物をターゲットにする
ページ全体はシンプルに、落ち着きのあるマリンブルー系の静けさを感じるものに統一
ボタン部分にはホバー時にボーターを強調すうrアニメーションをつける

出力コードの構成:
シンプルなHTMLフォーマットで出力
スタイル部分はSass(scss)ファイル、もしくはcssファイルでもよい
スクリプト部のロジックは不要、もしくはプレインなJavascript
        
これで一旦、試してみましょう。

先んじて参考させたいリソースを添付ボタンから読み込んでアップロードします。

合同会社タコスキングダム|蛸壺の技術ブログ

プロンプト文をチャットインプットに貼り付けて、送信ボタンをクリックします。

合同会社タコスキングダム|蛸壺の技術ブログ

30秒程度で、イメージ通りのLPがデザインされました!

合同会社タコスキングダム|蛸壺の技術ブログ

デザインに納得がいかない場合には、再び修正のイメージを伝えて、再度生成を要求する流れになります。

合同会社タコスキングダム|蛸壺の技術ブログ

とはいえ、plain HTMLプロジェクトを要求したつもりでしたが、
Next.jsプロジェクトで始まるのは仕様のようです。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

超JavaScript 完全ガイド 2024

SvelteやプレーンなHTMLのコード出力

さきほどの説明した通り、現状、v0はNext.jsが標準出力のフレームワークになっているため、使えるものはReactベースのコードのプロジェクトが出力されます。

Vercelの本音からすると、自社開発の
Next.jsをユーザー推ししたいのは当然なのかもしれませんが、追加リクエストで、Svelte/Vue/Plain HTML&CSS対応のコードにもちゃんと変換してくれます。

個人の理想をいえば、
Sveltekitプロジェクトへ全体的に変換してくれると助かるのですが、今後対応されることを期待しつつ、今回のNext.jsのページデザインのSvelteやHTML&CSSスタイルとして抽出できないか考えてみましょう。

手始めにコンポーネントレベルの
Svelteソースコードなら、以下ようなプロンプトで変換してApp.svelteなどの名前で出力してくれます。

            
            プロジェクトにSvelteのコードも追加してください
        

合同会社タコスキングダム|蛸壺の技術ブログ

これはこれで十分使えそうです。

            
            <script lang="ts">
  let products = [
    { id: 1, title: "Electronic Kit 1", description: "Perfect for DIY electronics projects. Includes all necessary components and detailed instructions." },
    { id: 2, title: "Electronic Kit 2", description: "Advanced kit for experienced hobbyists. Create complex circuits and devices." },
    { id: 3, title: "Electronic Kit 3", description: "Beginner-friendly kit with easy-to-follow projects and educational content." },
    { id: 4, title: "Electronic Kit 4", description: "Specialized kit for IoT projects. Build your own smart home devices." },
    { id: 5, title: "Electronic Kit 5", description: "Robotics-focused kit with motors, sensors, and programmable components." },
    { id: 6, title: "Electronic Kit 6", description: "Audio electronics kit for building amplifiers, speakers, and audio effects." },
  ];
</script>

<main>
  <header>
    <nav>
      <ul>
        <li><a href="#" class="active">HOME</a></li>
        <li><a href="#">SHOP</a></li>
        <li><a href="#">Contact Us</a></li>
        <li><a href="#" class="login">Login</a></li>
      </ul>
    </nav>
  </header>

  <section class="banner">
    <img src="/placeholder.svg" alt="Tech DIY Shop Banner">
  </section>

  <section class="search">
    <input type="text" placeholder="Search products...">
    <button type="submit">Search</button>
  </section>

  <section class="products">
    <div class="product-grid">
      {#each products as product (product.id)}
        <div class="product-card">
          <img src="/placeholder.svg" alt={product.title}>
          <h3>{product.title}</h3>
          <p>{product.description}</p>
          <a href="#" class="btn">View Details</a>
        </div>
      {/each}
    </div>
  </section>
</main>

<style lang="scss">
  /* Variables */
  $primary-color: #1e3a8a;
  $secondary-color: #3b82f6;
  $background-color: #f0f9ff;
  $text-color: #1e293b;
  $card-background: #ffffff;

  /* Global Styles */
  :global(body) {
    font-family: Arial, sans-serif;
    background-color: $background-color;
    color: $text-color;
    line-height: 1.6;
    margin: 0;
    padding: 0;
  }

  /* Header Styles */
  header {
    background-color: $primary-color;
    padding: 1rem 0;
    position: sticky;
    top: 0;
    z-index: 1000;
  }

  nav ul {
    display: flex;
    justify-content: center;
    list-style-type: none;
    margin: 0;
    padding: 0;
  }

  nav ul li {
    margin: 0 1rem;
  }

  nav ul li a {
    color: white;
    text-decoration: none;
    font-weight: bold;
    transition: color 0.3s ease;

    &:hover, &.active {
      color: $secondary-color;
    }
  }

  .login {
    margin-left: auto;
  }

  /* Banner Styles */
  .banner {
    width: 100%;
    height: 300px;
    overflow: hidden;

    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  /* Search Styles */
  .search {
    max-width: 600px;
    margin: 2rem auto;
    display: flex;

    input {
      flex-grow: 1;
      padding: 0.5rem;
      font-size: 1rem;
      border: 1px solid $primary-color;
      border-right: none;
      border-radius: 4px 0 0 4px;
    }

    button {
      padding: 0.5rem 1rem;
      background-color: $primary-color;
      color: white;
      border: 1px solid $primary-color;
      border-radius: 0 4px 4px 0;
      cursor: pointer;
      transition: background-color 0.3s ease;

      &:hover {
        background-color: darken($primary-color, 10%);
      }
    }
  }

  /* Product Grid Styles */
  .product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 2rem;
    padding: 2rem;
  }

  .product-card {
    background-color: $card-background;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    transition: transform 0.3s ease, box-shadow 0.3s ease;

    &:hover {
      transform: translateY(-5px);
      box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
    }

    img {
      width: 100%;
      height: 200px;
      object-fit: cover;
    }

    h3 {
      font-size: 1.2rem;
      margin: 1rem;
    }

    p {
      font-size: 0.9rem;
      margin: 0 1rem 1rem;
      color: lighten($text-color, 20%);
    }

    .btn {
      display: block;
      background-color: $secondary-color;
      color: white;
      text-align: center;
      padding: 0.5rem;
      text-decoration: none;
      margin: 1rem;
      border-radius: 4px;
      transition: background-color 0.3s ease;

      &:hover {
        background-color: darken($secondary-color, 10%);
      }
    }
  }

  /* Responsive Design */
  @media (max-width: 768px) {
    nav ul {
      flex-direction: column;
      align-items: center;
    }

    nav ul li {
      margin: 0.5rem 0;
    }

    .login {
      margin-left: 0;
    }

    .product-grid {
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    }
  }
</style>
        
もう一つ、以下のようなプロンプトでplain HTMLコードも追加してみましょう。

            
            プロジェクトにplain HTMLも追加してください
        
すると、LPの見た目そのままHTMLとCSSへ変換してくれます。

合同会社タコスキングダム|蛸壺の技術ブログ

以下、そのときの
index.htmlstyles.cssです。

            
            <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tech DIY Shop</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><a href="#" class="active">HOME</a></li>
                <li><a href="#">SHOP</a></li>
                <li><a href="#">Contact Us</a></li>
                <li><a href="#" class="login">Login</a></li>
            </ul>
        </nav>
    </header>

    <main>
        <section class="banner">
            <img src="/placeholder.svg" alt="Tech DIY Shop Banner">
        </section>

        <section class="search">
            <input type="text" placeholder="Search products...">
            <button type="submit">Search</button>
        </section>

        <section class="products">
            <div class="product-grid">
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 1">
                    <h3>Electronic Kit 1</h3>
                    <p>Perfect for DIY electronics projects. Includes all necessary components and detailed instructions.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 2">
                    <h3>Electronic Kit 2</h3>
                    <p>Advanced kit for experienced hobbyists. Create complex circuits and devices.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 3">
                    <h3>Electronic Kit 3</h3>
                    <p>Beginner-friendly kit with easy-to-follow projects and educational content.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 4">
                    <h3>Electronic Kit 4</h3>
                    <p>Specialized kit for IoT projects. Build your own smart home devices.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 5">
                    <h3>Electronic Kit 5</h3>
                    <p>Robotics-focused kit with motors, sensors, and programmable components.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
                <div class="product-card">
                    <img src="/placeholder.svg" alt="Electronic Kit 6">
                    <h3>Electronic Kit 6</h3>
                    <p>Audio electronics kit for building amplifiers, speakers, and audio effects.</p>
                    <a href="#" class="btn">View Details</a>
                </div>
            </div>
        </section>
    </main>
</body>
</html>
        

            
            /* Variables */
:root {
  --primary-color: #1e3a8a;
  --secondary-color: #3b82f6;
  --background-color: #f0f9ff;
  --text-color: #1e293b;
  --card-background: #ffffff;
}

/* Global Styles */
body {
  font-family: Arial, sans-serif;
  background-color: var(--background-color);
  color: var(--text-color);
  line-height: 1.6;
  margin: 0;
  padding: 0;
}

/* Header Styles */
header {
  background-color: var(--primary-color);
  padding: 1rem 0;
  position: sticky;
  top: 0;
  z-index: 1000;
}

nav ul {
  display: flex;
  justify-content: center;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

nav ul li {
  margin: 0 1rem;
}

nav ul li a {
  color: white;
  text-decoration: none;
  font-weight: bold;
  transition: color 0.3s ease;
}

nav ul li a:hover,
nav ul li a.active {
  color: var(--secondary-color);
}

.login {
  margin-left: auto;
}

/* Banner Styles */
.banner {
  width: 100%;
  height: 300px;
  overflow: hidden;
}

.banner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Search Styles */
.search {
  max-width: 600px;
  margin: 2rem auto;
  display: flex;
}

.search input {
  flex-grow: 1;
  padding: 0.5rem;
  font-size: 1rem;
  border: 1px solid var(--primary-color);
  border-right: none;
  border-radius: 4px 0 0 4px;
}

.search button {
  padding: 0.5rem 1rem;
  background-color: var(--primary-color);
  color: white;
  border: 1px solid var(--primary-color);
  border-radius: 0 4px 4px 0;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.search button:hover {
  background-color: #152c69;
}

/* Product Grid Styles */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

.product-card {
  background-color: var(--card-background);
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.product-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
}

.product-card img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.product-card h3 {
  font-size: 1.2rem;
  margin: 1rem;
}

.product-card p {
  font-size: 0.9rem;
  margin: 0 1rem 1rem;
  color: #4b5563;
}

.product-card .btn {
  display: block;
  background-color: var(--secondary-color);
  color: white;
  text-align: center;
  padding: 0.5rem;
  text-decoration: none;
  margin: 1rem;
  border-radius: 4px;
  transition: background-color 0.3s ease;
}

.product-card .btn:hover {
  background-color: #2563eb;
}

/* Responsive Design */
@media (max-width: 768px) {
  nav ul {
    flex-direction: column;
    align-items: center;
  }

  nav ul li {
    margin: 0.5rem 0;
  }

  .login {
    margin-left: 0;
  }

  .product-grid {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
}
        
これだと、そのまま使えそうですね。


合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き

超JavaScript 完全ガイド 2024

まとめ

今回はVercel v0の始め方を、登録から簡単なLPの出力までを流しで確認していきました。

これまでWebページのデザインを一つ一つ自作しながらやってきた自分にとって、ものの30秒でほとんどの工程が終わってしまうなんてただただ技術の進歩に驚かされしまうばかりです。

記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。

合同会社タコスキングダム|蛸壺の技術ブログJavascript(js)&Typescript(ts)プログラミング入門〜これから学ぶ人のためのおすすめ書籍&教材の手引き