※この記事は 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でそれぞれの商品ページを生成するので、getStaticPaths
とgetStaticProps
を使ってそデータを取得していきます。
["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>
);
}
リンクを押して商品詳細画面に行くと以下のような画面が表示がされていると思います。
購入ボタンの設置
あとは購入への導線を用意してあげれば完了です。
今回は最小限のコードで試したいので、カートページは用意せずに、商品詳細画面に直接購入ボタンをおいてみたいと思います。
["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
をカートのように使うことができますが、処理を簡単にするためにこのような単純な実装としています。
checkout
はwebUrl
というプロパティを持っています。
これはShopifyのサイトに移動して決算ができるページのURLとなっているので、今回はこれを利用します。
あと、注意点としてaddLineItems
に指定する商品のIDはproduct.id
ではなく、product.variants[x].id
となります。
Shopifyの商品データは、サイズや色などを別のバリエーションとして持つことができ、そのIDとなります。
今回は特にバリエーションは気にせず、最初のバリエーション(product.variants[0].id
)を選択しています。
これで[購入する]ボタンが追加されたかと思います。
このボタンを押すと、Shopifyのサイトに移動して
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