Prevent items of 1 or less appearing in Searchs /mark as out of stock

Hi,

I need to make all my products with quantity of 1 or less out of stock or not visible in the search bar or via google search.

I have added meta fields to remove these from the search but the products still appear while typing the search and can still be found on google.

How can I prevent products of 1 or less from showing up on the website?

Thanks

1 Like

I also used this code to hide the products from the search. Is there any way to add to this to prevent it coming up while typing search and in google? Thanks

for example, when I click search, there are no results but the results still appear when typing and in google..does anyone know how to get round this?

You can conditionally set noindex to that product
like


Thanks!

Thanks - how would I apply that across all products so they won’t appear when typing into search aswell as google?

This might work, depending on your theme. This worked before Shopify 2.0, with the whole metafield definitions thing I’m not sure anymore:

  1. Log in to your Shopify admin.
  2. Search for “Metafields”.
  3. Click on “Products”.
  4. Click “Add definition”.
  5. You can name it what you want.
  6. For “Namespace and key”, type seo.hidden
  7. Set description to what you want. I recommend “1 = hidden from search. 0 = not hidden”
  8. Click “+ Select type”.
  9. Click “Integer”.
  10. Save.
  11. Now go to your products list and checkbox every item you want to hide.
  12. Click “Bulk edit”.
  13. Click “Columns”.
  14. Under “Metafields”, find the seo.hidden metafield you just made and select it.
  15. Set the items you want to hide to have a value of 1 for seo.hidden.
  16. Save.

This should work still… hopefully!

Thanks, I think that should work as a way to hide products but not quite what I need. Am I right in saying that would that hide any product the metafield was attached to, not just products of quantity 1 or less?

Yes, you are correct. It’s kind of more of a band-aid than an exact solution.

However, I wonder if this code would work if you put it in the tag. Maybe you could test it on your store:

{% if product.variants.first.inventory_quantity <= 1 %}
    
{% endif %}

The code is saying, “if the product has a stock of 1 or less, do not index”.

I’m not the biggest expert on this-- but I can try to answer questions you have in this thread.

Thanks for your input! Just to clarify you don’t think its possible to create a global rule that could implement this? It would need to be done manually product by product?

Appreciate that. I will try that code and see if it has an effect. Thanks

1 Like

Hi Machalleri, I just wanted to check with this method as it seems like some of my options don’t match up with what you said? I’m not sue how this would work.

Thanks for the suggestion Threed but it didn’t seem to effect the products visibility. This was where I placed the code. If you or anyone else has other suggestions would be grateful to hear them. Thanks

1 Like

Hi, unfortunately it is not my own store so would have to get permission to give any third party access

Once we’ve looked at all possible options then would consider bringing someone else in, but would have to be confident they had a solution that was not one we’ve already tried out. Thanks

Darn, sorry that didn’t work.

I asked an AI and it gave me this:

{% if product %}
	{% if product.variants.first.inventory_quantity > 1 %}
		
	{% else %}
		{% assign metafields = product.metafields %}
		{% assign seo_hidden = metafields.seo.hidden %}
		{% if seo_hidden == null or seo_hidden == '0' %}
				{% assign metafields = metafields | json %}
				{% assign metafields["seo"] = "{'hidden': '1'}" | json %}
				{% comment %} Update the product with the new metafields {% endcomment %}
				{% assign updated_product = product | metafield: 'update', metafields %}
		{% endif %}
		
	{% endif %}
{% endif %}

"When the product’s inventory quantity is 1 or less, the code checks if the seo.hidden metafield is already set to 1. If it is, the code doesn’t update the metafields and just sets the “robots” meta tag to “noindex, nofollow”. If the seo.hidden metafield is not set, the code updates the metafields object to include the seo.hidden metafield set to 1, and then updates the product with the new metafields. After that, the “robots” meta tag is set to “noindex, nofollow”.

Note that this code only updates the seo.hidden metafield if it is not already set to 1. If you want to always update the seo.hidden metafield when the product’s inventory is 1 or less, you can remove the check for seo_hidden == null or seo_hidden == '0'."

Gonna be real, I didn’t even know you could change metafield values like this. Sometimes the code AI gives me doesn’t work at all, sometimes it works great. But it’s worth a try!

Thanks very much for that. Unfortunately it didn’t work yet. I tried the full code and cut out the part you mentioned…

{% if product %}
	{% if product.variants.first.inventory_quantity > 1 %}
		
	{% else %}
		{% assign metafields = product.metafields %}
		{% assign seo_hidden = metafields.seo.hidden %}
		
	{% endif %}
{% endif %}

Unfortunately the item is still appearing in google search. Strangely even when I test like this..

{% if product %}
		
	{% endif %}

the product still shows up. Do you think I’m missing something?

