The reason why it did not work was same that you concluded, that it was not a product page. However, given the product ID we can get the recommendations of any product. The Shopify Docs for Recommendations object state
The recommendations object returns products only if it's used in a
theme section that's rendered through an HTTP request to
<base_url>?section_id=<section_id>&product_id=<product_id>. section_id
is the ID of the section where the recommendations object is being
used, and product_id is the ID of the product you want to show
recommended products for. To determine the base_url, use the
routes.product_recommendations_url attribute. Using the routes object
rather than a hardcoded URL ensures that the product recommendations
load in the correct locale.
So, unlike Shopify product page, where product object is globally available, you have to pass product ID from Shopify cart items. To do so, add a new section named product-recommendations-cart and include it in your cart template.
{% comment %}
The contents of the cart.liquid template can be found in /sections/cart-template.liquid
{% endcomment %}
{% section 'cart-template' %}
{% section 'product-recommendations-cart' %}
Then inside product-recommendations-cart section
{%- if section.settings.show_product_recommendations and cart.item_count > 0 -%}
{%- for item in cart.items -%}
{%- assign product_rec = item.product -%}
{%- endfor -%}
{%- if recommendations.performed -%}
{%- if recommendations.products_count > 0 -%}
<div class="product-recommendations__inner">
{%- if section.settings.heading != blank -%}
<div class="section-header text-center">
<h2>{{ section.settings.heading | escape }}</h2>
</div>
{%- endif -%}
<ul class="grid grid--uniform grid--view-items">
{%- for product in recommendations.products -%}
{%- assign display = true -%}
{%- for item in cart.items -%}
{%- if item.product.id == product.id -%}
{%- assign display = false -%}
{%- endif -%}
{%- endfor -%}
{%- if display == true -%}
<li class="grid__item small--one-half medium-up--one-quarter">
{% include 'product-card-grid', max_height: 250, product: product, show_vendor: section.settings.show_vendor %}
</li>
{%- endif -%}
{%- endfor -%}
</ul>
</div>
{%- endif -%}
{%- else -%}
<div class="page-width" data-base-url="{{ routes.product_recommendations_url }}" data-product-id="{{ product_rec.id }}" data-section-id="{{ section.id }}" data-section-type="product-recommendations"></div>
{%- endif -%}
{%- endif -%}
{% schema %}
{
"name": {
"en": "Product Recommend Cart"
},
"settings": [
{
"type": "checkbox",
"id": "show_product_recommendations",
"label": {
"en": "Show dynamic recommendations"
},
"info": {
"en": "Dynamic recommendations change and improve with time. [Learn more](https://help.shopify.com/en/themes/development/recommended-products)"
},
"default": true
},
{
"type": "text",
"id": "heading",
"label": {
"en": "Heading"
},
"default": {
"en": "You may also like"
}
},
{
"type": "checkbox",
"id": "show_vendor",
"label": {
"en": "Show vendor"
},
"default": false
}
]
}
{% endschema %}
Here, I added the condtion to display only if cart has some items and used the last product in cart to get recommendations.
As per your comment, I have added the condition to skip products that are already in cart. You can improve this using a string of product ids in cart instead of looping all cart items again and again.
If you need more control, use Product recommendations with the Product Recommendations API products response.