18
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Next.jsとShopifyで最速でECサイトをつくる②

Last updated at Posted at 2020-12-30

※この記事は Next.jsとShopifyで最速でECサイトをつくる① の続きです。
まだ読んでいない人は先に前半の記事を読むことをおすすめします。

前半: Next.jsとShopifyで最速でECサイトをつくる①
後半: Next.jsとShopifyで最速でECサイトをつくる② ←いまここ

商品詳細画面の作成

つぎに簡単な商品の詳細画面を作成します。

["pages/[id].tsx"]

type DetailProps = {
  product?: Product
  errors?: string
};

const DetailPage = (props: DetailProps) => {
  const {product, errors} = props;

  if (errors) { return <p>Error: {props.errors}</p> }
  if (!product) { return <p>Error: Product not found</p> }

  return (
    <Layout title={product.title}>
      <div>
        <p>{product.title}</p>
        <img src={product.images[0].src} height={200}/>
      </div>
    </Layout>
  )
}

export default DetailPage

今回はSSGでそれぞれの商品ページを生成するので、getStaticPathsgetStaticPropsを使ってそデータを取得していきます。

["pages/[id].tsx"]

export const getStaticPaths: GetStaticPaths = async () => {
  const products: Product[] = await client.product.fetchAll();
  const paths = products.map((product) => ({
    params: { id: product.id.toString() },
  }))
  return { paths, fallback: false }
}

export const getStaticProps: GetStaticProps<DetailProps> = async ({ params }) => {
  try {
    const id = params?.id;
    if(!id) {
      return { props: { errors: "not found" } };
    }
    const productRes = await client.product.fetch(id as string);
    const product = JSON.parse(JSON.stringify(productRes));
    return { props: { product: product } }
  } catch (err) {
    return { props: { errors: "unexpected error" } };
  }
}

最後に、トップページからリンクを作成すれば完成です。

["pages/index.tsx"]

const IndexPage: React.FC<IndexProps> = ({ products }) => {
  console.log(products);
  return (
    <Layout title="Top">
      <h1>Hello Next.js 👋</h1>
      <ul>
        {
          products.map((product) => 
          <li key={product.id}>
+            <Link href="/[id]" as={`/${product.id}`}>
+              <a>
                {product.title}
                <img src={product.images[0].src} height={80}/>
+              </a>
+            </Link>
          </li>)
        }
      </ul>
    </Layout>
  );
}

リンクを押して商品詳細画面に行くと以下のような画面が表示がされていると思います。

スクリーンショット 2020-12-30 19.03.57.png
http://localhost:3000/[商品ID]

購入ボタンの設置

あとは購入への導線を用意してあげれば完了です。

今回は最小限のコードで試したいので、カートページは用意せずに、商品詳細画面に直接購入ボタンをおいてみたいと思います。

["pages/[id].tsx"]

const DetailPage = (props: DetailProps) => {
  const {product, errors} = props;
+  const [checkoutLink, setCheckoutLink] = useState("");

  if (errors) { return <p>Error: {props.errors}</p> }
  if (!product) { return <p>Error: Product not found</p> }
+
+  useEffect(() => {
+    client.checkout.create().then((checkout: any) => {
+      const variantsId = product.variants[0].id;
+      client.checkout.addLineItems(checkout.id, [{ variantId: variantsId, quantity: 1}])
+      .then((checkout) => {
+        console.log(checkout.lineItems); 
+        setCheckoutLink(checkout.webUrl);
+      });
+    });
+  }, []);

  return (
    <Layout title={product.title}>
      <div>
        <p>{product.title}</p>
        <img src={product.images[0].src} height={200}/>
      </div>
+      <Link href={checkoutLink}>
+        <button>購入する</button>
+      </Link>
    </Layout>
  )
}

処理としてはuseEffectの中で、購入処理の単位となるcheckoutを作成して、現在の商品詳細画面で表示している商品を1つ追加しています。
このcheckoutをカートのように使うことができますが、処理を簡単にするためにこのような単純な実装としています。

checkoutwebUrlというプロパティを持っています。
これはShopifyのサイトに移動して決算ができるページのURLとなっているので、今回はこれを利用します。

あと、注意点としてaddLineItemsに指定する商品のIDはproduct.idではなく、product.variants[x].idとなります。
Shopifyの商品データは、サイズや色などを別のバリエーションとして持つことができ、そのIDとなります。
今回は特にバリエーションは気にせず、最初のバリエーション(product.variants[0].id)を選択しています。

スクリーンショット 2020-12-30 19.21.30.png

これで[購入する]ボタンが追加されたかと思います。
このボタンを押すと、Shopifyのサイトに移動して

スクリーンショット 2020-12-30 19.22.47.png

https://nexjs-example.myshopify.com/52339802311/checkouts/[checkoutID]

このような購入ページが表示されると思います。

まとめ

以上でNext.jsとShopifyで最速でECサイトを作るの内容としたいと思います!

はじめてShopifyというECサービスを使ってみて、苦戦することも多かったですがなんとか購入できるところまで作成できたと思います。

ShopifyはセルフホスティングだけでECサイトを構築することができますが、今回のように便利なAPIを用意してくれているので、独自でJAMStack構成やマイクロサービス構成などにも組み込みやすくなっていると思います。

今回はStorefront API (by js-by-sdk)を使用しましたが、他にもShopify Buy Bottonを使う方法や、Admin APIなどもあるためできることはまだいろいろありそうです。

引き続きShopifyについて勉強していきたいと思います。

今回のソースコードはこちらにあります。
GitHub: https://github.com/nobux42/next-shopify-example

18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?