This article is published in English.
Technical SEO Pitfalls in Modern JavaScript Frontends
Client-only rendering, flaky metadata, semantics, CWV, robots mistakes, and dynamic routes — fixes for engineering teams.
Nine technical SEO mistakes in modern JS apps
React, Vue, and Next make rich apps easy — and make it easy to ship HTML that crawlers struggle with. SEO is engineering, not only copywriting.
1. Client-only rendering
<div id="root"></div>
<script src="app.js"></script>
If the first response is an empty shell, some bots see nothing useful. Prefer SSR/SSG or hybrid rendering for public content.
2. Missing or flaky metadata
export default async function ProductPage() {
const product = await getProduct();
return (
<main>
<h1>{product.name}</h1>
<p>{product.description}</p>
</main>
);
}
Titles and descriptions must be stable per URL. Generating them only in useEffect is a classic footgun.
3. Ignoring semantic HTML
<title>My Application</title>
<meta name="description" content="Welcome to my app">
Headings, landmarks, and meaningful elements help both a11y and crawlers. Div soup hides structure.
4. Broken client navigation assumptions
export const metadata = {
title: "Modern React Performance Guide",
description:
"Learn practical techniques for improving React application performance.",
};
Ensure each shareable view has a real URL and that soft navigation updates metadata.
5. No structured data
<div>
<div>Article Title</div>
<div>Article content</div>
</div>
JSON-LD for articles, products, and FAQs can improve rich results when it matches visible content.
6. Weak Core Web Vitals
<article>
<header>
<h1>Technical SEO Mistakes</h1>
</header>
<section>
<p>Article content...</p>
</section>
</article>
Huge JS bundles and late images tank LCP/INP. Code-split, optimize media, and measure field data.
7. Accidentally blocking crawlers
<Link href="/products/react-course">
React Course
</Link>
Misconfigured robots.txt, noindex on prod, or auth walls on marketing pages wipe rankings overnight.
8. Dynamic routes without crawl strategy
<button onClick={() => navigate("/products/react-course")}>
React Course
</button>
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Technical SEO Mistakes Developers Make",
"author": {
"@type": "Person",
"name": "Developer"
}
}
Sitemaps, stable slugs, and server-rendered detail pages matter when IDs are infinite.
9. Treating SEO as marketing later
const Chart = dynamic(() => import("./Chart"), {
ssr: false,
});
<meta name="robots" content="noindex">
Bake metadata, rendering mode, and performance budgets into the definition of done.
Fixes worth repeating
Disallow: /
/products/item-123
/blog/article-name
/users/profile-name
Ship crawlable HTML, unique metadata, semantics, sitemaps, and performance budgets — then let content teams do their job on a foundation that works.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.
Prefer small examples readers can paste into a sandbox without a monorepo.