The body content on this page is in raw HTML. The internal links within the article — shown in the "Related pages" block below — are injected by JavaScript. They do not appear in view-source. To verify, open Command Prompt (Windows) or Terminal (Mac) and run: curl -L https://sallymills.com/seo-javascript-issues/links-loaded-javascript/ | grep '<a href' — you'll see only the nav links from the site template, not the article content links. (Windows: replace | grep '<a href' with | findstr "a href".)
What this demonstrates
The body content on this page — these headings and paragraphs — is present in raw HTML. What is not present in raw HTML is the set of internal links within the article body. The "Related pages" block in this article is rendered by JavaScript. In view-source, you will see a <div id="js-article-links"> that is empty. The links are injected into it by a DOMContentLoaded script.
This is a common real-world pattern: CMS-generated navigation blocks, "You might also like" sections, and related content widgets are often built as JavaScript components that inject their links after render. The page content is present, but the outgoing links are invisible to Wave 1.
Why it matters
PageRank and link equity flow through <a href> links discovered in raw HTML. Links found only in JavaScript are less reliable signals — discovered late (Wave 2), and historically weighted differently in Google's link graph. Pages linked exclusively through JavaScript may receive lower crawl priority and slower link equity pass-through.
At scale, this is a significant problem. If your site has a JavaScript-rendered navigation, a JS-injected breadcrumb, or link clusters added by JavaScript, any pages that are only linked from those JS elements may be crawled much less frequently than those linked via raw HTML links. Your internal linking strategy is being undermined by your rendering approach.
The issue is distinct from the client-side rendered demo: here the content is visible in Wave 1, but the outgoing links to other pages aren't. Googlebot knows what this page is about — it just can't follow the connections.
The code
The empty link container in raw HTML, and the JavaScript that populates it.
<!-- In raw HTML: content is present, but link container is empty -->
<p>Body content here — present in raw HTML.</p>
<div id="js-article-links"><!-- links injected by JavaScript --></div>
<!-- JavaScript injects the links after DOM load -->
<script>
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('js-article-links').innerHTML =
'<a href="/seo-javascript-issues/server-side-rendered/">Server-Side Rendered</a>' +
'<a href="/seo-javascript-issues/client-side-rendered/">Client-Side Rendered</a>' +
'<a href="/seo-javascript-issues/csr-ssr-mixed/">Mixed Rendering</a>';
});
</script>
<!-- Correct: put links in raw HTML -->
<a href="/seo-javascript-issues/server-side-rendered/">Server-Side Rendered</a>
What Google does
- Googlebot crawls this page and receives the full HTML response.
- Wave 1: body content is read — headings, paragraphs, meta tags all present in HTML.
- Wave 1: the
<div id="js-article-links">is empty. No<a href>links in the article content area. - Googlebot discovers only the links in the SSI-included nav and footer — not any article content links.
- The pages that would have been linked from the article content receive no crawl signal from this page on Wave 1.
- Wave 2: JavaScript executes, links are injected. Googlebot discovers and queues the linked pages — but with hours or days of delay compared to raw HTML links.
How to detect it
-
view-source
Ctrl+U(Windows) /Cmd+U(Mac) → search for<a hrefin the article content area. The "Related pages" block below shows as an empty<div id="js-article-links">. No links visible in the article content in raw source. -
curl
Open Command Prompt (Windows) or Terminal (Mac) and run:
curl -L https://sallymills.com/seo-javascript-issues/links-loaded-javascript/ | grep '<a href'→ Returns only nav and footer links from the SSI-included template. No links from the article content itself — those are in the empty JS container. (Windows: replace| grep '<a href'with| findstr "a href".) - Google Search Console Pages linked only via JavaScript from this page will not appear in the Links report attributing this page as their referring page, or will show with much lower link counts than expected. GSC's link data reflects Wave 1 and Wave 2 combined, but Wave 2 links are less reliably reported.
- Screaming Frog JavaScript rendering OFF → crawl this page → outlinks report shows zero or very few internal links from article content (only template nav links). JavaScript rendering ON → article links appear. The gap in outlink count between these two modes shows exactly how many links are JS-dependent.
How to fix it
Place internal links in raw HTML. "Related content" sections, navigation blocks, breadcrumbs, and any link clusters that matter for SEO should be rendered server-side. If the links are generated dynamically (e.g., based on categories or tags), the server should output them as <a href> tags in the HTML response — not inject them client-side.
If JavaScript-rendered links are unavoidable (e.g., truly dynamic personalised content), ensure the most important internal links are also present as static HTML links elsewhere on the page — in a static breadcrumb, in the footer, or in the main nav.