"i only speak liquid" #38: Hydrogen tips

Written by Luke (a Storetasker Expert)

Hey all đź‘‹!

Welcome to my 2nd!! edition of 'i_only_speak_liquid'. I’m Luke, an expert on Storetasker and I love working on headless challenges within Shopify.

In the previous newsletter I focused on comparing two different headless technologies paired up with two popular frontend frameworks (Hydrogen vs. Nuxt / Nacelle).

I’ll be authoring another 2 newsies before handing the pen off to another expert. Enjoy!

What I’ve been thinking about:

Let’s dive a little further into Shopify’s Hydrogen and I can give you a handful of tips based on their setup documentation that will help you sidestep some common issues I’ve found working with it in the past.

Tip 1 - Load your product information server side

Use the server side loader to your advantage. Remix is built to make use of node’s server side rendering, so you can preload your API data on the server and then hydrate the rest of the application. 

In Remix, you do this via the loader function, which takes in some loader arguments such as page parameters, the node request object, the application context and more. You can use these to get a product from Shopify like so.

This will run a request to the Shopify Storefront API, cache the response and we send it to the frontend as json in the return that can be used in the main React component how you wish.

Important to note, this method only ever runs on the server. So you don’t have access to some things you might be used to on the client side like the “window” object etc. It’s a common gotcha when working on server side apps.

Tip 2 - Caching is your friend. 

My example is close to what is on the Shopify Hydrogen website but with one quite important change. Caching. 

You should cache your API requests so that multiple requests don’t actually hit the shopify server for the response but their cache store for that product.  There’s plenty of options and you can set them via helper methods like in the example which looks like this:

Or by manually passing in an object that accepts a couple of properties such as max age and the revalidation time. 

Whatever you decide depends on your use case, but caching is better than not caching for anything that does not change often like product information etc.

Tip 3 - Defer your non critical information

Now you are loading in your information and caching, you want to make sure that you only load the minimal amount of information on the server, otherwise you run the risk of making the user wait for everything to be ready before they see anything.

Remix uses a defer method and Await component so you can do this easily. Say we had some recommended products along with our main product. We change the “json” method into the “defer” one like so.

Then we update our component to display the product information as soon as we have it, but we don’t show the recommended products until we get the resolve back from the promise.

The Suspense component allows you to set up a fallback, this is usually a component that shows a loading skeleton etc. Inside it is the Await, this component takes in the promise that we pass from the defer method in our loader and once that resolves, we show the actual component. We pass in the data to the new component from the return of the Await component and it renders as normal.

With this, we load the page quickly with the main product data, then we just show a loading state until Shopify comes back with the recommended products. 

Using defer, you can load any non-critical data onto pages but it is not limited to Shopify. Third party apps and other data can also be loaded into the loader and deferred. This reduces the risk of slowing down your site because of slow response times from other parties which you have little control over. 

Tip 4 - Only load your information once if you can

In some cases in the past I’ve seen multiple requests to the Shopify API for the same information over and over because the API request is tied to the route params changing or the variant selection buttons.  

If you see this, or do it by accident (we’ve all been there) then just think about how you can store the information, reuse it to save network requests and make things quicker. 

One example is to use a “State” store which in React is called a Context. By wrapping your product route in say a Product Context. You can set up a store for product information that is returned from the API. 

Then set up your selected options in the context too. That way, rather than asking Shopify to return information based on the selected options from the API, you can just filter the product variant data you have and update the product page.

3 links you can’t miss:

Shopify caching - here’s the documentation to the Shopify api caching which explains in more detail the methods available. 

Remix performance docs -  This is a WIP doc from remix but it outlines some useful things to consider when you want to improve performance of your Hydrogen storefront.  This should also go in pair with the streaming documentation. 

React context - here’s the documentation that explains the context store/state in React which will help get you started.  

1 app I like:

Appy Stamp - Loyalty and Rewards - Okay so this will be a little (hugely) biased. As the app I like is one of my own. I built this app as an alternative to the many “points” based loyalty programs for a lot of my clients who wanted an easier to understand program.

It offers a lot of similar functionality such as various reward types, VIP programs, integrations etc but I also wanted pricing to be fair and no lock away features behind expensive paywalls.

One learning as a freelancer:

I’ve learned that continuous iteration is better than trying to perfect something before releasing it.  We all get stuck in the mindset that something is not done until it works flawlessly, has every function we could ever think of, and is perfect for the end user.

In reality this is never the case, we have time constraints and bugs will always happen no matter how good we are. For this reason, it is more important to continually improve and iterate on your code and coding practices. 

The small changes and improvements you make will compound interest down the line which is going to save you time in the future. Don’t try and make a whole website faster, choose a key area like a PDP and start there and then choose a particular area which might be loading slower and improve that first.

Build up these iterations and eventually the entire site will be faster and hopefully because you did it in stages, you improved, your code got better and you passed on each learning to the next piece of code.

Now you can go back and start on the first component… good luck! 

Happy coding, 

Luke