This post is for marketing and SEO teams at hospitals and clinic groups whose doctor profiles are built with a JavaScript framework, and who suspect that what a patient sees is not what a search engine receives. You do not need to be a developer to run the test described here, though you will need someone who can open browser developer tools and run a command line fetch.
The question is narrow: for each doctor profile, which fields exist in the HTML the server sends, which appear only after JavaScript runs, and which never appear at all in a rendered page? The fields that matter most on a profile are the doctor's name, specialty, qualifications, registration number, hospital and location, languages, consultation slots, and the structured data that describes them. If a field is missing from what Google processes, it cannot help the page rank and cannot support a rich result.
We describe a method, not a set of results. The point is that you can repeat it on your own pages in an afternoon and get an answer specific to your build.
How Google handles JavaScript pages
Google's JavaScript SEO basics describe three phases: crawling, rendering and indexing. A page with a 200 status code is queued for rendering, and the queue can take longer than a few seconds. Google's documentation also says that server-side or pre-rendering is still a good idea, because it makes sites faster for users and because not all bots can run JavaScript.
Several other points from that document bear directly on doctor profiles:
- Google discovers links only from
<a>elements with anhrefattribute. A "Book appointment" or "View profile" button wired up with a click handler is not a link to a crawler. - Titles and meta descriptions can be set with JavaScript, but a canonical tag injected by JavaScript must agree with any canonical in the original HTML, and there should be only one.
- If a page carries
noindexin the original HTML, Google may skip rendering, so JavaScript that removes the tag later may never run. - Content on pages or in files blocked by robots.txt is not rendered. If your profile data comes from an API path that is disallowed, the rendered page will be empty of it.
- Client-side routed apps should return a real 404 status for missing pages, or redirect to a URL that does, to avoid soft 404s.
None of this means client-side rendering never works. Google does render JavaScript. It means that every dependency in the chain is a place the page can fail without anyone noticing.
The test: raw HTML against rendered DOM
Pick 20 doctor profiles. Choose them deliberately: a mix of departments, a few doctors with long biographies, a few with many locations, at least two who were recently added, and at least two with no photograph. If the site has more than one template, such as a flagship hospital and a satellite clinic, include both.
For each URL, capture three views.
View 1: the raw HTML. This is what the server sends before any script executes. Use a command line fetch (curl -s -A "Mozilla/5.0" URL > raw.html) or view-source in the browser. Do not use the Elements panel of developer tools for this; that shows the live DOM after scripts run, which is a different thing.
View 2: the rendered DOM as Google sees it. In Search Console, run the URL Inspection tool on the live URL and open the rendered HTML and screenshot. The Rich Results Test also shows the rendered HTML Google retrieved and any structured data it parsed. These tools use Google's own renderer and are the closest public view of what the indexer receives.
View 3: your own browser, without interaction. Load the page with a clean profile, wait for the network to settle, and save the DOM. This shows what a patient sees without clicking any tabs, which is the baseline for what a renderer that does not click anything could see.
Then compare the three in a spreadsheet with one row per field and one column per view.
The field-by-field checklist
| Field | Where it usually fails | What to check |
|---|---|---|
| Doctor name, specialty (in the H1 and title) | Set by client script after the data loads | Present in raw HTML title and H1? |
| Registration number and council | Loaded by a separate API call, or placed inside a "credentials" accordion that renders on click | Present in raw HTML or rendered HTML? Visible text, not an image? |
| Qualifications, experience | Hidden in tabs generated on click | Appears in the rendered HTML without interaction? |
| Hospital, location, address | Map widget only, no text | Text address in the HTML, linked to the location page? |
| Languages spoken | Filter chip rendered by a script | Present in text? |
| Consultation slots | Fetched live from a scheduling system | Absent from raw HTML is acceptable, but the page must still explain the booking route in static text |
| Profile photo and alt text | Lazy-loaded without an <img> in the initial HTML | img element and alt present? |
| Internal links (department, location, related doctors) | Click handlers, not anchors | Real <a href> elements in the rendered HTML? |
| Canonical, meta robots | Injected by script, or contradictory between raw and rendered | Same value in both views? Only one tag? |
| Structured data (Physician, MedicalBusiness or equivalent JSON-LD) | Generated client-side; fields differ from visible content | Present in rendered HTML and valid in the Rich Results Test? |
| HTTP status for a non-existent profile URL | 200 with an empty template | Returns 404 or redirects to a URL that does? |
Colour the cells: green if the field is in the raw HTML, amber if it only appears in the rendered view, red if it is absent from both. The red and amber cells are your work list.




