Technical SEO for web applications is where good engineering and good marketing meet. A beautifully built single-page application can be close to invisible in search if its routes are not crawlable, its content only exists after JavaScript runs, or its pages take too long to become usable. The fixes are rarely glamorous, but they are decisions best made at the architecture stage rather than retrofitted after launch.
This guide is written for CTOs, product owners and developers who build web applications with frameworks such as React, Vue, Angular, Laravel, Django or ASP.NET Core. It covers how search engines discover and render pages, how to choose a rendering strategy, what the Core Web Vitals actually measure, and the supporting work around structured data, sitemaps, metadata and the newer llms.txt convention.
One principle runs throughout: search engines and AI systems can only rank, cite or recommend what they can reliably fetch, render and understand.
Technical SEO for web applications starts with crawling and rendering
Google describes its pipeline in three broad stages: crawling, rendering and indexing. A crawler requests a URL and receives the HTML response. If the page relies on JavaScript, it is queued for rendering in a headless browser, after which the rendered content can be indexed. Google’s Search Central documentation covers each stage in detail.
Three practical consequences follow for web applications:
- Links must be real links. Crawlers discover pages by following
<a href>elements. Navigation implemented with click handlers ondivorbuttonelements is not reliably followed. - Rendering is a separate, resource-limited step. Content that appears only after slow API calls, user interaction or scrolling may never be seen.
- Not every consumer renders JavaScript. Social media link previews, some search engines and many automated agents work largely from the initial HTML. If your important content is not in that HTML, they miss it.
Crawlability: URLs, routing and status codes
Crawlability problems in web applications usually come from client-side routing decisions made early and never revisited.
Use clean, stable URLs
Every piece of indexable content should have its own URL using the History API (for example /products/blue-widget), not a hash fragment such as /#/products/blue-widget. Fragments are generally treated as the same page, so hash-based routing collapses an entire application into a single indexable URL. Keep URLs lowercase, readable and permanent; when they must change, use 301 redirects.
Return honest HTTP status codes
A classic SPA problem is the “soft 404”: the server returns 200 OK for every route and the client renders “Page not found”. Search engines then index thousands of empty error pages. Your server or edge layer should know which routes exist and return 404 or 410 for those that do not, 301 for permanent moves and 503 during planned maintenance.
Control what gets indexed
- Use
robots.txtto stop crawlers wasting effort on endless filter combinations, internal search results and API endpoints. Remember it controls crawling, not indexing. - Use
noindex(meta tag orX-Robots-Tagheader) for pages that may be crawled but should not appear in results. The crawler must be able to fetch the page to see the directive. - Use
rel="canonical"to consolidate duplicate URLs created by tracking parameters, sorting options or pagination variants. - Keep authenticated areas such as dashboards and account pages behind login; they should not be indexable at all.
Choosing a rendering strategy for public pages
The single most important technical SEO decision for a JavaScript-heavy application is how its public pages are rendered. The options trade server cost and complexity against how quickly and reliably content appears.
| Strategy | How it works | SEO reliability | Best for |
|---|---|---|---|
| Client-side rendering (CSR) | Server sends an empty shell; JavaScript builds the page in the browser | Weakest; depends on crawler rendering | Logged-in dashboards and internal tools |
| Server-side rendering (SSR) | Server renders full HTML per request, then the app hydrates | Strong | Frequently changing, personalised-but-public pages |
| Static site generation (SSG) | HTML generated at build time and served from a CDN | Strong and fast | Marketing pages, documentation, blogs |
| Incremental or on-demand regeneration | Static pages regenerated after a set time or on content change | Strong | Large catalogues with periodic updates |
| Traditional server-rendered framework | Laravel, Django or ASP.NET Core render HTML templates | Strong | Content-led applications with light interactivity |
A sensible pattern for many products is a hybrid: statically generated or server-rendered marketing and content pages, with the authenticated application itself rendered on the client. Frameworks such as Next.js, Nuxt and Angular’s server-side rendering support make this straightforward to set up when it is planned from the start.
Google has described dynamic rendering, serving pre-rendered HTML only to bots, as a workaround rather than a long-term solution. If you inherit an application that depends on it, plan a migration to proper SSR or static generation as part of broader refactoring.
Core Web Vitals and performance
Core Web Vitals are Google’s user-experience metrics for loading, responsiveness and visual stability. They are measured from real Chrome users (field data) and assessed at the 75th percentile of page loads, so a fast developer laptop on fibre tells you little about a customer on a mid-range phone and a mobile connection. The current thresholds are documented on web.dev.
| Metric | What it measures | “Good” threshold | Common culprits in web apps |
|---|---|---|---|
| Largest Contentful Paint (LCP) | Loading: when the main content element renders | 2.5 seconds or less | Large unoptimised hero images, render-blocking scripts, slow server response, client-side data fetching |
| Interaction to Next Paint (INP) | Responsiveness to clicks, taps and key presses across the visit | 200 milliseconds or less | Long JavaScript tasks, heavy hydration, expensive re-renders, third-party scripts |
| Cumulative Layout Shift (CLS) | Visual stability: unexpected movement of content | 0.1 or less | Images without dimensions, late-loading banners and ads, web font swaps |
INP replaced First Input Delay (FID) as a Core Web Vital in March 2024. The change matters for web applications in particular: FID only measured the delay before the first interaction was handled, whereas INP considers responsiveness throughout the visit. Heavy single-page applications that felt fine under FID often struggle under INP.
Practical performance wins
- Ship less JavaScript: split bundles by route, lazy-load below-the-fold components and audit dependencies.
- Break up long tasks so the main thread can respond to input, and move heavy computation to web workers.
- Serve modern image formats at the right size, set explicit width and height, and preload the LCP image.
- Cache aggressively at the CDN and keep server response times low; slow back-ends delay everything else.
- Load third-party tags (analytics, chat, marketing pixels) deliberately, and remove the ones nobody uses.
Metadata, structured data and sitemaps
Per-route metadata
Each indexable route needs its own unique <title>, meta description, canonical URL and Open Graph tags, present in the server response rather than injected after load. A surprising number of SPAs ship the same title on every page because metadata was never wired into the router. For multilingual applications, add hreflang annotations so the right language version is shown to the right audience.
Structured data
Structured data uses the schema.org vocabulary, which Google recommends expressing as JSON-LD, to describe what a page represents: an organisation, a product with price and availability, an article, a breadcrumb trail, a software application or a local business. It helps search engines understand content and can make pages eligible for rich results. Generate it from the same data that renders the page so the two never disagree, validate it with Google’s Rich Results Test, and do not mark up content that users cannot see. Be aware that Google narrows eligibility for some rich result types over time; FAQ rich results, for example, are now shown only for a limited set of authoritative sites. Mark up content accurately because it helps understanding, not only for a visual reward.
XML sitemaps
An XML sitemap lists the canonical URLs you want indexed. For applications with dynamic content, generate it automatically from the database rather than maintaining it by hand. Each sitemap file is limited to 50,000 URLs or 50MB uncompressed, so large catalogues should use a sitemap index pointing to several files. Include accurate lastmod dates, exclude redirected, noindexed and non-canonical URLs, reference the sitemap in robots.txt and submit it in Google Search Console and Bing Webmaster Tools.
llms.txt and visibility in AI-driven search
People increasingly discover products and services through AI assistants and AI-generated search summaries. The fundamentals that help traditional search help here too: crawlable pages, content in the initial HTML, clear headings, accurate structured data and genuinely useful writing.
llms.txt is a proposed convention: a Markdown file at the root of your site (/llms.txt) that gives language models a concise overview of your organisation and links to your most useful pages, optionally with plain-text or Markdown versions of key documentation. It is not an official web standard, and major providers have not confirmed that they rely on it. Our view is pragmatic: it is cheap to produce, harmless and can be generated from your existing sitemap and content, so add it if you like, but do not let it distract from the fundamentals. Separately, review your robots.txt rules for AI crawlers so that what you allow or block is a deliberate business decision.
A technical SEO checklist for your next release
Build these checks into your definition of done and your QA process so that SEO regressions are caught before deployment, not months later in analytics:
- Every public page has a unique, clean URL and is reachable through standard anchor links.
- Key content and metadata are present in the initial HTML response.
- Unknown routes return a real 404; moved content returns a 301.
- Canonical tags, noindex directives and
robots.txtrules are deliberate and tested. - LCP, INP and CLS are monitored with field data, not only lab tests.
- Structured data is generated from page data and validates without errors.
- The XML sitemap is generated automatically and submitted to search consoles.
- Authenticated areas are not indexable.
- Analytics and Search Console are configured before launch so you have a baseline.
Automated tests can enforce several of these, for example asserting status codes, titles and canonical tags for a set of key routes in your end-to-end suite. Our article on building a QA testing strategy explains how to fit such checks into a wider test pyramid.
How Adriel Corp can help
At Adriel Corp, search visibility is part of how we build web applications, not an afterthought. In our Structuring Phase we decide which pages must be indexable and how they will be rendered, and performance is tested alongside functionality before anything is deployed. Our Web Application Starter gives new products a solid, search-friendly foundation, and for existing applications that are slow or poorly indexed, a Code Audit & Refactoring Sprint identifies and fixes the architectural causes.
If your web application deserves to be found, let’s talk about getting it there.