用 Next.js 搭建了一个 Shopify 商店 😁
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
我用 Next.js 搭建了一个 Shopify 店铺。
我工作上一直都在用 Shopify,我对 Next.js 很感兴趣,因为它支持多种渲染方式,比如 SSR、SSG 和 ISR,所以我决定把两者结合起来搭建一个店铺。
店铺设计基于 Shopify 的默认主题 Debut(现在叫 Dawn)。
使用的技术等。
应用商店:https
://nextjs-shopify-store.vercel.app 代码仓库:https://github.com/naoya-kuma1990/nextjs-shopify-store
使用技术:React、Next.js、TypeScript、Tailwind CSS、Material UI、Shopify JavaScript Buy SDK、Store Front API (Graph QL)
已实现页面:产品列表、产品详情、购物车、搜索结果
Next.js 和 Store Front API 的速率限制
正如我在文章开头提到的,Next.js 是一个支持 SSR 和 ISR 的 React 框架。我这次选择它是因为我认为“对于电商网站来说,支持 SEO 是理所当然的,而如果想用 React 实现 SEO,Next.js 就是最佳选择”。然而,事实证明,我这次做的网站 SEO 失败了,因为所有重要的信息获取操作,例如产品信息获取,都是在客户端进行的(笑)。
这是因为 Shopify 的 API 访问存在名为“ API 速率限制”的成本限制,并且访问限制取决于 API 的类型。您可以在官方网站上了解更多信息,但简单来说,每个店铺(严格来说,是作为访问点的私有应用程序)都有一定数量的点数,如果点数用完,请求就会出错,直到点数恢复为止。
因此,当大量用户访问网站时,两个管理 API(REST 和 GraphQL)的运行成本会迅速飙升,所以才有了 Store Front API。与管理 API 不同,店铺前端 API 受 IP 地址限制。因此,只要客户端请求的信息量达到一定水平,店铺前端 API 就不会产生任何成本超支。
正因如此,使用 Shopify API 构建店铺前端时,服务器端渲染 (SSR) 并非首选方案,因为 SSR 意味着每次用户访问都会调用 API,无论使用哪种 API,都会迅速导致成本超支。
可行的方案是使用中断服务渲染 (ISR) 定期调用 API 并将其渲染为静态页面,或者使用客户端服务渲染 (CSR) 每次都调用店铺前端 API。这次我选择了 CSR。
在页面组件的 useEffect 中获取信息
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/pages/collections/%5Bhandle%5D.tsx#L30-L60
使用自定义客户端查询店铺前端 API
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/graphql/collection/getCollectionWithProducts.ts#L69-L136
JavaScript SDK 和自定义客户端
JavaScript Buy SDK是一个用于调用 Store Front API 的 SDK。基本上,你可以用这个 SDK 获取产品信息和进行购物车操作,所以我原本打算完全使用它,但遇到了一些问题。这个 SDK 只用于购物车操作,例如添加和删除产品,而 GraphQL 客户端库(graphql-request)则用于在产品页面上获取产品信息和进行搜索,直接调用 Store Front API。这是因为,首先,JS Buy SDK 似乎使用了较旧的 TypeScript 类型定义,类型信息与实际可以获取的属性不匹配,需要自行部分扩展类型定义。这是我第一次扩展类型定义,所以学到了很多东西,但确定哪些属性有类型、哪些没有类型确实很麻烦。此外,SDK 支持的基本属性只是官方文档中描述的 Store Front API 可检索信息的一部分,当我尝试扩展 SDK 时,发现非常繁琐(例如,商品系列页面不支持商品排序)。(SDK 的排序功能是这样实现的。)
因此,我决定仅将 SDK 用于购物车操作,并扩展库的类型定义,其余操作则使用自定义客户端直接访问 Store Front API。
JS 购买 SDK
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/client.ts
自定义客户端
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/graphql/customClient.ts
扩展 SDK 类型定义
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/types/shopify-buy.d.ts
定制挂钩
我为推车操作定制了一个挂钩。
自定义钩子(useCart)
https://github.com/momonoki1990/nextjs-shopify-store/blob/a91df30dd6fe4f6e6f057294dbbbb71876602ec9/lib/useCart.ts#L17-L130
Tailwind CSS 和 Material UI
为了重现 Shopify 的默认主题 Debut(现在默认主题是 Dawn),我使用了 Tailwind CSS 和 Material UI 组件来实现抽屉和骨架(初始绘制时显示的占位符)等动画效果。我之前用 Liquid 编写主题时就用过 Tailwind CSS,它完美解决了 CSS 全局样式的问题,给我留下了深刻的印象。不过,我仍然觉得用 Tailwind 将样式集成到 HTML 中非常实用,可以减少代码量。
我们也同时使用了 Tailwind 和 Material UI,但由于 Tailwind 使用的是类名,而 Material UI 是组件,所以没有出现冲突。我不建议同时使用不同的 CSS 框架,因此我个人不建议在实际项目中这样做。
氢和氧。
Hydrogen 包含购物车、款式选择器和媒体库等电商专用组件,旨在简化定制店铺的搭建流程。
与此同时,Shopify 还发布了 Oxygen。Oxygen 提供了一种快速且全球化的方式,可以直接在 Shopify 上托管 Hydrogen,并针对电商进行了优化。Hydrogen
和 Oxygen 现已上线。
另见:氢
一个名为 Hydrogen 的 React 框架,它提供了看起来像是我自己编写的组件和 Hooks,以及一个名为 Oxygen 的服务器,用于托管 Hydrogen,它们都即将发布。
随着前端开发潮流完全转向 SPA 框架,使用 Liquid 开发主题本身就极具挑战性,但 Shopify 也将加入这一行列,这将改善用户体验、开发速度和开发体验。
其他的
-
无法在商品系列页面显示总页数。
如果能提供一个显示总页数的属性就好了,但 Store Front API 不允许我们获取商品系列中的商品总数。因此,在检索到一定数量的商品(最多 250 个)后,我们可以判断是否有下一页pageInfo.haxNextPage,但无法显示总页数,例如“1 / 12”。我能想到的解决方案是使用中断服务例程 (ISR) 在商品系列页面上定期获取商品系列信息,从 Store Front API 或 GraphQL Admin API 获取商品系列信息,然后获取商品总数。 -
商店里展示的商品
我正在使用一款名为Oberlo的应用程序。 -
点击“前往结账”后,结账流程与主题相同,会跳转到 Shopify 提供的支付页面
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/useCart.ts#L110 -
对集合中的产品进行排序
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/graphql/collection/getCollectionWithProducts.ts#L87
查询的参数列在QueryRoot中“products”的“arguments”中。 -
产品标题关键词搜索
https://github.com/momonoki1990/nextjs-shopify-store/blob/a91df30dd6fe4f6e6f057294dbbbb71876602ec9/lib/graphql/product/getProductsByTitle.ts#L52-L90 Shopify GraphQL 查询部分匹配过滤
器https://stackoverflow.com/questions/51742384/shopify-graphql-partial-matching-on-query-filter
感谢阅读!
文章来源:https://dev.to/momonoki1990/built-a-shopify-store-with-next-js-38c4
