Lightning Fast E-Commerce: Remix your Shop with Shopify Hydrogen

Rate this content
Bookmark

Ready to take a thrilling ride into the world of headless e-commerce with Shopify Hydrogen? This cutting-edge solution, built on top of Remix, is the latest and greatest way to build high-performance online store. E-commerce is more important than ever, and providing a seamless customer experience is key. But building a platform that delivers can be daunting, even for experienced developers. With Hydrogen, you'll not only find it easier to build a top-of-the-line online store, but you'll also discover how much fun it can be! From creating collections and products to implementing a shopping cart, we'll show you how Hydrogen can take your developer experience to the next level.

27 min
15 Nov, 2023

Video Summary and Transcription

Today's Talk is about Shopify Hydrogen and how it simplifies the development of headless Shopify stores. The Talk covers topics such as mixing Storyblok and CMS data, code and data manipulation in Hydrogen, creating products and collections, handling SEO, building a performance server-side cart, setting up and managing the cart, and displaying cart and raffle information.

Available in Español

1. Introduction to Shopify Hydrogen

Short description:

Hello, I'm Alessandra Sfalato, a developer relations engineer at Storyblok. Today, I will talk about how to remix your shop with Shopify Hydrogen to build a lightning-fast e-commerce. Headless commerce separates the front-end and back-end, offering advantages such as omnichannel selling, faster time to market, better performance, SEO, personalization, and customization. Shopify Hydrogen simplifies the development of headless Shopify stores, leveraging Remix for improved performance and seamless integration with Shopify APIs. We will explore creating a project, fetching and mutating data, building collections and products, handling SEO, and building a cart using Hydrogen.

Hello, I'm Alessandra Sfalato, I'm a developer relations engineer at Storyblok. I'm French, you can hear by my accent, and I live in Madrid.

So today my topic is how you can remix your shop with Shopify hydrogen in order to build a lightning fast e-commerce. So well, I have the public in front, I'm a public in front so I cannot ask you who is using already, I don't know about it, but I hope you will learn and like it with my talk.

So in the first part of the talk, we will cover the basics of e-commerce, it's important, and the second part we will introduce Shopify hydrogen and its features, and finally the big part of the talk, we will talk, we will explore the code of a custom storefront build together with Hydrogen.

So headless commerce means the separation of the front-end and the back-end, and this is achieved thanks to an API-driven architecture, which allows for a flexible and customizable front-end experience. When compared to monolithic, headless offers many advantages, omnichannel selling, faster time to market, better performance, which leads to better SEO, personalization and customization, and certainly much more. However, it may come with an increased development complexity.

So imagine an e-commerce platform that offers all the benefits of headless commerce while minimizing the development complexity. This is where Shopify Hydrogen comes in. So Shopify Hydrogen is a new framework designed to simplify the development of headless Shopify stores. It incorporates built-in best practice and it's built on top of Remix. So again, I cannot ask you who knows Remix, but for the one who doesn't know Remix, it's a full stack React frameworks, which is based on web standards and it creates a really great developer experience because you work with web standards, so it makes everything simpler. And also you can make really scalable and fast website. I didn't know it before learning Hydrogen and by learning Hydrogen, I fall in love with Remix and now it's really my go-to framework.

So it offers, well, Hydrogen, not Remix, a component-based architecture that leverages Remix for improved performance and it also provides a seamless integration with Shopify APIs. So now it's time to take a deep dive into the code of a Shopify Hydrogen project. So first we will create the project, then we will see how to fetch and mutate data in Hydrogen, how to build the collection and products, how to handle SEO and how to build a cart.

So first we use the Shopify CLI to create the project with NPM-created Shopify Hydrogen latest, and this will create for you in two minutes a full featured ecommerce website. For this session we will use the template hello world command which provides a barbone repo and so we can really explore what we are building but let's see what we obtain with this command in just two minutes.

So this is a website you get with that, so we are off. What happened, oh yes I have to launch the development so npm run dev. Okay, so now we should be good. Okay, we have mock data, so we have this home page, we have all the products, we have the single products with options, we can add them to the cart, we can apply discounts, we can check out, we can sign in, we can search. So we have really everything and we can see it in the code of the storefront here. We have all the possible routes, login, logout, recover, register, reset, addresses, orders, collections, products, search. So you can use that and customize it to make your shop or explore it to learn. But I have used the Hello World template to build this little nice website about surf. So this is the homepage, the homepage is built with Shopify and Storyblok, my favorite headless CMS. So we have here a banner that come from the CMS and here we have a product grid that comes from Shopify and here single products where the image is pulled from Shopify and these little text which is pulled from the CMS.

2. Mixing Storyblok and CMS Data

Short description:

