Skip to content

Fix/seo canonical indexing - #711

Merged
likhithThammegowda merged 3 commits into
feature/opt3from
fix/seo-canonical-indexing
Aug 17, 2026
Merged

Fix/seo canonical indexing#711
likhithThammegowda merged 3 commits into
feature/opt3from
fix/seo-canonical-indexing

Conversation

@likhithThammegowda

Copy link
Copy Markdown
Contributor

No description provided.

Search Console reported 265 pages as "Page with redirect" and 293 as
"Discovered - currently not indexed", with indexed coverage falling from
278 to 261 while known URLs grew to 844.

The CDN 301-redirects every extension-less path to its trailing-slash
form, but all 547 sitemap URLs and every canonical were emitted without
the slash. Google discards a canonical that points at a redirect and
picks its own, which is why /public/home/ and /public/home both appear
in the Pages report as separate pages splitting one page's traffic.

- SeoService normalises canonical and og:url to the served form, and
  reuses an existing canonical tag instead of appending a second one
- generate-sitemap.js emits trailing slashes; sitemap.xml regenerated
- Course canonicals derive from the course, not the request URL, so
  stale slug variants and ?courseId= forms stop self-canonicalising
- slugify transliterates Devanagari, so Hindi titles no longer collapse
  to an empty slug and fall back to the id: 189 of 497 course URLs read
  /do_1145.../do_1145.../ and carried no search signal
- Unblock /public/login: it was robots-disallowed and noindex at once,
  so Google could never read the noindex and kept it indexed with no
  snippet. It earns 1,367 clicks at 44.56% CTR on the brand login
  cluster and now has a real title and description
- Drop the SearchAction: its target /app/search is robots-disallowed and
  Google indexed the literal template as a URL. The sitelinks search box
  is retired, so the markup only cost an indexed junk URL
- Org landing pages apply SEO on orgId rather than after ORG_CONFIG
  resolves; they are 47% of all impressions and were serving the generic
  homepage title
The generic CNE cluster is roughly 9,000 impressions a quarter sitting
at position 6-9 with about 1% CTR, and no page targeted it: "cne online"
(4,162 impressions, pos 8.48), "cne login" (1,815, pos 5.20), "cne"
(1,027, pos 9.48, zero clicks). Where a page does target the phrase the
domain already ranks top three, so the gap was the page, not authority.

The hub covers what CNE is, who needs credits, the credited courses, how
the certificate works, and how to log in - the last because "cne login"
had nothing answering it.

The course list is generated, not hand-written. CNE_COURSE_PLAYLIST in
the web_layout form config is the curated list the home page renders,
and cneName on each course holds its credit hours; every curated id has
a cneName, so the playlist is a strict subset that cannot introduce a
false claim. generate-sitemap.js joins the two at build time and writes
cne-courses.generated.ts, so credits, providers and ratings can never
drift from the catalogue. It falls back to filtering on cneName if the
form config is unreachable.

The generated file is committed because `yarn build` alone does not run
the generator.

Verified against a real prerender: 14 course cards in static HTML with
correct credits in English and Hindi, 16 crawlable internal links,
CollectionPage + FAQPage structured data, 1,323 indexable words.
Checked every CNE figure in the file against the catalogue's cneName
field. Three were wrong, two of them false claims about certification:

- Post Partum Haemorrhage was listed at 7.5 credits; it awards 5
- Antenatal Care was listed at 7.5 credits; it has no cneName and awards
  none. Removed, and the list filled out with Hypertension in Pregnancy
  (5) and Infection Prevention (2.5), both credited but missing
- The meta description claimed courses are worth 5-7.5 CNE hours each;
  the real INC range is 2.5-7.5
- Care of Newborn and Newborn Resuscitation was shown at 4.8 stars
  against an actual 4.73, and two learner counts were stale

Every remaining figure now verifies against the catalogue. Added a note
pointing at cneName as the source so the next edit does not reintroduce
a guessed value.
@likhithThammegowda
likhithThammegowda merged commit 1f63f22 into feature/opt3 Aug 17, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant