Using URL Parameters In Liquid

Topic summary

A developer is building a recipe filtering system using Shopify metaobjects and wants to filter by ingredients and category with pagination.

Core Issue:

  • Liquid templates cannot directly read URL parameters (like ?ingredient=salmon&category=fish&page=3) because Liquid is server-side compiled before the request reaches the browser
  • The developer initially hoped to use Liquid templating with URL parameters instead of AJAX calls

Recommended Solutions:

  1. AJAX + JavaScript approach - Make backend API calls to GraphQL, then build HTML dynamically on the frontend
  2. Different URLs instead of parameters - Better for SEO but less flexible
  3. Hybrid approach (recommended) - Render initial recipes in Liquid for SEO, add JavaScript for dynamic filtering, include <noscript> fallback for crawlers

SEO Considerations:
Pure AJAX-built content may not be indexed properly by search engines without server-side rendering or static fallbacks.

Resolution:
The original poster confirmed they will proceed with the AJAX/JavaScript approach as recommended.

Summarized with AI on October 27. AI used: claude-sonnet-4-5-20250929.

I am creating a metaobject that holds recipes. I want to be able to filter the recipes by ingredients and category. I also want the list to be paginated. From my research, it looks like the best practice is to make an ajax call to a backend app that then calls the graphql api to retrieve the entries and return it to the frontend. The frontend js would then build the html.

I’d prefer to be able to pass in a url parameter to the page and use a liquid template to create the page, /recipes?ingredient=salmon&category=fish&page=3. Is this possible? From everything I have read, url parameters can’t be read in liquid without a hack because the code is compiled on the server? I don’t understand what that means, do they mean cached and not compiled? why are the url parameters not passed as an attribute on the request object?

What are the SEO implications to using an ajax call to build the recipe lists? What is the best way to solution this?

I’d like to do something like this with the filters applied:

{% assign sortable_metaboject = shop.metaobjects.recipes.values %}
{% assign sorted_metaobject = sortable_metaboject | sort_natural: 'date_created' %}

{% paginate shop.metaobjects.recipes.values by 10 %}
	{% for entry in sorted_metaobject %}
		{% render 'metaobject-image-with-text-date', recipe: entry, image_first: image_first, show_button: true %}
	{% endfor %}
	{{ paginate | default_pagination }}
{% endpaginate %}

Hi,

Hope this will work

  • You can’t directly access ?ingredient=salmon in Liquid and Liquid doesn’t have access to the request.GET
  • Option 1: Use AJAX + JavaScript (Best for Dynamic Filtering)
  • Option 2: Use Different URLs Instead of Params (Best for SEO)
  • Suggested Best Practice Solution (for SEO + Filters + Pagination): Backend App + AJAX (with graceful fallback)
    Step 1: Render all recipes in Liquid (initial load)
    Step 2: Add JavaScript to Filter Recipes Dynamically
    Step 3: Use to Provide a Static Version for SEO

JavaScript example:


That was my fear. Thanks for confirming this is the way to do it.