Like/ Dislike Feature on Shopify

In today’s competitive e-commerce landscape, engaging your customers is more important than ever. Adding interactive features like a Like/Dislike option can provide valuable insights into customer preferences while creating a more personalized shopping experience.

Benifits for Like/ Dislike Feature

  1. Enhances User Engagement: Keeps users interactive on product pages.
  2. Provides Valuable Feedback: Helps identify popular or less favored products.
  3. Improves Recommendations: Enables personalized product suggestions.
  4. Boosts Social Proof: Highlights well-liked items, encouraging conversions.

Requirement

To add a Like/Dislike feature on Shopify for products or custom items (such as our “Graphic of the Week”), I’ll illustrate the process using products as an example. However, the same approach can be applied to any item.

Implementation

Two primary implementation approaches are available:

  1. Budget-Friendly Solution: Leveraging Shopify Metafields for simpler, cost-effective setups.
  2. Scalable Solution: Using AWS DynamoDB for high traffic handling and robust performance.

Approach 1: Using Shopify Metafields

To implement the feature, We need to add 2 metafield definition in each Product Metafields and Customer Metafield with exact configuration as show in the above image.

To add the definition, go to the admin dashboard, and after that go to settings and custom.

Metafields for Customers:

  1. likes: A JSON array of product IDs the customer has liked.
  2. dislikes: A JSON array of product IDs the customer has disliked.

Metafields for Products:

  1. likes: A JSON array of customer IDs who liked the product.
  2. dislikes: A JSON array of customer IDs who disliked the product.

These metafields will be updated via a custom app with Shopify Admin API and used to display likes/dislikes on the storefront.

The above approach is an easy solution which works well for websites with low to medium traffic.

/* Code snippet to get Product and Customer Metafields */

const fetchProductAndCustomerMetafields = async (productId, customerId) => {
const query = `
query getProductAndCustomerMetafields($productId: ID!, $customerId: ID!) {
product(id: $productId) {
metafields(first: 10) {
edges {
node {
id
namespace
key
value
type
}
}
}
}
customer(id: $customerId) {
metafields(first: 10) {
edges {
node {
id
namespace
key
value
type
}
}
}
}
}
`
;

const variables = {
productId: `gid://shopify/Product/${productId}`,
customerId: `gid://shopify/Customer/${customerId}`,
};

try {
const response = await axios.post(
'https://your-shop.myshopify.com/admin/api/2023-04/graphql.json',
{ query, variables },
{ headers: { 'X-Shopify-Access-Token': 'your-access-token' } }
);

const productMetafields = response.data.data.product.metafields.edges;
const customerMetafields = response.data.data.customer.metafields.edges;

console.log('Product Metafields:', productMetafields);
console.log('Customer Metafields:', customerMetafields);
} catch (error) {
console.error('Error fetching metafields:', error);
}
};

/* Code snippet to update the metafield */

/* Similar logic for dislike */
const updateLike = async (customerId, customerMetafieldId, productId, productMetafieldId, likes) => {
const query = `
mutation updateCustomerAndProductMetafields(
$customerId: ID!,
$metafieldId: ID!,
$productId: ID!,
$productMetafieldId: ID!,
$likes: String!
) {
customerUpdate(input: {
id: $customerId
metafields: [
{
id: $metafieldId
namespace: "custom"
key: "likes"
value: $likes
type: "json"
}
]
}) {
customer {
id
}
userErrors {
field
message
}
}

productUpdate(input: {
id: $productId
metafields: [
{
id: $productMetafieldId
namespace: "custom"
key: "likes"
value: $likes
type: "json"
}
]
}) {
product {
id
}
userErrors {
field
message
}
}
}
`
;

const variables = {
customerId: `gid://shopify/Customer/${customerId}`,
metafieldId: customerMetafieldId,
productId: `gid://shopify/Product/${productId}`,
productMetafieldId: productMetafieldId,
likes: JSON.stringify(likes)
};

try {
const response = await axios.post(
'https://your-shop.myshopify.com/admin/api/2023-04/graphql.json',
{ query, variables },
{ headers: { 'X-Shopify-Access-Token': 'your-access-token' } }
);

console.log('Response:', response.data);
} catch (error) {
console.error('Error updating metafields:', error);
}
};

Approach 2: Using AWS DynamoDB

Why DynamoDB?

AWS DynamoDB is a NoSQL database that offers high scalability, low latency, and a cost-efficient structure, making it ideal for handling dynamic user interactions like likes/dislikes.

DynamoDB is known for one table structure. In NoSQL databases, Table/ Schema Design is done based on the Query Access Patterns

Query Access Patterns

  1. Fetch metadata for n image
    -Use a batch query with the PK pattern Product#<Product_id> and SK=Metadata
  2. Fetch all likes or dislikes by a specific user
    -
    Query using PK = User#<User_id> and filter SK starting with Like# or Dislike#
  3. Fetch the total number of likes or dislikes for an Product
    -
    Query with PK = Product#<Product_id> and SK = Metadata
  4. Fetch all the users by a specific product
    -Need to add GSI on the Sort Key (starting with Like# or Dislike#) and query on that. 

Adding/ Updating Likes/ Dislike for Product by User (Should be Transactional)

  1. Increment likes or dislikes for an image
    -
    Use an Update Expression to increment the like_count or dislike_count atomically.
  2. Track whether a user has liked or disliked an image
    -
    Write a record in the USER#<User_id> partition for LIKE#<Product_id> or DISLIKE#<Product_id>.

The above queries can be helpful, now you have to use Shopify’s Product Id and User’s Id to store likes/dislikes for products by users.

Whatever you solution you choose to implement, you will still need an API to connect the frontend to the persistent storage (Metafield or DynamoDB). AWS Lambda functions, along with AWS Lambda Function API or AWS API Gateway, can facilitate this integration effectively and is budget friendly.

Pricing Overview

No Additional Charges for Storage Metafields in Shopify

Pricing for AWS Lambda

Pricing for AWS (Dynamo DB)

  • Read & Write Request
  • Data Storage

Conclusion

In conclusion, adding a Like/Dislike feature to your Shopify store boosts user engagement and provides valuable feedback. Whether using the scalable AWS DynamoDB approach or the cost-effective Shopify Metafield solution, both methods efficiently track user preferences. This feature can also increase social proof and drive conversions, giving your store a competitive edge in the e-commerce market.

Author: Jainish Sakhidas

Back to blog