Dev.to WebDev 🛠 Dev 👁 0 📖 2 min read

We had 167 pages Google wouldn't index. The fix was links, not tags.

Wonderlist (https://wonderlist.co) is a travel marketplace: Pakistani agencies list Umrah packages and tours, travelers compare and book in the app. The web side has a public page for every package, built with the Next.j

Wonderlist (https://wonderlist.co) is a travel marketplace: Pakistani agencies list Umrah packages and tours, travelers compare and book in the app. The web side has a public page for every package, built with the Next.js App Router.

Search Console said 16 pages indexed, 167 not. Every page had a title, a description, a canonical and JSON-LD. The sitemap listed them all. So what was wrong?

1. Nothing linked to the pages

The /tours page was a client-side search: it loaded packages with JavaScript after the page rendered. Googlebot does render JavaScript, but it ranks pages by the links it finds in HTML, and our server HTML had zero links to any package page. A URL that is only in the sitemap is a URL Google knows about but has no reason to rank.

The fix was boring: server-rendered category pages (/umrah-packages, /pakistan-tours, /international-tours) that list every bookable package as a plain <a href>, linked from the footer on every page. Then "similar packages" on each package page, an agency directory, and facet pages for real searches (/umrah-packages/21-days, /pakistan-tours/skardu) — each only indexable when at least two packages match, so there are no near-empty pages.

2. The sitemap listed trips that had already happened

79 of 180 active packages had tour dates in the past. They were in the sitemap and indexable, so Google was spending crawl on dead trips. Now a finished trip stays reachable (old links and QR posters still work) but is noindex and out of the sitemap, and its Offer says SoldOut.

3. Titles longer than Google shows

140 of 213 titles were over 60 characters (agencies write long package names). One helper builds every title: the package name first, the brand only if it fits, cut at a word.

export function seoTitle(main: string): string {
  const text = clean(main);
  if (text.length + SUFFIX.length <= 60) return `${text}${SUFFIX}`;
  return cutAtWord(text, 60);
}

4. Check it, don't assume it

A short script crawls the live sitemap and fails on any page that isn't 200, has a title over 60 or description over 155, a canonical that isn't itself, a noindex, more or fewer than one <h1>, or JSON-LD that doesn't parse. I run it against production after every deploy; the result today is 164 URLs, 0 problems. New URLs go to Bing and others through IndexNow straight after.

What I'd tell anyone with the same Search Console report

"Discovered – currently not indexed" usually isn't a tag problem. Open your server HTML (curl, not the browser) and count the <a href> links to the pages you want indexed. If it's zero, that's the bug.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.