Product description examples, and what 8,019 live products actually look like
Every article about product descriptions shows you an example, and almost none of them say where it came from. Usually somebody wrote it for the article. That demonstrates a style perfectly well, but it tells you nothing about what a description on a real store looks like, or how yours compares.
So we read some. Using the public catalogue endpoint that most Shopify storefronts expose, we read 225 live storefronts and measured the description on all 8,019 products they returned. The most common problem was not the one we went looking for. Empty descriptions turned out to be fairly rare, at 389 of 8,019. What is everywhere is repetition: 1,613 products, one in five, carry a description that another product in the same store carries word for word.
One thing to be straight about, since the first paragraph makes an issue of it: the worked example further down is written for this article too, and it is invented on purpose, because holding up a real store's page as the bad one is not something we are willing to do. What the 8,019 products give you is the measurement, which is to say how common each failure actually is, and therefore which one is worth your afternoon.
This applies to any catalogue with more products than patience, on Shopify or anywhere else. The measurement happens to come from Shopify storefronts, because that is the platform where the catalogue is usually readable without asking anyone's permission.
Key takeaways
- 1,613 of 8,019 products (20.1%) repeat another product's description word for word in the same store, ignoring case and whitespace. This showed up on 111 of the 225 storefronts.
- 1,265 (15.8%) run under 200 characters, and 389 (4.9%) are completely empty. The empty ones are counted inside the 1,265.
- The empty page is not the main event. 184 of the 225 storefronts had no empty description anywhere, and only 3 had nothing written on any product.
- Length is not quality. The median description ran to 701 characters, and a long paragraph of adjectives is worse than 200 characters of specifics.
- A description is doing three jobs at once, and the fill-in template below separates them: what the thing is, who it suits, and the specifics a buyer would otherwise have to email you about.
The descriptions at the end of the product list are the ones that never get written
Arvio reads your live catalogue, tells you which products have an empty or one-line description, and drafts each one against that product's own title, type, tags and variants. Nothing is saved until you approve it.
Check your own catalogue first
Before copying anyone's example, look at what you already have. Most Shopify storefronts publish their catalogue as JSON, with no login and no app:
https://your-store.com/products.json?limit=250
This script runs the same two tests, in the same order, that produced the numbers below. Two differences are worth knowing before you compare: we stopped at 50 products per store and this walks your whole catalogue, and our sample is 225 stores while yours is one.
# save as descriptions.py, then: python3 descriptions.py your-store.com
import json, re, sys, time, urllib.request
from collections import Counter
host = sys.argv[1]
products, page = [], 1
while True: # 250 at a time, until the catalogue runs out
url = "https://%s/products.json?limit=250&page=%d" % (host, page)
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
batch = json.load(urllib.request.urlopen(req))["products"]
products += batch
if len(batch) < 250:
break
page += 1
time.sleep(1)
def plain(html): # length test: strip the tags, decode the
text = re.sub(r"<[^>]+>", " ", html or "") # entities a browser would have
for a, b in ((" ", " "), ("&", "&"), ("<", "<"),
(">", ">"), ("'", "'"), (""", '"')):
text = text.replace(a, b) # rendered, then collapse the
return re.sub(r"\s+", " ", text).strip() # whitespace and count
def norm(html): # duplicate test: the same, then lowercased
return plain(html).lower()
lengths = sorted(len(plain(p.get("body_html"))) for p in products)
# empty descriptions are counted once as empty, not as copies of each other
seen = Counter(norm(p.get("body_html")) for p in products if plain(p.get("body_html")))
print("products read ", len(lengths))
print("empty ", sum(1 for n in lengths if n == 0))
print("under 200 chars ", sum(1 for n in lengths if n < 200))
print("same as another ", sum(1 for p in products
if seen[norm(p.get("body_html"))] > 1))
print("median length ", lengths[len(lengths) // 2] if lengths else 0)
for p in products:
text = plain(p.get("body_html"))
if not text:
print(" fix (empty):", p["handle"])
elif seen[norm(p.get("body_html"))] > 1:
print(" fix (copy): ", p["handle"])
elif len(text) < 200:
print(" fix (thin): ", p["handle"])
That last loop prints the handles, labelled by which problem they have, which is your work queue.
What we measured
Two tests, run over every product we could read. Length is characters after tags and whitespace are stripped. Duplication is that same text lowercased, then compared against every other product in the same store.
| Finding | Products | Share |
|---|---|---|
| Same text as another product in the same store | 1,613 | 20.1% |
| Under 200 characters | 1,265 | 15.8% |
| Description completely empty | 389 | 4.9% |
The first row is scored on a different test from the other two, so a product can land in more than one of them. Inside the second row, 389 are empty and 876 have somewhere between 1 and 199 characters. Read those as two separate problems wearing the same symptom: pages that were never written, and pages where somebody typed one sentence and moved on.
The store-level view is what changed our mind about which problem matters:
| At the store level | Stores |
|---|---|
| Have at least one description repeated on another product | 111 of 225 |
| Have no empty description anywhere | 184 of 225 |
| Have nothing written on any product | 3 of 225 |
We expected the empty page to be the story. It is not. Four out of five of these stores have written something on everything they sell, and only 3 of 225 had left the whole catalogue blank. Meanwhile half of them have at least one description sitting on two products at once, which is a different kind of failure: not a missing page, a page that was filled in by copying the one above it.
Here is the length spread, for context rather than as a target:
| Measure | Chars |
|---|---|
| Shortest quarter, below | 347 |
| Median | 701 |
| Longest quarter, above | 1,285 |
| Longest single product | 23,335 |
What this sample does not tell you:
- We read up to 50 products per store. 126 of the 225 storefronts hit that ceiling, and those stores account for 79% of the products counted. So the shares above describe the front of a catalogue, not the whole of one. If the unwritten pages cluster at the end of the product list, which is where they usually collect, this measurement misses them.
- The stores chose themselves. They come from a public list of merchants who posted their own storefront URL asking strangers for a review. That is not a random draw from Shopify, and these stores skew newer and smaller.
- That self-selection runs one way. Somebody who asks the internet to critique their store is paying attention to it. Whatever these numbers say about sloppy descriptions, the wider population is unlikely to be tidier.
The template
Copy this. It is deliberately short, because the failure modes we measured are absence, thinness and repetition, and no amount of styling advice fixes any of the three.
[One sentence: what the thing is, in the words a buyer would use.]
[Two or three sentences: who it suits and what for. Name the situation.
"Fits a 13-inch laptop and a water bottle" beats "spacious and versatile".]
Details
- [Material / composition]
- [Dimensions or size, with units]
- [What is included in the box]
- [Care, compatibility, or anything a buyer would otherwise email to ask]
[One sentence: the thing that would make somebody return it. Say it
plainly. This is the line that stops the return, and it is the line
most descriptions leave out.]
The first sentence is doing most of the work, because on a phone the description often sits collapsed behind a tap and that line is all anyone sees. The bullet block underneath is where the specifics live, and specifics are exactly what a buyer cannot get from the photo.
The bullets are also what makes the template survive being reused. The prose at the top can be similar across a product family without much harm. The moment the dimensions, the contents and the care line are copied across as well, you have two pages that a buyer cannot tell apart, which is the shape 1,613 of the products we read are in.
The last line looks like it is talking people out of buying, and it is. Naming who the product is wrong for costs you a few sales you would have refunded anyway, and it is what makes the four lines above it believable.
None of this is a keyword slot. The search side of a product page lives in different fields, which we wrote about separately in Shopify meta descriptions.
The same product, written twice
Both of these are written for this article. The product is invented so that no real store is being held up as a bad example.
Before:
Beautiful handmade ceramic mug. Perfect for coffee lovers. Order yours today!
After:
A 350 ml stoneware mug, thrown and glazed by hand, so no two are the
same shade.
It is heavier than a standard mug, which is the point if you drink
coffee slowly and hate a cold last mouthful. The handle takes two
fingers, so it sits differently in the hand than a standard mug.
Details
- Stoneware, food-safe reactive glaze
- 350 ml, 9 cm tall, 8.5 cm across the rim
- 460 g empty, roughly a third heavier than a thin-walled mug
- Dishwasher and microwave safe
- Sold singly, not as a set
If you want a matched set of six, this is the wrong mug. Colour varies
between firings, so two of these will rarely be an exact match.
The second version is longer, but that is a side effect. What actually changed is that six questions got answered: capacity, weight, dimensions, care, whether it is a set, and whether the colour is consistent. The first version answers none of them and asks for the order anyway.
Notice what happens if you paste that second version onto the same mug in a different glaze. Five of the six answers still hold, one of them is now wrong, and the page has stopped being about the product in the photo. That is how a description ends up on two products at once, and it rarely happens on purpose.
You now have the template. The catalogue is the hard part
Arvio takes the same shape you just filled in by hand and applies it product by product, using each product's own data instead of a generic paragraph. You review every draft and can undo any of them.
Where the work actually is
Writing one good description is a pleasant afternoon's work. Writing them until the product list runs out is a different activity, and that gap is where both the empty pages and the copied ones come from. A copied description is what an empty one looks like after somebody decided the page could not ship blank.
Three ways through it, in the order most stores try them:
One at a time in the admin. Workable while the product list still fits on a screen or two. Open the product, write, save, back to the list, and repeat. The cost is all in the switching, and duplicating an existing product to save that cost is exactly what puts the same paragraph on two pages.
A CSV round trip. Export, edit Body (HTML) in a spreadsheet, import with overwrite. Faster for a large batch, and it is the route where the mistakes are expensive: a column present in the file but left blank will write an empty value over your live one. Delete the columns you are not changing before you import. A spreadsheet is also the fastest place to spot repetition, because sorting on the description column stacks the identical ones next to each other.
The bulk editor. Shopify's bulk editor shows one field across many products at once, which suits this job better than the product page does. We covered how to open it and which fields it can reach in bulk editing product descriptions.
If the thin or repeated descriptions all arrived on the same day, they probably came in together from a supplier feed or an import. That has its own pattern and its own fix, which we measured in cleaning up after an import.
FAQ
Which products should I fix first?
Empty ones, then the repeated ones, then the thin ones, and inside each group start with whatever you actually sell. The script prints handles in catalogue order, so it is worth re-sorting that list against your own sales before you begin.
Is it a problem if two products share the same description?
It was the most common thing we found: 1,613 of 8,019 products, on 111 of 225 storefronts. The cost is not a penalty handed down by anybody, it is that two pages a buyer cannot tell apart force them to work out the difference themselves, and some of them will not bother. The fix is usually small. Keep the shared paragraph, replace the specifics underneath it.
How long should a product description be?
There is no target. In what we read, half of the products sat between 347 and 1,285 characters, with a median of 701, and the longest single description ran to 23,335. That spread is context, not a benchmark. A 200-character description that answers the size question beats an 800-character one that does not.
Do I need a description on every product?
Search engines and shopping surfaces read the description field, so an empty one is a page with less to work with. The stronger argument is simpler: a product page with no description asks a visitor to guess, and some of them will guess wrong and return it.
Should I write the description or let a model draft it?
A model drafting against a product's own title, type, tags and variants gives you something to edit, which beats an empty box. A model writing from the product name alone will invent specifics. The difference is what you feed it.
What about alt text on the product images?
Worth doing, and a separate job, and the script above cannot audit it. In a different and much smaller read, 41 storefronts on 4 September 2026, the public catalogue endpoint listed 391 product images and returned no alt value on any of them. Read that as a fact about what the endpoint hands back, not as a count of stores that left the field blank, since the admin holds alt text the endpoint does not publish. It is also not the sample described above, so the two should not be added together.
Method
Sample. 225 live Shopify storefronts, read on 5 September 2026, taken from a public list of stores whose owners had posted their own URL on the Shopify Community's Store Feedback board. Everything here came from endpoints any browser can fetch. Store names, domains and product names are deliberately not published.
The funnel. 230 stores on the list, 225 answered, 5 did not and are in no denominator. We requested up to 50 products from each and read 8,019 in total. 126 stores returned the full 50, which is the ceiling we set, and those stores hold 79% of the products counted, so treat every share above as describing the front of a catalogue rather than all of it.
Definitions. Length is the character count after HTML tags are stripped and whitespace is collapsed. Duplication is that same text lowercased and compared with every other product in the same store, so it is a separate test from length and a long description can still be a copy. Both are the definitions the script above uses.
Whether it looks like you. Stores that post their URL asking for feedback skew newer and smaller, and the list was built from stores still trading at the time, so anything that had already gone dark is missing. It is a convenience list, not a random draw from Shopify, and it leans one way we should say out loud: a merchant who invites strangers to critique their store is more likely than average to have tidied it first.
One page is a pleasant afternoon. The rest of the catalogue is why people give up
Arvio is an AI store operator: it reads the catalogue you already have, proposes the change per product, and waits for you to approve it.
Not ready to install anything? Run the free store audit on your storefront. It needs no account, and it reports empty and thin descriptions alongside the rest of your catalogue's data.
