We run a small 925 silver jewelry workshop in Surat, India, and sell on Shopify. Two of our landing pages target searches that look almost the same but come from different buyers:
- moissanite rings for men
- lab grown diamond rings for men
Both are Shopify pages (/pages/...), not collections. Getting them to rank means solving two problems: page type, and making sure the two pages don't cannibalise each other. Here's how I approached both.
Problem 1: a text page for a shopping search
For either search, the buyer wants to see rings and prices. What ranks for queries like these is mostly category pages with a product grid, not articles.
Collection (/collections/...) |
Page (/pages/...) |
|
|---|---|---|
| Product grid | Built in | None by default |
| Filters and sorting | Yes | No |
| Product schema on grid | Usually from the theme | No |
| Best for | Shopping searches | Guides, policies, about |
A text-only page answering a shopping search is a mismatch, however good the copy is.
Fix: add a product grid without changing the URL
If a page already has links and history, keep the URL and add a grid with a small reusable section.
First, create one collection per stone, for example with tag rules:
- tag
moissanite-ring-men→ moissanite rings - tag
lab-grown-ring-men→ lab grown diamond rings
Then one section renders any collection on any page:
{% comment %} sections/collection-grid-on-page.liquid {% endcomment %}
{% assign c = collections[section.settings.collection] %}
<div class="page-width">
<h2>{{ section.settings.heading }}</h2>
<ul class="grid">
{% for product in c.products limit: section.settings.limit %}
<li class="grid__item">
{% render 'card-product', card_product: product %}
</li>
{% endfor %}
</ul>
</div>
{% schema %}
{
"name": "Collection grid on page",
"settings": [
{ "type": "collection", "id": "collection", "label": "Collection" },
{ "type": "text", "id": "heading", "label": "Heading", "default": "Shop the rings" },
{ "type": "range", "id": "limit", "label": "Products", "min": 4, "max": 24, "step": 4, "default": 12 }
],
"presets": [{ "name": "Collection grid on page" }]
}
{% endschema %}
Add the section to each page's template, pick the matching collection, and both pages now show live products with live prices. The snippet name (card-product) depends on your theme, so check snippets/ for the one your collection template uses.
Problem 2: two similar pages competing for the same searches
"Moissanite ring" and "lab grown diamond ring" sound alike, and a lot of buyers compare them. If both pages say the same things, Google can't tell which one to show, and both end up weaker.
The fix is to give each page a clearly different job.
| Moissanite page | Lab grown diamond page | |
|---|---|---|
| Buyer | Wants maximum sparkle on a budget | Wants a real diamond at a lower price |
| Core message | Very hard, more rainbow sparkle, much cheaper than diamond | Chemically the same as a mined diamond, lower price |
| H1 phrase | moissanite rings for men | lab grown diamond rings for men |
| Main questions answered | Is it a real diamond? Does it get cloudy? | Is it a real diamond? Will it test as diamond? |
| Comparison section | Short, links to the lab grown page | Short, links to the moissanite page |
Each page owns its own phrase and mentions the other stone only in one comparison section, with one link across. That tells Google how the two relate instead of making them duplicates.
Problem 3: product data that contradicts the page
While checking our catalogue, I found products whose titles said "Diamond" even though they weren't lab grown. On a lab grown page, that's a trust problem; on a moissanite page, it's a relevance problem.
A quick audit with the Admin GraphQL API:
{
products(first: 100, query: "tag:moissanite-ring-men OR tag:lab-grown-ring-men") {
nodes {
title
handle
tags
}
}
}
Then flag titles that don't match their tag:
for p in products:
title = p["title"].lower()
tags = [t.lower() for t in p["tags"]]
if "moissanite-ring-men" in tags and "moissanite" not in title:
print("Moissanite missing from title:", p["title"])
if "lab-grown-ring-men" in tags and "lab grown" not in title:
print("Lab grown missing from title:", p["title"])
Renaming a product title keeps its handle (URL) the same, so nothing breaks.
Problem 4: copy that repeats instead of answering
With the grid in place, the text supports the products instead of carrying the page. Under each grid, a few short H2 sections are enough:
Moissanite page
- What moissanite is, and how its sparkle differs from diamond
- Hardness and everyday wear
- Why a silver setting keeps the price low
- How it compares with lab grown diamond (one link across)
Lab grown diamond page
- What a lab grown diamond is
- How it compares with a mined diamond
- Why set it in 925 silver instead of gold
- How it compares with moissanite (one link across)
Keep the target phrase in the H1 and the first paragraph. There's no need to repeat it in every line.
The live pages
You can see both pages here:
Checklist
- [ ] Shopping search? Show a product grid, not only text
- [ ] One collection per stone, driven by tags
- [ ] Each page owns one phrase; the other stone gets one comparison section
- [ ] One link between the two pages, in that comparison section
- [ ] Product titles match the stone actually used
- [ ] Prices come from live product data, not typed into the copy
Wrapping up
When two pages target closely related searches, the goal isn't to make both pages cover everything. It's to give each one a clear job, show the right products, and connect them with a single honest comparison.
I run Glowory, a 925 sterling silver jewelry workshop in Surat, India, and write about the Shopify and SEO side of running a small manufacturing brand.
Top comments (0)