We can mix and match Storyblok and CMS data to create storytelling. Clicking on the board link gives access to collection entries. In the performance board, collection details and products are available. Single product pages have a shop pay button for quick purchase. The cart functionality allows adding, removing, and checking out items. Personalization is implemented, showing a different homepage based on user behavior and navigation.

So we can mix and match Storyblok and the CMS data and make storytelling. I will show you after how this is built. And now if I click on the board link, I have access to my collection entries. So we have performance board and original board collection. So if I click on a collection here in the performance board I have access to the collection details with a banner here and all the products in this collection. And then I can go to my single product. The shop pay button is a buy now button and then I can add to cart and here I can see the items in my cart. And I can go to my cart. I can remove items from the cart and I can check out. And here everything is working. And if I go back to my website and to my homepage, I can see that my banner has changed. Now it's featuring performance board and is also displaying only performance board in this product grid. This is because I have implemented some personalization. So depending of the behavior of my user, and here I have navigated to the performance board, I will serve a different home page. And as I have navigated to the performance board, I assume that my user is interested in performance board. So I serve that, and here I go directly to the performance board.

3. Exploring Code and Data Manipulation in Hydrogen

Short description:

In this part, we explore the code of the website, including the server.js file, routes, and components. We also learn about fetching and mutating data in Hydrogen using the storefront client. The storefront client allows us to send queries and mutations from REMIX loaders and actions. We create and inject the storefront client in server.js, pass it the necessary tokens, and use it to get data from products, collections, and the cart. We also use storefront.mutate for GraphQL mutations in RemixAction.

OK, so let's explore the code of my, of this little website. So I have a server.js file which is the entry point. And I have created some routes. So this is for the pages. This is the cart route, a collection index route that shows my collection entries, the collection handles that shows the collection details dynamically, the product.handle that shows the product details dynamically too. The root file is the parent root. And here I have my components. So header, footer, layout, the common components. And here I have all the cart components and in blocks it's the components that come from Storyblok and this is the ones that come from Storyblok and Shopify.

Let's go back to our slides. OK, so now let's see how to fetch and mutate data in Hydrogen. Hydrogen provides the storefront client to send queries and mutations from REMIX loaders and actions. So REMIX loaders are functions that get the data from the server, and REMIX actions are functions that make mutations and send data to the server. So for that, we are going to create and inject the storefront client in server.js. So let's see that in the code. So here is server.js. So we have this create storefront client. So this is when you create your storefront with the CLI. All that is provided except this content security policy that I had to customize, which you will have access to the code to. So we have this create storefront client function, and we use it to create our storefront and pass all our tokens here. And then we pass this storefront to get load context. So our storefront will be available in our global context in our loaders and actions. And by the way, you have here the repo if you want to grab it. And here you will have all the details to reproduce this website. OK, so we pass the storefront to the context. Next. And from there, we can call the storefront client in loaders and actions. So we will use storefront.query to send queries to our storefront and load data. We will use that to get the data from our products and collection, and also from our cart. And we will use storefront.mutate to perform graph-QL mutation in RemixAction.

4. Creating Products and Collections with Hydrogen

Short description:

We will use the storefront.query function to create products and collections. The GraphQL query includes the ID, title, handle, and image for collection entries. The loader function retrieves the data using the useLoaderData hook. Hydrogen React provides React components for easy integration, such as the image component for displaying Shopify images, the money component for price and currency, and the shop pay button for quick purchase. The server-side cart is more efficient, but other cart components are available for different use cases.

So we will use that for all our cart operations. So now let's see how we can create the products and collections. As I was showing you in the report, we have created this file should the collection index to display the collection entries, the collection handle to display the title description, and paginated products from the collection, and the products that are handled to display the product details. So this is how it works. This is for the collection details. We have our graph-QL query, and we request here the ID, the title, the handle, and the image that we need to display in our collection entries.

And then in our loader function, we pass this query to context storefront.query. And then we can, so this happened on the server. This is in the same file. And here in our component, we can retrieve our data. So our collections with the hook, it's a remix hook use loader data. And then we have just to map around our collections to display them. So same principle for the collection details and the product details. We make the query, we pass it to storefront.query and we retrieve it with use loader data.

We also have a hydrogen React which is a library of React components, hooks and utilities that can be used with any react framework or application. So for example, if you have a Next.js website, you can totally use this React components. So here's some examples, the image component get the product image was a Shopify image very easily. The money component will display the price and currency very easily too. And the shop pay button will display a buy now button just by passing the store domain. There is also many components for the cart. In our case, we are going to be in the server side cart. So we would not choose them because the server side is more efficient, but if you want to use them, go to the documentation and then you can implement a hydrogen on any React framework.

5. Handling SEO in Hydrogen

Short description:

Hydrogen provides an SEO component that collects data defined in the handle export. We can pass a function to receive data from the loader. SEO component is placed in the head of the root file. Titles and descriptions can be customized for different pages. Handling SEO in Hydrogen is easy.

