The customer portal went live in March. It works, people use it, nobody complains. In October someone in marketing searches Google for one of the products, and the top result is a distributor's listing. The company's own page isn't there. In Search Console, a good share of the URLs show as not indexed, and when someone asks an AI assistant about the company, it answers with whatever the old site used to say.
In custom web development this problem usually has one cause: the application ships an almost empty HTML document and relies on the visitor running JavaScript to see anything. A browser does that without trouble. Google does too, but there's a queue involved and a few conditions. Several AI crawlers don't do it at all. If you're still choosing an architecture, we compare the options in SPA, SSR or static site. This article is for the other situation: the application is already in production, it doesn't show up in search, and you need to decide what to fix first.
First, confirm that JavaScript is the problem
Not every site missing from Google has a rendering problem. Before you touch the architecture, run three checks. They take less than half an hour.
- Open a public page and view the source (Ctrl+U), not the browser's inspector. The inspector shows the DOM after JavaScript has run; the source shows what a bot that doesn't run it receives. If the
<body>holds little more than<app-root></app-root>and a couple of scripts, that's where you start. - Use the URL Inspection tool in Search Console and test the live URL. According to Google's guide to fixing JavaScript problems, it shows loaded resources, console errors and the rendered HTML. If the rendered version doesn't have your content either, Google isn't seeing it.
- Turn JavaScript off in your browser and click around. Whatever doesn't show up that way doesn't exist for a crawler that won't run code.
| What you find | What it probably means |
|---|---|
| Empty source, complete Google rendering | Google sees you, just late. Other bots don't. |
| Empty source, Google rendering also empty or full of errors | Rendering is failing: blocked resources, JS errors or an API that doesn't respond. |
| Complete source, page still not indexed | Rendering isn't the issue. Check noindex, canonicals, internal links and content quality. |
The SPA mistakes we see most
When the checks point at JavaScript, one of these is almost always involved, and several can be fixed without rebuilding anything.
- Links that aren't links. Google says that, generally, it can only crawl a link if it's an
<a>element with anhrefattribute. A button or a<span>with a click handler works for the user, but Google won't follow it as a link. - Routes with
#. An SPA that loads different views atexample.com/#/productshas a single URL as far as Google is concerned. The official advice is to use the History API so each view gets its own URL. - Everything returns 200. If a route that doesn't exist returns a 200 status and a "not found" page drawn by JavaScript, Google treats it as a soft 404 and may index error pages. Either redirect to a URL that really returns 404 or add
noindexin those cases. - A
noindexin the initial HTML. Google queues pages with a 200 status for rendering unless a robots tag tells it not to index (JavaScript SEO basics). If the starting HTML carriesnoindexand JavaScript removes it later, that JavaScript never gets to run for Google. - JavaScript blocked in
robots.txt. Google doesn't render JavaScript from blocked files. An old rule excluding/assets/or/static/leaves the page blank for the renderer. - Content that depends on state. Google's renderer clears local storage, session storage and cookies between page loads. If content only appears after the user picks a region or accepts something, Google gets the version where nothing was picked.
- File names without fingerprints. Google caches resources aggressively and may use stale JavaScript. Names like
main.2bb85551.js, which change with every release, avoid that. Check that your production build generates them.
Google isn't the only one reading your site
Google runs JavaScript, but part of search now happens through AI assistants that read sites with their own crawlers.
In an analysis Vercel published in December 2024 of traffic across its network, none of the major AI crawlers it measured executed JavaScript. That included OpenAI's (GPTBot, OAI-SearchBot, ChatGPT-User) and Anthropic's ClaudeBot. They downloaded .js files (11.5% and 23.8% of their requests, respectively) but didn't run them. The study is nearly two years old and these companies change their crawlers without much notice, so treat it as a reference point rather than a fixed rule.
For an SPA the consequence is concrete: if the product name, price or service description only exists after code runs, that assistant has nowhere to get it from.
Four ways out, depending on how much you want to change
| Option | What it involves | When it fits |
|---|---|---|
| Fix the SPA | Real routes, links with href, correct HTTP codes, per-route titles, a reviewed robots.txt | Few public pages, most of the system behind a login |
| Prerender public routes | HTML for those pages is generated at build time and published as files | Public content that rarely changes: services, blog, docs |
| SSR or hybrid rendering | A server builds the HTML for public routes on each request | Catalogs with prices or stock that change often and still need to rank |
| Split in two | A static public site, with the private application as an SPA | When the marketing site and the platform move at different speeds, with different teams |
One option we don't recommend is dynamic rendering, which means serving bots a prerendered version and people the SPA. Google describes it as a workaround it doesn't recommend, because of the complexity and resources it adds.
The first row is usually the first step whatever you choose. Prerendering or moving to SSR won't fix a link without href or a 200 on an error page.
What we did with our own site
We went through this at Disrupsoft. Our previous site was assembled in the browser, and the blog and service pages relied on JavaScript to show their content. We moved to pages generated at build time, and now every article arrives with complete HTML, its title and its description in the server's first response.
In a migration like that, the framework isn't what takes the most work. The inventory is: listing every URL that existed, deciding which ones stay, redirecting the ones that change and confirming in Search Console that Google sees the same thing a visitor does. If you're planning something similar, start there.
How to check it's fixed
After the change, repeat the checks from the start. The page source should show the content, and URL Inspection shouldn't report resource errors. Also:
- Submit a sitemap with the real URLs and make sure it has no
#routes or error pages. - Watch the Search Console indexing report over several weeks, not a few days. Reindexing takes time.
- Measure Core Web Vitals before and after. The thresholds, and how to write them into a contract, are in custom web development in Chile.
Frequently asked questions
Does Google index an SPA built with Angular or React?
It can. Google runs JavaScript, but pages go through a rendering queue and have to meet some conditions: real URLs, links with href, correct HTTP codes and unblocked resources. If the page needs to rank, serving HTML that's already built is the safer bet.
Do I have to rewrite the application to show up on Google?
Almost never. The usual path is to fix routes, links and HTTP codes, then prerender or server-render only the public pages. The private area can stay an SPA.
Do AI assistants read my site the way Google does?
Not necessarily. A Vercel study from December 2024 found that the OpenAI and Anthropic crawlers it measured didn't execute JavaScript. If your content only exists after code runs, those crawlers get an empty page.
Let's look at your application
At Disrupsoft we build custom web applications with Angular, Node.js, Azure and Power Platform. If your platform works well for users but doesn't show up in search, we can help you find the cause and scope the smallest change that fixes it. Let's talk about your custom development project.



