I want to make a shopify theme using react.
You have a bunch of template files that have access to global server-side variables with liquid e.g. {{ product.title }}
. Think wordpress or any other theme-based system.
/theme
/template
/index.liquid
/products.liquid
- Because this site is hosted on Shopify I don't have access to the server to render out react on the server dynamically.
- Because this is an e-commerce store I can't have pages not be rendered server side, for SEO reasons.
- I need to programmatically generate all of the pages in the template with react
render
locally, each template would have a component.
It's simple enough to pass the string versions of liquid variables to a component. What I'm not sure of is how to differentiate the props / components that are render out saved within a template and the instance of react in javascript that is running on the site. When the client runs react if the liquid variables are the default properties all the valued server-side variables will be converted to their string / variable counterpart this isn't what we want. React doesn't have the data, this is bad.
To fix this I thought about having two sets of properties, one getLiquidProps
that will be utilized when I call something like renderLiquid()
. Similar to the way react-async works. However what I really need is a way to read the existing values that the server wrote to the DOM and have those values be the component props. But this is us using the react server DOM as our datastore is this possible?
If I have a simple component for cart counter:
var CartCount = React.createClass({
getDefaultProps: function(){
return {
"count": '{{ cart.item_count }}'
}
},
render: function() {
return (
<div className="cartCount">
{ this.props.count }
</div>
)
}
});
The server will render
<div className="cartCount">
3
</div>
The client-side react will overwrite it again
<div className="cartCount">
{ this.props.count }
</div>
Hey!
What would be the 2021 approach of having a hybrid react/liquid shopify storefront?
I had the following idea in mind:
To each .liquid page, add a script tag that server side renders all needed liquid variables into a global JavaScript object (window.data or sth).
Liquid should then take care of rendering all content that is SEO-important (landing pages (?), on the product page the product title, description, ...). React is then only used for things that are rather hard to implement in liquid (such as image slider, variant / amount selectors, ...).
What do you think of that?
EDIT:
I'm not that familiar with SEO, but it might even be an approach to first render all SEO-relevant content server side using liquid and then, client side, hide the content and mount a whole react application and not just smaller features as described above.