Engineering

Technical SEO for Web Applications: What Actually Moves Rankings

Most SEO advice is written for content sites. Applications fail differently, and usually for reasons no keyword tool will ever show you.

10 min read Plexowave

When a web application does not rank, the cause is rarely the content. It is that the crawler received an empty page, or found four URLs holding the same thing, or spent its crawl allowance on faceted filter combinations, or was told by a stray directive not to index the page at all. None of these appear in a keyword report, and all of them need someone who can change the code.

Start with what the crawler actually receives

The single most useful habit in technical SEO is to stop looking at the page in a browser. Fetch the raw HTML the server returns and read that. It is routinely a different document from the one you see.

For client-rendered applications it may be an empty shell with a script tag. Google does render JavaScript, but rendering is queued separately from crawling and is not guaranteed to be prompt or complete - and other crawlers, including the ones behind social previews and several AI systems, render far less reliably or not at all.

The fix is to serve the content in the initial HTML for any page you want ranked. Server-side rendering, static generation or prerendering all achieve this; which one you choose is an architecture decision, but the requirement is not negotiable if search matters.

Duplicate URLs are the quiet killer

Applications generate URL variants effortlessly: tracking parameters, session identifiers, sort and filter combinations, trailing-slash variants, uppercase paths, and the same page reachable from two routes. Each variant is a separate URL to a crawler, and the ranking signals split between them.

Three things resolve it. Every page needs a self-referencing canonical pointing at the version you want indexed. The server should redirect variants - non-canonical host, wrong protocol, inconsistent trailing slash - with a permanent redirect rather than serving all of them. And parameters that do not change the content should not produce a distinct indexable URL.

The most common mistake here is a canonical that disagrees with the sitemap, or a canonical pointing at a URL that redirects. Both are treated as confused signals, and confusion resolves against you.

Crawl budget is real once you have filters

For a fifty-page site, crawl budget is not your problem. For an application with faceted navigation it is one of the first problems, because a handful of filters produce a combinatorial explosion of URLs and a crawler will happily spend weeks on them instead of on the pages that matter.

Decide explicitly which filter combinations deserve to be indexed - usually the ones with genuine search demand, such as a category plus one attribute - and make the rest non-indexable. Use robots.txt to stop crawling of parameter patterns that have no value, and a noindex directive for pages that must remain crawlable for their links but should not appear in results.

Those two are not interchangeable, and confusing them is common: a page blocked in robots.txt cannot be crawled, so its noindex is never seen, and the URL can still appear in results on external signals alone. If you want a page out of the index, it must be crawlable and carry noindex.

Core Web Vitals, measured in the field

Performance is a ranking factor, and more importantly it is a conversion factor. The mistake is optimising against a lab score on a fast machine instead of against what real users experience.

For Largest Contentful Paint the usual culprits are an image that is not preloaded, a font that blocks text from painting, and a render-blocking stylesheet. Preload the element that will be largest, use font-display so text appears immediately in a fallback, and inline the styles needed for the first screen.

Cumulative Layout Shift almost always comes from images and embeds without dimensions, from content injected above existing content, and from web fonts that reflow on swap. Set explicit width and height, reserve space for anything that arrives late, and match fallback font metrics.

Interaction to Next Paint is the one applications fail most, because it measures responsiveness under a heavy JavaScript main thread. Break up long tasks, do less work on the main thread, and be honest about how much framework is genuinely needed on a page whose job is to display information.

Structured data that reconciles

Structured data does not directly raise rankings, but it determines how a result is displayed and how confidently a search engine resolves what your site is about. The common failure is not invalid markup - it is markup that contradicts itself across pages, describing the same organisation three different ways.

Use one identified organisation node and have every other block reference it, rather than restating the company on each page. Validate in the build rather than by pasting into a testing tool occasionally, so a regression fails the build instead of quietly shipping.

Do not mark up reviews you have not collected, ratings you have aggregated from nothing, or FAQs that do not appear on the page. These attract manual actions, and the rich result is not worth the risk.

Internationalisation, where it usually goes wrong

If you serve multiple languages, hreflang tells search engines which version to show. It is also one of the easiest things to get subtly wrong.

  • Annotations must be reciprocal. If the English page points at the German one, the German page must point back, or the whole set is ignored.
  • Every URL in the set must return 200. One 404 in the cluster undermines it.
  • Each page's canonical must point at itself, not at the English version. A canonical to another language is a request to drop that page from the index.
  • Use x-default for the fallback when no language matches.
  • Do not machine-translate a page and mark it as a language alternate unless it is genuinely good. A thin or mangled translation is worse than not offering that language at all.

Measurement that survives a privacy-first web

A large share of visitors block client-side analytics, and the share is highest among technical audiences - which for a software product is the audience you most want to understand. Numbers from a blocked tag are not just incomplete, they are biased in a direction that matters.

Server logs and server-side measurement do not have this problem, and they also show you crawler behaviour, which client-side analytics never will. For a new site, watching Googlebot arrive in the logs is a more useful signal than any dashboard - it tells you whether you have a crawling problem or a ranking problem, which are fixed very differently.

Search Console remains the most valuable source, because it reports the queries you already appear for. Those queries are a better content brief than any keyword tool, because they show where you are close enough that a small improvement changes the outcome.

A practical order of work

  1. Verify indexability firstSearch Console, coverage report, and a crawl of your own site. There is no point optimising a page that is excluded.
  2. Fix renderingEnsure the content you want ranked is in the initial HTML response.
  3. Resolve duplicatesCanonicals, redirects and parameter handling, so signals concentrate rather than split.
  4. Control crawlDecide which generated URLs deserve indexing and stop the rest consuming crawl allowance.
  5. Then performanceField data, not lab scores, and fixed in the build pipeline so it cannot regress.
  6. Then contentWritten against the queries Search Console shows you are already close on.

That order matters. Content written for a page the crawler cannot see is wasted work, and performance tuning on a page that is excluded from the index changes nothing at all.

Questions

Common questions.

Does Google index JavaScript-rendered content?

Yes, but rendering happens in a separate queue from crawling, and it is neither immediate nor guaranteed to be complete. Other crawlers - social previews, several AI systems, smaller engines - render much less reliably. For anything you want ranked, serve the content in the initial HTML.

How long before technical fixes show up in rankings?

Indexing changes can appear within days. Ranking changes typically take weeks, and anything dependent on accumulating authority takes months. If someone promises top positions in a fixed short period, they are either targeting terms nobody searches or not being straight with you.

Is a sitemap still necessary?

It does not make pages rank, but it helps discovery on larger or poorly linked sites and gives you a coverage report worth reading. Keep it generated by the build so it cannot disagree with the site, and make sure every URL in it returns 200 and is canonical.

Should we use robots.txt or noindex to keep a page out of search?

noindex, and the page must stay crawlable for it to be seen. A page blocked in robots.txt can still be listed on external signals, because the crawler was never allowed to read the directive telling it not to.

Working through this decision?

Describe the problem rather than the solution. If the answer is a product you can buy, or no software at all, we will say so.

Start a project