So now let's see how we can handle SEO in a Hydrogen shop. So Hydrogen provides an SEO component that collects the data defined in the handle export. And we can pass a function that will receive the data from our loader as a prop. And here we choose the shop name as the title and the shop description as the description. Then we place our SEO component into the head in our root file, which is the parent root. Then in other roots, we can overwrite this here. So here, I want the title to be the product title and the description to be the product description. And this is the result. We can see that we retrieve our title in our head and our description as meta description. So it's really, really easy to handle SEO in Hydrogen.

6. Building a Performance Server-Side Cart

Short description:

Now it's time to build a cart using Remix's powerful mutation API. By implementing a traditional server-side form workflow, we can maintain a great user experience while avoiding the performance degradation caused by client-side cart operations. This approach also allows for progressive enhancement, as the cart can function without JavaScript.

And now it's time to build a cart. So, oops, I'm losing my hair clothes. So cart operation could be done on the client side, but this would cause performance degradation because of the additional code delivered to the browser. And it will also affect the customer experience as critical flows won't be actionable until JavaScript has finished loading. But Remix has a powerful mutation API that uses web standards like format element and HTTP. So we can implement a traditional server side form workflow while keeping the benefit of client side user experience. And it also allows progressive enhancement because our cart can totally work without JavaScript. So let's build a performance server side cart.

7. Setting Up the Cart and Adding Products

Short description:

To initialize the cart, we create a cart handler in our server.js file. This cart instance allows us to interact smoothly with the storefront API. Once the cart is set up, we can add products to it using the cart form component, which simplifies the process. We define the items to add, specify the action, and place the add to cart button on the product page. Additionally, we can remove items from the cart using the remove from cart button. To set up the cart root, we use cart.jsx.

So first we need to initialize a cart we create cart handler. So this is in our server.js file within the fetch handler. We create a cart instance using the create cart handler and this utility is super handy because it lets us interact smoothly with the storefront API. So we create our cart with essential configuration like the storefront and methods to get and set the cart ID. Next we pass our cart instance to get load context. So this ensure our cart is accessible and can be manipulated as needed. So with this step, our hydrogen cart is all set up and ready to roll.

Now we have a cart, we need to add products to our cart. So for that we are going to create our two cart button. So first we import the cart form component that abstracts away a lot of complexity. And let me tell you that I have done this talk several times a few months ago and this cart form component was not existing. So I was doing all that manually. So the cart form make things really easier. Well, not for me because I discovered that. One week ago and I have to make this talk again a few days after and I have to rebuild my slides, my project to practice all that. So it was not easy but that shows how fast and good hydrogen is evolving and bringing stuff to make the developer life easier.

So we define what to add to the cart with the lines, specifying the item of the merchandise ID passing the variant ID and the quantity. And we have a root attribute where we define where the form will be processed. So here in the cart root and in the actual attribute, we define the action. Here it's lines had. And in the inputs attribute, we pass our lines. So the products we want to add. Our button is nested inside the cart form. So this ensures that the click translates to adding items to the cart. Thanks to the lines had action and all this action is directed to our cart root. Then we place our add to cart button into our product page and there's a shop pay button. Then we also make a remove from cart buttons that will work the same, but here's the lines are the lines IDs representing the products to remove. And the action is lines remove. Here we add an icon inside of a button and this button will be placed in our cart item and offers the possibility to remove the product from the cart.

Okay, so now we have to set up this in the cart root, so cart.jsx.

8. Managing the Cart and Displaying Data

Short description:

Here we get the cart from the context, get the form data from the request, and pass it to the cart form. We manage cart actions using a switch statement. The cart ID is updated to ensure accuracy. We need to grab the cart data to display it in the header icon and cart page. The loader retrieves the cart data from the server in the root file. We use defer to handle critical data loading and resolve the cart promise. The cart components render the products, quantity, total, and checkout button.

And here we get the cart from the context, then we get the form data from the request and we pass it to cart form, get for input to grab our action and input from there. We set up a switch statement to manage this cart actions. So depending on the action, we trigger the different cart function, add, remove or update lines. And then a small but crucial detail is a cart ID. It can change. So we always make sure that is updated.

Okay, so now we have a cart, we have a button to have items to our cart. So we need to grab the data from the cart to read it and display it. And we need it in two places because you remember that we have this little icon in the header that display the number of item in the cart. And of course, we have our cart page where we want to display everything. So we need this data to be globally accessible, and that's why we're going to write our loader. So the loader gets the data from the server in the root file, which is the parent root.

