Hi all,
I thought I’d make my first post about something I’ve learned recently about metaobjects that’s not really well documented. Well, it is and it isn’t documented (explicitly). Either way, I feel I have some learnings that will help shape when you should (and maybe shouldn’t) use metaobjects.
We’re using metaobjects to configure some website functionality. Basically we’re storing country/region information – something we currently do in a JSON-formatted shop metafield, which isn’t very non-technical user friendly.
You could argue that this information could be stored as metafields on markets, however we liked the new Admin interface for metaobjects and being able to shape the data model was a great idea, as well as being able to provide information per country/region (especially if the market comprises multiple countries/regions). We also wanted to store country/region information for areas that we’re not selling to just yet (e.g. a “rest of world” region).
Using and configuring metaobjects is great. The Shopify Admin experience is very good there. It’s easy for non-technical people to use as well for entry management and translations.
One of the first “issues” I hit was using metaobjects in Liquid. It is possible to refer to individual metaobjects using shop.metaobjects[type][handle]
and you can use shop.metaobjects[type].values
for an iterator over multiple metaobjects. However, you can only refer up to 20 individual metaobjects by handles, and forloop iteration is controlled by Liquid’s pagination limitations.
If you are thinking of using metaobjects for site configuration where you need more than 20-50 configuration objects (e.g. let’s say you’re doing a store locator and you’re storing all store locations as metaobject entries), don’t expect to be able to render all stores within the single page render. I think this architecture makes sense for server-side rendering performance, and you can potentially get around it with smart UI/UX design that downloads additional pages when necessary, depending on what you’re use-case is.
Thankfully, one “hack” I found is that if you need to refer to more than 50 maximum metaobjects, you can use the {% paginate <iterator> by <amount> %}
tag. For instance, I have 65 country/region entries, so doing something like this actually works:
{% assign countries = shop.metaobjects.country.values %}
{% paginate countries by 200 %}
{% for country in countries %}
# ...
{% endfor %}
{% endpaginate %}
Eventually we’d love to use metaobjects to manage store locations, but we’ll have some issues due to, again, further limitations that probably just haven’t yet been worked into the platform. For example, if we are limited to maximum 50 entries per page, how do we search/filter/retrieve entries which are based on some kind of query or sorting method? I don’t believe search is available for metaobjects yet, and there might be a way to do it via Storefront API (I’ve not looked into it yet). For example, if I had latitude and longitude values for each store and I managed to create a UI that could produce a LatLng based on a search term and then try to search the metaobject entries for closest locations, it might be a real stretch to do something like that using Shopify.
So my main learnings are this:
- Metaobjects are primarily for paginated content
- Using metaobjects in Liquid is subject to maximum handle reference (20) and pagination limitations
- If you need to do something fancy (e.g. metaobject entry search), you’ll probably have to build your own app — beware of adding additional layers as further complication only leads to operational and development complexity