I’m currently working on a project with a mobile sticky bottom bar and have run into an issue with handling URL query parameters directly in Liquid (not JavaScript). I have a single page but need to handle it differently based on the query parameters. Here’s the setup:
For the URL with the query type=product, I want to run a specific set of conditions.
For the URL with view=wishlist, a different set of conditions should apply.
Here are the example URLs:
/search?type=product&options
/search/?view=wishlist
I’m looking for help on how to write this logic in Liquid to check the query parameters in order to conditionally render the right content.
Thank you in advance for any guidance or advice on this!
There is currently no ‘native’ way to achieve this, but it can still be done via a hacky way that involves using content_for_header, but be advised this could break at any time should content_for_header change.
Just FYI, the view parameter is used by Shopify to present different templates, so be careful using that.
This is the setup I use.
{% comment %}
Retrieves parameters from the URL
Accepts:
- key: {String} Pass a key to retrieve certain data
Usage:
{% render 'data-url-parameters' key: 'handle' %}
{% endcomment %}
{%- liquid
# theme-check-disable
capture content_for_query_string
echo content_for_header
endcapture
# theme-check-enable
assign page_url = content_for_query_string | split: '"pageurl":"' | last | split: '"' | first | split: '.myshopify.com' | last | replace: '\/', '/' | replace: '%20', ' ' | replace: '\u0026', '&'
assign page_query_string = page_url | split: '/' | last
assign split_string = page_query_string | split: '?'
assign parameters = split_string[1] | downcase | split: '&'
if key
assign parameter_found = false
assign key_downcase = key | downcase
for parameter in parameters
assign parameter_arr = parameter | split: '='
assign parameter_property = parameter_arr[0] | downcase
if parameter_property == key_downcase and parameter_found == false
assign parameter_found = parameter_arr[1]
endif
endfor
if parameter_found
echo parameter_found
endif
else
assign parameters = parameters | join: ','
echo parameters
endif
-%}
Thank you, Luke, for your response and for sharing your setup! Your code gave me some helpful insights.
I noticed you used the key variable within the if condition but didn’t define it explicitly at the top. I wasn’t sure if that was intentional, so I took inspiration from your approach and made some adjustments to fit my use case.
This setup works to check if the URL contains view=wishlist and applies the condition accordingly. Let me know if you have any further suggestions or if there’s anything else I should consider. Thanks again for your help!
You could store the data in cart attributes and get it in Liquid that way.
You could still utilize the URLs like you were mentioning but you would just have the data in Liquid via cart attributes without needing to rely on something that could break anytime as @Luke noted…
Thank you for the suggestion! I understand the concept of using cart attributes to store the data and access it in Liquid, but could you provide a specific example? I’d like to see how the process would work end-to-end, especially for detecting the query parameter and setting it as a cart attribute.
The ability to add custom data for use within Liquid via URLs (or AJAX Cart API) is one of the main reasons I love Shopify.
You could even use them with URL redirects to mask the main URL with something like /wishlist. On the customer end they would see that path then the final one with the view parameter but never the one in between via their URL bar/history.
My approach is to use the url path as pseudo query parameters: /search/type/products
and then assign url_segments = request.path | split: '/'
and analyze the segments with liquid.
I believe this may be more stable than content_for_header, but no way to know for sure.
That approach certainly works in at least some cases, and could probably work here given that /search still seems to function normally with a variable path length.
The approach I shared would keep the end URL structure the same and not require use of parsing {{ content_for_header }} for details. Depending on your requirements it may be the most suitable approach for future-proof sake, but I guess ultimately Shopify could cause none of them to work in the future…
If the end URL structure does not matter much then the approach @Daniel_G may be quickest to implement.
At this point the ball is in your court @Ahsan_Ahmed. Any of these approaches seem like they could work well for you at least for now.
Not really relevant to what @Ahsan_Ahmed is trying to do, but thought it was worth mentioning that I ran into some issues using the content_for_header method on a page type that seems to be more aggressively cached, a blog post in my case. Basically, the URL/parameter that was in the content_for_header didn’t always match what I loaded in the browser.