Dev.to · 9 min read

The Store Passed QA. Then Its Best Seller Vanished from Search

The Store Passed QA. Then Its Best Seller Vanished from Search

At 8:17 on a Tuesday morning, a store administrator sent me a message: “Why has our best-selling product disappeared from search?” That sentence made my stomach tighten. Six days earlier, I had called the launch clean. The new theme was live. Checkout worked. Mobile pages felt quick. The redirects we knew about had passed our tests. I had even shared a screenshot of the performance report with several green circles on it. Now the store's most reliable organic landing page was losing impressions, and nobody knew why. I wanted the problem to be a bad deployment. A bad deployment has a comforting shape: find the commit, repair it, go home. Instead, the storefront looked healthy. The product opened from a direct link, the buy button worked, and the admin showed the correct inventory. The page existed. Search had simply stopped treating it as important. The first hour gave me all the wrong confidence The shop sold handmade lighting through a hosted commerce platform. Its catalog had about 180 products—large enough to create messy edge cases, but small enough that the team believed it could still be managed by eye. I opened the missing product page and ran through my usual checks: The server returned 200 OK. The page was allowed to be crawled. Its canonical tag pointed to the preferred URL. The product appeared in the XML sitemap. The title and description were present in the HTML. Everything on that page looked reasonable. By 10:00, I had collected plenty of reassuring evidence and still had no answer. Then the administrator joined the call. While I was talking about response codes, she said, almost as an aside, “I renamed one of the collections last month. The old name sounded too plain.” That small sentence changed the investigation. One tidy rename had cut an old path in half The collection used to be called Desk Lamps. During the rename, its public URL changed as well. The new address looked better inside the menu, but the old address returned a 404. Two design articles and an old newsletter still linked to that previous URL. Those links had been carrying people—and search authority—to the collection for more than a year. We had quietly led all of them into a dead end. The administrator had not made a foolish choice. She improved the wording she saw in the dashboard. The dashboard did not show the history attached to the old address, and our release checklist never asked her to preserve it. We added a permanent redirect: /collections/desk-lamps 301 → /collections/workspace-lighting A 301 tells browsers and crawlers that a resource has moved permanently. More importantly, it lets an old path keep doing useful work instead of becoming a wall. That fixed one break, but it did not explain everything. The product was visible only after a click I returned to the new collection and scrolled through it like a customer. The first 24 products appeared immediately. A Load more button revealed the rest. Our missing seller was in that second group. The interaction felt smooth, so it had passed visual QA. But when I inspected the initial HTML, the later product links were absent. They appeared only after JavaScript handled the button click. A crawler follows addresses. It does not explore a shop with the curiosity of a person. If the next group of products has no ordinary link, discovery becomes fragile. We kept the polished interaction but gave it a real route underneath: Next products JavaScript could still intercept that link and update the grid without a full reload. If the script failed—or a crawler read the page without clicking—the address remained available. This was the point where I felt embarrassed. I had spent time smoothing the animation between product batches. I had never asked whether the second batch had a path of its own. The sitemap listed the product, but a sitemap is only an announcement. Internal links show how a page belongs to the store. We had supplied the announcement and forgotten the road. A helpful filter had created more pages than products The next clue appeared in the crawl report. This catalog of roughly 180 items had produced more than 2,000 parameter URLs. Nothing malicious had happened. The administrator had enabled filters for room, finish, material, price, availability, and sort order. Each control helped shoppers narrow the catalog. Together, they could create a large number of address combinations: /collections/lighting?room=office&finish=brass&sort=price-asc Most combinations showed nearly the same inventory in a different order. Some returned empty grids. Search crawlers were spending attention on that maze while important category pages had weak internal paths. I could have blocked every filter and called the job complete. That would have ignored the administrator's knowledge. She knew that one room-and-product combination represented a genuine way customers searched; the other combinations were simply shopping controls. So we separated two jobs: A small set of useful search themes received clean, stable landing pages with their own copy and links. Temporary filter states remained useful inside the store without pretending that every combination deserved a place in search. The exact controls differ by platform. They may involve crawl rules, link behavior, canonical signals, or routing changes. The principle is simpler: decide which pages deserve discovery before asking code to enforce the decision. A canonical tag alone is not a cleanup button. If the storefront keeps generating endless links, crawlers can still spend time requesting them. Then three versions of the same product disagreed We found the last problem during a price check. The page showed $129. The machine-readable product data embedded in the theme still said $149. The shopping feed reported the item as out of stock because an export job had failed after an access token expired. To a customer, the product was available at the lower price. To two other systems, it was either more expensive or impossible to buy. This is where SEO stopped looking like “content” and started looking like data engineering. The theme had been reading an old custom field for its structured data. We changed it to use the same current catalog record that supplied the visible page. The feed exporter was reconnected to that source, and we added a check for disagreement. The idea was small enough to express as a test: expect(machineData.price).toBe(visiblePage.price); expect(shoppingFeed.stock).toBe(catalog.stock); This is illustrative code, not a platform API. The important part is the contract: price and availability should have one source of truth, even when several systems publish them. The administrator owned the accuracy of the catalog record. I owned the routes that carried it into the page, structured data, and feed. Neither of us could make the promise alone. The report had measured the wrong kind of safety The performance work had been real. The pages loaded faster, layout movement was lower, and shoppers benefited. But I had let a clean report calm me. It measured what happened after someone reached a page. It did not tell me whether an old link survived, whether the full catalog could be followed, or whether three systems agreed on stock. That was the most useful lesson from the incident: a SaaS platform can automate technical foundations, but it cannot understand the meaning of every admin decision. The developer sees rendering and routes. The administrator sees products and merchandising. Search visibility lives in the handoff between them. What changed after the repair There was no movie ending. Sales did not double overnight, and the graph did not leap upward the moment we deployed. The first reassuring sign was smaller: old referral links reached the right collection again. Then the cleaner category path began receiving more crawl activity. Over the following weeks, organic entrances stopped falling and gradually returned. The quiet recovery felt better than the green score had. We finally understood what we were measuring. More importantly, the team stopped treating SEO as a plugin setting or a developer task performed at launch. We wrote a short release agreement. Before an administrator changes a public URL, collection, product status, price, or navigation label, the change records: the current public address; the reason for the change; the new destination, if one exists; the person who will verify the result. Before a developer calls a storefront change complete, we check one full path from navigation to category to product—not only the component that changed. After release, we compare what a shopper sees with the HTTP response, page source, structured data, and feed. It takes minutes when the habit is normal. It takes days when we wait for traffic to disappear. A six-question check you can run today Choose one category that matters to the business and one product inside it. Ask these questions together: Can someone reach both pages through ordinary links without knowing their URLs? Does every important page return the intended status code and preferred URL? If an address changed, does the old one lead to a relevant new destination? Can the complete product list be reached without depending on a button click? Do the visible price and stock agree with structured data and any shopping feed? Are filters creating crawlable pages that nobody intentionally chose? Give each problem one owner and one verification step. “Install an SEO app” is not an owner. “The administrator confirms the catalog value; the developer tests the rendered output” is. The question I wish we had asked before launch The platform had not betrayed us. It had faithfully published our choices: a renamed address, a button without a path, a forest of filters, and three conflicting product records. Each choice looked harmless to the person making it. Their combined effect was almost invisible until the traffic graph went quiet. Now I use one question to bring the whole store into view: If a person does not already know this URL, can they still find the page, understand it, and trust what it says? That question is useful to a developer, a merchant, and a search engine for the same reason. It turns SEO from a mysterious score into a path we can walk together. Once the team could see that path, the store no longer felt like a machine we were afraid to touch. It became a system we understood—and a system we understood could be improved.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Programming & Dev News