Okay, so here we are in our root file, in our loader, and we get the cart from the context. And we get the data with the function cart get. But here we don't want to wait for this promise to be resolved because we have other critical data to load. The data from the shop to get that we need for our SEO to get the shop name and the shop description that we have seen before. So for that we use defer which is a remix utility for creating streaming deferred responses. And it will transport the premises to our UI components. So here it's, this is how we create our cart icon. So we use the hook use loader data to get the data from the root because the cart icon is a child from the root file. So we can get the data as a component level with use loader data. We have access to the parents root. And then here we resolve the cart promise with a weight along with suspense. Then we get the data and from this data we get the total quantity. So we can display it in our icon. Then we can create all our cart components. So the line item, we render each product from the cart and we render also here, our remove from cart button. The cart lines items component is using the flatten connection another hydrogen react component that flattens the northern edges object with simple array of lines which represent each of our products. So here we display all the products. The cart summary component renders a total using the money component and the checkout button links to the checkout URL.

9. Displaying Cart and Raffle Information

Short description:

The cart component displays all the products, cart lines, items, total, and checkout button. We use the use matches hook to access the cart data from the root file. If there are items in the cart, the cart content component is displayed; otherwise, the cart empty component is shown. Scan the QR code for access to slides, Storyblok and Hydrogen documentation. Don't forget to participate in the raffle for a chance to win an Egghead subscription.

Finally, the cart component displays everything all our products, the cart lines, items, the total with the cart summary and the checkout button to checkout.

Now we need to display all that now are a cart root and the cart root is not a child of the root file. So here we use another hook, the use matches hook that give us access to the root file. And from there, we can get the data from the cart. And then again, we use a wait to resolve the cart with suspense, we get our data. If we are items in our cart, we display the cart content component, otherwise we display the cart empty component.

And while we have a nice small e-commerce website, headless, really easy to build. So I hope you like this talk and here you can grab this QR code and have access to the slide where you will have access to the repository, to also the Story Block documentation and to the Hydrogen documentation. I really recommend you go there. It's really well done. I have learned everything from them. And I'm not a documentation person. I'm a video learner. So it's really, really good. And the Remix documentation, which is really well done too.

And finally, I invite you to scan this QR code in order to perhaps win a subscription to Egghead because Storyblok organized a raffle. And for that you scan the QR code, you fill out the form by December 31 and you can win an Egghead subscription. So thank you.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
9 min
Scaling WordPress with Next.js
As modern as the web is, WordPress is still king. It’s not the most scalable, but is still compelling with its long history and UX. How can we leverage Next.js to bring WordPress to the modern web? We’ll walk through the tools that Next.js provides us to scale WordPress to the world. We’ll talk about what APIs we can use to easily wrangle WordPress content and how we can make the dynamic bits static.
React Summit 2023React Summit 2023
25 min
Off with Their Heads: Rise of the Headless Components
Aren't You Tired of Repeating Yourself? Tired of repeating the same code over and over again in your React projects? In this talk, we'll discover the power of headless components, a design pattern that separates the logic from the presentation layer, allowing you to create reusable and flexible UI components.
We'll explore how headless components can simplify your development process, saving you both time and effort. We'll examine popular headless component libraries and provide tips for integrating them into your projects. Whether you're a beginner or an experienced developer, join us to discover how headless components can help you streamline your React development and create high-quality, customizable UIs.
GraphQL Galaxy 2021GraphQL Galaxy 2021
23 min
Exploring the WordPress Graph with Next.js & WPGraphQL
Headless Wordpress using its built-in REST API is a powerful solution to scale WordPress to the web, but complex relationships can easily turn into chains of requests, making maintainability difficult along with the potential cost of performance.
With WPGraphQL, we can harness the benefits of GraphQL, leading to a better developer experience and optimized request logic, making sure we’re only delivering what we need to our users.We’ll explore these advantages and how these pieces fit together with modern tools like Next.js to build great experiences for the web.

Slides & more
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
API-first Development with Headless WordPress
When the burden of rendering is removed from WordPress, it becomes an open source API platform. With a few plugins like WPGraphQL, you can create an extensible backend for your React apps to consume which enables modern architectures and development practices in WordPress.

Workshops on related topic

Node Congress 2022Node Congress 2022
134 min
Deploying a decoupled restaurant review site to production with Strapi and Platform.sh
WorkshopFree
Node.js has become an increasingly popular language to build and deploy backend APIs. In a world of legacy CMSs adopting decoupled implementations, plenty of frameworks have sprung up to classify themselves as "headless" CMSs, designed from the start to provide an easy way to personalize content models, administer permissions and authentication, and serve a content API quickly.
Strapi, one of the leaders in this space, has recently released their v4 version of the framework, and with Platform.sh it can be deployed alongside a number of frontends within the same project, giving a drastically simplified development experience working with decoupled sites. In this workshop, we'll deploy a Strapi demo application, which has been configured to serve a restaurant review site.
Piece piece you will add database services, tests, and frontends, all within the safety of isolated development environments. At the end, each user will have a functioning decoupled site, and some greater understanding of working with decoupled sites in production.