Ahh, so I think what could be the issue is that your site has not been recrawled yet. We had a similar issue with our site, where there was a vulnerability with a particular URL format and people could make pages to index on your site without your consent. (I’m gonna link that topic here too, because I don’t know if Shopify has fixed the problem yet: https://community.shopify.com/c/shopify-discussions/warning-collections-vendors-can-be-a-huge-security-risk-for-your/m-p/1886944#M332909)

But my point is that while we rolled out the fixes on our end ASAP, the manipulated URLs still appeared in search. Removing a page from search once it has been crawled by a search engine isn’t instant-- when they show the page to searchers, it’s because when they previously crawled the page, they didn’t see the instructions for .

So even if the page has now changed to have those instructions for a crawler to not index the page, the search engine doesn’t know that yet, so you have to wait for search engines to re-index your site.

There is a fix to this as well. It isn’t instant, but I got my pages removed from the search within half a day. You can ask the search engine to recrawl your website, where it will then read those instructions, and then remove the pages with in their tag.

For example, with Google Search console:

  1. Log in to Google Search Console
  2. Make sure your website is selected as the property
  3. Click on “URL inspection” in the menu
  4. Enter the URL of the page you would like to be re-indexed (in this case, a product page)
  5. You’ll see something that says “Page changed? REQUEST INDEXING”. Click that.
  6. A pop-up will show, testing if the URL can be re-indexed. It takes a little bit
  7. If successful, you will see “Indexing requested - URL was added to a priority crawl queue. Submitting a page multiple times will not change its queue position or priority.”

Here is a guide from Google about getting your pages recrawled: https://developers.google.com/search/docs/crawling-indexing/ask-google-to-recrawl?visit_id=638121718994461468-559836782&rd=1

Since you probably have several products, if this process is too tedious to do URLs one-by-one, you can try submitting your site’s sitemap: https://help.shopify.com/en/manual/promoting-marketing/seo/find-site-map

Thank you so much for you’re help mate I really appreciate it. I’m a bit of a novice to Shopify and I thought I’d fixed this issue for our client previously but he said the items were still showing.

The other aspect I’m not able to fix was when you type the product in the internal searcher it still comes up as a suggested product. However, the code I added does remove it from the search results.

I’m not sure if I insert similar code to

{%- for product in search.results -%}
  {%- assign all_inventory = 0 -%}
  {%- for variant in product.variants -%}
    {%- if variant.inventory_management -%}
      {%- assign all_inventory = variant.inventory_quantity | at_least: 0 | plus: all_inventory -%}
    {%- endif -%}
  {%- endfor -%}
  {%- if all_inventory > 1 -%}
    {%- render 'product-item', product: product, list: show_as_list, grid_classes: grid_classes -%}
  {%- endif -%}               
{%- endfor -%}

somewhere in search.template.liquid it would prevent the product appearing as a suggestion in the search bar?

Which theme are you using? I think the search capability changes from theme to theme. In my theme, there is something called predictive-search.liquid. This is associated with the search bar on my theme, where it will try to predict a result as a person is typing. main-search.liquid seems to control the main search result page. Do you have files like this on your site?

I don’t really know if this will work, but you can try this:

{% for item in search.results %}
	{% if item.object_type == 'product' -%}
		{% if item.product.inventory_quantity > 1 %}
			{%- render 'product-item', product: product, list: show_as_list, grid_classes: grid_classes -%}
		{% endif %}
	{%- endif -%} 
{% endfor %}

Search results documentation: https://shopify.dev/docs/api/liquid/objects#search-results

And no problem! I started working on Shopify stores with no clue on how things work, cause it was part of my job. Way confusing at first, still confusing for me but less so LOL.

Thanks again for you’re help it is really going to benefit me!

I’m using the Warehouse theme and don’t seem to have a main-search.liquid.

I can see some related files, the code didn’t work for me in the search-template.liquid file but maybe you can see some code in either of these that would be relevant to it…

search.ajax.liquid

{% layout none %}

{%- if search.results_count > 0 -%}
  {%- if search.types contains 'product' -%}
    

{{ 'header.search.products' | t }}

    
      {%- assign clean_terms = search.terms | split: ' AND ' | last | remove_first: '*' -%}

      {%- for item in search.results limit: 3 -%}
        
          

            

              
            

          

          
            

{{ item.title | highlight: clean_terms }}

            {{ item.price | money }}
          

        
      {%- endfor -%}
    

    {%- if search.results_count > 3 -%}
      
    {%- endif -%}
  {%- else -%}
    {%- if search.types contains 'article' and search.types contains 'page' -%}
      

{{ 'header.search.blog_posts_and_pages' | t }}

    {%- elsif search.types contains 'article' -%}
      

{{ 'header.search.blog_posts' | t }}

    {%- else -%}
      

{{ 'header.search.pages' | t }}

    {%- endif -%}

    
      {%- for item in search.results | limit: 3 -%}
        - {{ item.title }}
        
      {%- endfor -%}
    

  {%- endif -%}
{%- else -%}
  {%- assign show_empty_state = false -%}

  {%- if settings.search_mode == 'product' -%}
    {%- assign show_empty_state = true -%}
  {%- elsif search.types contains 'article' or search.types contains 'page' -%}
    {%- assign show_empty_state = true -%}
  {%- endif -%}

  {%- if show_empty_state -%}
    
      

{{ 'header.search.no_results' | t }}

    

  {%- endif -%}
{%- endif -%}

search.content.liquid

{%- comment -%}
On the dedicated search results, we show products differently from blog posts/pages. As a consequence, this cause all
kind of issues when doing the pagination. To circumvent this issue, when we enter into the search results, we only show
products, and we do another Ajax request to load the products and blog posts only.
{%- endcomment -%}

{%- layout none -%}

{%- assign filtered_terms = search.terms | replace: '*', '' -%}

{%- if filtered_terms contains ' AND ' -%}
  {%- assign filtered_terms = filtered_terms | split: ' AND ' | last -%}
{%- endif -%}

{%- if search.results_count > 0 -%}
  
    

      

      
        

          {%- for result in search.results limit: 20 -%}
            {%- if result.object_type == 'product' -%}
              {%- continue -%}
            {%- endif -%}

            - {{ result.title }}
            
          {%- endfor -%}
        

      

    

  

{%- endif -%}

Thanks again if you have any input :slightly_smiling_face: