DEV Community

Naoya Kumasegawa
Naoya Kumasegawa

Posted on

Built a Shopify store with Next.js šŸ˜

Alt Text

I've built a Shopify storefront with Next.js.
I've been using Shopify for work for a while now, and I was interested in Next.js because it supports various rendering methods such as SSR, SSG and ISR, so I decided to combine the two and build a store.
The design is based on Shopify's default Debut theme (which is now Dawn).

Technology used, etc.

Store: https://nextjs-shopify-store.vercel.app
Repository: https://github.com/naoya-kuma1990/nextjs-shopify-store
Technologies used: React, Next.js, TypeScript, Tailwind CSS, Material UI, Shopify JavaScript Buy SDK, Store Front API (Graph QL)
Implemented pages: Collection (product list), product details, cart, search results

Rate Limit for Next.js and Store Front API

As I mentioned at the beginning of this article, Next.js is a React framework that supports SSR and ISR. I used it this time because I thought that "when it comes to e-commerce sites, it's natural to support SEO, and if you want to achieve that with React, Next.js is the way to go". However, as it turns out, the site I made this time fails SEO because all the major information fetching, such as product information fetching, are performed on the client side lol.
This is because there is a cost limit called "API Rate Limits" on access to Shopify's API, and access is restricted depending on the type of API. You can read more about it in the official website, but basically, each store (strictly speaking, the private app that is the access point) has a set number of points, and if the points are consumed, the request will become an error until the points are recovered.
Therefore, the two Admin APIs (REST and GraphQL) can quickly become too costly to run every time a large number of users access the site, so there is Store Front API . Unlike the Admin API, this one is limited by IP. As a result, the Store Front API does not incur any cost overruns, as long as a certain amount of information is hit from the client side.
For these reasons, SSR is not the first choice for building a store front using Shopify's API, as SSR would mean hitting the API for every user access, which would quickly lead to cost overruns no matter which API you use.
The options are to use an ISR to hit the API at regular intervals and render it as a static page, or to use a CSR to hit the Store Front API each time. This time I chose CSR.

Get information in useEffect in page component
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/pages/collections/%5Bhandle%5D.tsx#L30-L60

Query the Store Front API using a custom client
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/graphql/collection/getCollectionWithProducts.ts#L69-L136

JavaScript SDK and custom clients

The JavaScript Buy SDK is an SDK for hitting the Store Front API. Basically, you can use this SDK for product information and cart operations, so I thought I'd use it entirely, but there were some problems. The SDK is only used for cart operations such as adding and deleting products, while the GraphQL client library (graphql-request) is used for retrieving product information and search functions on the product page, directly hitting the Store Front API. This is because, first of all, JS Buy SDK seems to have an old type definition of TypeScript, and the type information does not match the property that can actually be retrieved, and it is necessary to extend the type definition partially by oneself. This was the first time for me to extend the type definitions, so I learned a lot, but it was troublesome to determine which properties were typed and which were not. Also, the basic properties supported by the SDK are only a part of the information that can be retrieved by the Store Front API as described in the official documentation, and when I tried to extend the SDK, it seemed to be so cumbersome (for example, the collection page does not support sorting of products). (Sorting is achieved with the SDK like this)
Therefore, I decided to use the SDK only for cart operations where the SDK is sufficient, extending the library's typedefs, and to define a custom client to directly access to the Store Front API for the rest.

JS Buy SDK
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/client.ts

Custom Client
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/lib/graphql/customClient.ts

Extending the SDK type definitions
https://github.com/momonoki1990/nextjs-shopify-store/blob/main/types/shopify-buy.d.ts

Custom hooks

I made a custom hook for a operation of a cart.

Custom hooks (useCart)
https://github.com/momonoki1990/nextjs-shopify-store/blob/a91df30dd6fe4f6e6f057294dbbbb71876602ec9/lib/useCart.ts#L17-L130

Tailwind CSS and Material UI

To recreate Shopify's default theme Debut (Dawn is the default theme now), I used Tailwind CSS and Material UI components for animations like drawers and skeletons (dummies displayed during the initial drawing). I personally used Tailwind CSS when I wrote my theme in Liquid and was very impressed with how it solved the problem of CSS being global. However, I still found it very useful to use Tailwind to integrate styling with HTML and reduce the amount of writing.
We also used Tailwind in conjunction with Material UI, but as Tailwind is using class name and Material UI is a component, there were no conflicts. I don't think it's recommended to use different CSS frameworks together, so I don't think I'd personally recommend it for a real project.

Hydrogen and Oxygen.

Hydrogen includes commerce-specific components such as a cart, variant picker and media gallery to take the complexity out of building a custom storefront.
At the same time, "Oxygen" was announced. This is a fast and global way to host Hydrogen directly on Shopify, optimised for eCommerce.
Hydrogen and Oxygen are now available

See also: Hydrogen

A React framework called Hydrogen, which provides components and Hooks that look like I wrote by myself, and a server called Oxygen, which hosts Hydrogen, are being released.

With the tide of front-end development completely shifting to SPA frameworks, developing themes with Liquid has been a challenge in its own right, but Shopify is going to join the bandwagon, which will improve the UX, development speed, and development experience.

Others

Thank you for reading !

Top comments (6)

Collapse
 
titanxtream profile image
Tamojit Bhowmik

Great project I just started learining shopify and this will inspire me to go forward without hesitating and also Next Js is my favourite framework till now so it is great to see such a project with Next Js. Thank you and carry on.

Collapse
 
ahmadint profile image
ahmadint

@momonoki1990 As you mentioned in the first point of "Others" section.
I'm not sure if I fully understand the challenge you are facing but getting the product count of a created collection is accessible through storefront api.
https://.com/collections/all.json look for the products_count key

Collapse
 
momonoki1990 profile image
Naoya Kumasegawa

@ahmadint
Thank you for your advise !

https://.com/collections/all.json look for the products_count key

Maybe this is Rest Admin API endpoint of shopify, not GraphQL Storefrot API.
And, count rate limit way is different between Rest Admin and GraphQL StoreFront, so Rest Admin API would not withstand a large number of requests made each time the page is accessed.

Collapse
 
ilyas profile image
Azeem Ilyas

Hi @momonoki1990 ,

I love the design!

Could I ask what license this is under? I'd like to use it for some of my own projects but they might end up being used commercially. I noticed you didn't have a license on your github repo. Thanks!

Collapse
 
momonoki1990 profile image
Naoya Kumasegawa • Edited

@ilyas
Thank you for your comment.
And sorry for the very late reply ... šŸ™!!!
I added MIT License to this repository !
Thank you.

Collapse
 
gloriamaldonado profile image
Gloria Maldonado āœŖ

This is wonderful šŸ”„šŸ”„