Hướng dẫn về JavaScript SEO

Cách hãy bảo đảm các công cụ tìm kiếm có thể crawl, render, và chỉ mục JavaScript-phụ thuộc nội dung — real links, parity, lazy-loading, infinite scroll, soft-404s, và kiểm thử.

Xuất bản lần đầu: 23 thg 6, 2026 · Cập nhật lần cuối: 8 thg 8, 2026 · Advanced
Ngôn ngữ
1 tín hiệu bằng chứng trên trang này

JavaScript SEO là về liệu các công cụ tìm kiếm có thể crawl, render, và chỉ mục nội dung đó phụ thuộc vào JavaScript. Google có thể chạy JS — đó các chế độ lỗi là hơn cụ thể: parity (thô so với được kết xuất), interaction (Google không scroll hoặc nhấp), state (đó renderer là stateless), và timing. Giữ links as real anchors, không block JS/CSS, ưu tiên SSR/prerendering cho nội dung đó phải xếp hạng, và watch infinite scroll — một tall render viewport có thể nhận hai các trang được lập chỉ mục as một.

TL;DR — Google có thể chạy của bạn JavaScript, so “can Google read JS?” (bản dịch) «có thể Google đọc JS?» là đó sai câu hỏi. Đó các chế độ lỗi là parity (thô so với. được kết xuất DOM), interaction (Google không scroll hoặc nhấp), state (đó renderer là stateless), và timing. Giữ links as real <a href> anchors, không block JS/CSS, lazy-load on viewport không interaction, trả về real statuses cho client-side 404s, và remember một thô noindex có thể ngăn kết xuất trước JavaScript có thể xóa điều này. Combine directives đó đã là thực ra processed, nhưng không assume một universal thô/được kết xuất winner. Watch infinite scroll especially: một tall render viewport có thể trigger đó loader và hợp nhất hai URLs vào một được lập chỉ mục trang. Cho đó renderer internals và mà kết xuất chế độ để pick, see kết xuất.

có thể Google đọc JavaScript? Có — đó không câu hỏi

Google can run your JavaScript — the real risks are parity, interaction, state, and timing. Nguồn: /technical-seo/javascript-seo/

Three stages run left to right: crawl, render, and index. The render stage branches into four failure modes: parity, where the rendered DOM may not match expectations; interaction, where content requires a scroll or click; state, where content relies on cookies or storage that the renderer clears; and timing, where content is deferred behind slow JavaScript.

© Patrick Stox LLC · CC BY 4.0 ·

Google xử lý JavaScript apps trong three phases: “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” (bản dịch) «Google xử lý JavaScript web apps trong three main phases: 1. Crawling 2. Kết xuất 3. Lập chỉ mục.» Đó middle phase chạy của bạn JS trong an evergreen, headless Chrome để xây dựng đó DOM đó nhận được lập chỉ mục. “Rendering is important because websites often rely on JavaScript to bring content to the page, and without rendering Google might not see that content.” (bản dịch) «Kết xuất là quan trọng vì websites thường rely on JavaScript để bring nội dung để đó trang, và không có kết xuất Google có thể không see đó nội dung.»

Evidence for this claim Google processes JavaScript web apps in three main phases: crawling, rendering, and indexing; without rendering, Google might not see JavaScript-provided content. Scope: Google Search's processing of JavaScript pages; successful rendering does not guarantee indexing or ranking. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

So Google có thể chạy của bạn JavaScript. hữu ích các câu hỏi là nhiều hơn cụ thể:

  • Parity — làm được kết xuất DOM thực ra contain Điều gì bạn think nó làm?
  • Interaction — làm bất cứ điều gì require scroll/nhấp Google sẽ không perform?
  • State — là bạn relying on cookies/localStorage stateless renderer clears?
  • Timing — là cốt yếu nội dung deferred behind chậm hoặc muộn JavaScript?

On timing cụ thể: Google queues một được crawl trang (một đó đã trả về một 200) cho kết xuất, và “the page may stay on this queue for a few seconds, but it can take longer than that.” (bản dịch) «đó trang có thể stay on này queue cho vài seconds, nhưng điều này có thể take lâu hơn đó.» có không published fixed delay hoặc timeout — và một trang đó trả về một non-200 status, hoặc đó bắt đầu out với một noindex directive, có thể skip đó render queue thay vì chờ cho JavaScript để thay đổi điều này.

Evidence for this claim Google queues crawled pages with a 200 response for rendering; the page may stay in that queue for a few seconds but can take longer, with no published fixed delay or timeout, and non-200 or initial noindex responses may skip rendering. Scope: Google Search's documented render-queue behavior; not a guaranteed or universal timing figure. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

mechanics của Cách Google renders — Web Kết xuất Service, statelessness, bộ nhớ đệm, “hai waves” myth — trực tiếp on kết xuất trang. Ở đây I’ll focus on practical các vấn đề và các cách sửa.

Này là đó single hầu hết phổ biến JS-SEO bug. “Google can only discover your links if they are <a> HTML elements with an href attribute.” (bản dịch) «Google có thể chỉ discover của bạn links nếu they là <một> HTML elements với an href thuộc tính.» MỘT clickable <div> với an onclick handler là invisible để Google as một link — điều này sẽ không là followed, và các trang đó phụ thuộc on điều này cho phát hiện có thể go uncrawled. đây là perfectly fine để inject links với JavaScript, miễn là they end lên as real <a href> anchors trong đó được kết xuất DOM. Những được kết xuất anchors là parsed sau JavaScript chạy, though — landing trong đó được kết xuất DOM làm một link discoverable, đây là không một promise đó URL nhận được crawl, được lập chỉ mục, hoặc treated đó giống nhau as một link present trong đó thô HTML.

Evidence for this claim Google can reliably discover links only when they are HTML anchor elements with an href attribute. Scope: Link discovery by Google Search; this does not claim that every discovered URL will be crawled or indexed. Confidence: high · Verified: Google Search Central: Make your links crawlable

Lazy-loaded và interaction-gated nội dung

Đó renderer không behave như một curious người dùng: “Google Search does not interact with your page.” (bản dịch) «Google Search không interact với trang của bạn.» Không scrolling, không clicking, không hovering. So bất kỳ nội dung đó chỉ loads on một of những events sẽ không là seen.

Google hướng dẫn: load nội dung khi điều này enters đó viewport, không khi người dùng acts — “make sure that your lazy-loading implementation loads all relevant content whenever it is visible in the viewport,” (bản dịch) «hãy bảo đảm đó của bạn lazy-loading implementation loads all relevant nội dung bất cứ khi nào điều này là visible trong đó viewport,»“don’t add lazy-loading to content that is likely to be immediately visible when a user opens a page.” (bản dịch) «không thêm lazy-loading để nội dung đó có khả năng là immediately visible khi một người dùng opens một trang.» Dùng IntersectionObserver hoặc native loading="lazy" cho images — không bao giờ một scroll hoặc nhấp handler — so đó nội dung loads during một thông thường render.

Evidence for this claim Google Search does not interact with a page, so lazy-loaded content should load when it becomes visible in the viewport rather than requiring user interaction. Scope: Google Search's documented rendering behavior for lazy-loaded content; other crawlers can behave differently. Confidence: high · Verified: Google Search Central: Fix lazy-loaded content

Infinite scroll: Khi hai các trang nhận được lập chỉ mục as một

Google's tall render viewport can trigger an infinite-scroll loader and merge two pages into one indexed URL. Nguồn: /technical-seo/javascript-seo/

A normal browser viewport stops after the first page, but Google's render viewport expands much taller. The expansion reaches an infinite-scroll trigger, fires the loader without a real user scroll, and appends the next page into the same DOM. Google then indexes both pages' content under one URL.

© Patrick Stox LLC · CC BY 4.0 ·

Đây là một gần như không ai giải thích, và nó worth toàn bộ section.

Googlebot có thể render tại một viewport considerably taller hơn một typical trình duyệt window. Google không publish an chính xác render viewport size — và điều này có thể thay đổi — so không design so với một cụ thể number; kiểm thử của bạn own implementation thay vì. Điều gì matters là đó mechanism: nếu của bạn infinite-scroll loader fires dựa trên scroll position hoặc viewport height, một taller-hơn-dự kiến kết xuất viewport có thể trigger đó loader during kết xuất itself — và đó tiếp theo bài viết hoặc sản phẩm trang nội dung nhận appended vào đó giống nhau DOM. Hiện tại hai distinct URLs’ nội dung đã được kết xuất together, và Google có thể chỉ mục them as một trang. Trong my own experience, “occasionally, two pages get indexed as one” (bản dịch) «occasionally, hai các trang nhận được lập chỉ mục as một» — I’ve đã có các trang reported as “không được lập chỉ mục” đó đã là thực ra được lập chỉ mục as part of một sản phẩm khác trang (thường đó trước đó post trong đó feed), vì “when Google resized the viewport to be longer … it triggered the infinite scroll and loaded another article in when it was rendering.” (bản dịch) «khi Google thay đổi kích thước viewport thành dài hơn … thao tác đó đã kích hoạt infinite scroll và tải thêm một bài viết trong lúc kết xuất.» Xác nhận liệu của bạn own setup làm này by kiểm tra URL Inspection được kết xuất HTML cho một trang bạn’d expect để dừng ngắn — không assume một size và không assume bạn là safe.

có hai layers để getting điều này right.

Làm infinite scroll tìm kiếm-friendly ngay từ đầu. Hỗ trợ paginated loading underneath đó infinite scroll. Mỗi chunk nên có “its own persistent, unique URL,” (bản dịch) «của nó own persistent, unique URL,» đó nội dung on mỗi URL nên stay đó giống nhau mỗi time điều này loads, bạn nên tránh relative parameters như ?date=yesterday, bạn nên “link sequentially to the individual URLs so that search engines can discover the URLs in a paginated set,” (bản dịch) «link sequentially để đó riêng lẻ URLs so đó các công cụ tìm kiếm có thể discover đó URLs trong một paginated set,» và khi một new chunk loads on scroll bạn nên “update the displayed URL using the History API.” (bản dịch) «cập nhật đó displayed URL dùng đó History API.» Dùng real <a href> pagination links và unique URLs — “don’t use URL fragment identifiers” (bản dịch) «không dùng URL fragment identifiers» (đó part sau một #) cho trang numbers, vì Google bỏ qua them. As I chẳng hạn trong my JavaScript SEO hướng dẫn, “if you have an infinite scroll setup, I still recommend a paginated page version so that Google can still crawl properly.” (bản dịch) «nếu bạn có an infinite scroll setup, I vẫn khuyến nghị một paginated trang version so đó Google có thể vẫn crawl properly.»

Nếu một buggy loader là actively merging các trang, đó fastest cách sửa là blunt: “block the JavaScript file that handles the infinite scrolling so the functionality can’t trigger.” (bản dịch) «block đó JavaScript tệp xử lý infinite scroll để chức năng đó không thể’t trigger.» Nếu đó loader không thể chạy during render, điều này không thể append đó tiếp theo trang nội dung, và mỗi URL renders as itself again.

Soft-404s sau khi client-side routing

Single-trang apps có thể đổi nội dung không có thay đổi đó HTTP mã trạng thái, so một “không tìm thấy” view có thể vẫn trả về 200. Google có thể classify đó phản hồi as một soft 404 sau evaluating đó đã trả về nội dung, nhưng một static fetch alone không thể prove đó Google có đã làm đó classification. Hai các cách sửa: navigate với đó History API, và cho một genuine không-được tìm thấy state either route để một URL đó trả về một real 404 status hoặc thêm một noindex tag. Và không lean on URL fragments cho routing — “the AJAX-crawling scheme has been deprecated since 2015, so you can’t rely on URL fragments to work with Googlebot.” (bản dịch) «đó AJAX-crawling scheme đã được deprecated since 2015, so bạn không thể rely on URL fragments để hoạt động với Googlebot.»

client-side chuyển hướng có giống nhau evidence vấn đề: ban đầu phản hồi có thể vẫn 200 cho đến khi JavaScript chạy. Google hỗ trợ JavaScript các chuyển hướng chỉ as fallback Khi máy chủ-side hoặc meta-refresh các chuyển hướng không phải có thể. Báo cáo static status và observed được kết xuất navigation riêng; không rewrite HTTP status trong audit hoặc call mỗi được kết xuất URL thay đổi chuyển hướng.

không block JavaScript hoặc CSS trong robots.txt

Google sẽ không render JavaScript từ blocked files hoặc on blocked các trang. robots.txt rule đó disallows của bạn bundle (hoặc /_next/, /static/, /assets/ directory nó lives trong) có thể break kết xuất hoàn toàn — Google fetches shell, có thể’t chạy scripts, và indexes trang rỗng. kiểm tra URL Inspection trang các tài nguyên cho bất cứ điều gì blocked.

DOM parity và stage-aware robots directives

So sánh của bạn thô HTML (View Nguồn) so với được kết xuất HTML (URL Inspection). nội dung đó chỉ tồn tại trong được kết xuất HTML vẫn indexes — nếu nó renders. nội dung trong neither không exist để Google.

có một stage-order risk Google documents trực tiếp: “When Google encounters the noindex tag, it may skip rendering and JavaScript execution, which means using JavaScript to change or remove the robots meta tag from noindex may not work as expected.” (bản dịch) «Khi Google encounters đó noindex tag, điều này có thể skip kết xuất và JavaScript execution, mà có nghĩa là dùng JavaScript để thay đổi hoặc xóa đó robots meta tag từ noindex có thể không hoạt động as dự kiến.» Nếu của bạn thô HTML ships an ban đầu noindex bạn meant để đổi out với JavaScript, Google có thể act on đó thô noindex và không bao giờ chạy đó script đó sẽ có đã xóa điều này.

Không turn này vào một universal “rendered wins” (bản dịch) «được kết xuất wins» rule. Reconciliation là trường-cụ thể:

TrườngĐiều gì thô/được kết xuất so sánh có thể establish
Main nội dung và linksGoogle có thể sử dụng nội dung và thực <a href> links produced during kết xuất nếu kết xuất succeeds. Thô availability reduces đó dependency.
Tiêu đề và mô tảGoogle có thể xử lý JavaScript-đặt metadata, nhưng tiêu đề links và snippets là được chọn từ several sources. hiển thị cả hai trạng thái; không claim được kết xuất, đầu tiên, hoặc cuối cùng giá trị là guaranteed.
Robots directivesthô noindex có thể nguyên nhân Google để skip kết xuất, so JavaScript removal có thể không bao giờ là seen. Thêm restrictions sau đó không phải evidence đó trước đó restriction là cancelled.
CanonicalGoogle JavaScript hướng dẫn nói không để đặt một giá trị trong nguồn và sau đó thay đổi nó với JavaScript. sử dụng một phương thức và verify một được kết xuất-head declaration.
HTTP status và chuyển hướngJavaScript không thể thay đổi phản hồi status đã nhận. Record static status và bất kỳ observed được kết xuất navigation as tách biệt facts.

đó matrix là Vì sao auditor nên giữ nguồn, được kết xuất, phản hồi-header, và observed-tìm kiếm state distinct thay vì collapsing them vào một “effective” giá trị.

Pick kết xuất chế độ đó diễn đạt nội dung trong DOM

Hầu hết JS-SEO risk xuất hiện xuống để cách đó HTML là produced. Phiên bản ngắn gọn: SSR, static/prerendering, và hydration all put nội dung trong (hoặc quickly vào) đó DOM, mà reduces cách nhiều của bạn visibility phụ thuộc vào đó renderer succeeding; đầy đủ client-side kết xuất leaves hơn riding on kết xuất completing correctly, on time, mỗi khi. Dynamic kết xuất là một workaround, không một peer option — as of Google hướng dẫn cuối cùng đã cập nhật December 2025, điều này mô tả dynamic kết xuất as một workaround thay vì một dài-term giải pháp và khuyến nghị máy chủ-side kết xuất, static kết xuất, hoặc hydration thay vì. As I put điều này trong my JavaScript SEO hướng dẫn, “any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines.” (bản dịch) «bất kỳ kind of SSR, static kết xuất, và prerendering setup là going để là fine cho các công cụ tìm kiếm.» Đó đầy đủ menu — CSR, SSR, SSG, hydration, ISR, edge, streaming, và dynamic kết xuất — với một trade-off bảng là on đó kết xuất trang. Google riêng mô tả máy chủ-side kết xuất hoặc pre-kết xuất as một good ý tưởng cho người dùng và các crawler. Evidence for this claim Google describes server-side rendering or pre-rendering as a good idea because it makes a website faster for users and crawlers. Scope: Google Search guidance for JavaScript sites; the source does not prescribe one framework or guarantee indexing. Confidence: high · Verified: Google Search Central: Understand the JavaScript SEO basics

Cách kiểm thử

URL Inspection trong Search Console là nguồn của truth: chạy trực tiếp kiểm thử, sau đó xem xét được kết xuất HTML, screenshot, và trang các tài nguyên / console messages để see Điều gì loaded và Điều gì thất bại. Rich Kết quả Kiểm thử cho nhanh được kết xuất-HTML kiểm tra. Tại quy mô, sử dụng crawler đó executes JavaScript (Ahrefs trang web Audit, Screaming Frog trong JS-kết xuất chế độ) để diff thô so với. được kết xuất trên trang web.

A render diff is diagnostic, not a score: investigate essential elements that appear only after JavaScript—or disappear after rendering.

An illustrative page has 1 title in both raw and rendered HTML, 18 headings in raw HTML and 19 rendered, 42 internal links in raw HTML and 71 rendered, 0 product descriptions in raw HTML and 12 rendered, and 6 canonical tags in raw HTML but only 1 rendered. These counts are synthetic.

JavaScript không phải bad Đối với SEO, và nó không evil. nó chỉ khác từ Điều gì nhiều SEOs là được sử dụng để. Hoạt động với của bạn nhà phát triển, nhận của bạn quan trọng nội dung vào DOM, và let Google own tools — không của bạn assumptions — là arbiter của Điều gì được kết xuất.

nơi để go tiếp theo: JavaScript SEO cluster

điều này hub là map. mỗi topic dưới là của nó own deep dive:

Kết xuất và architecture

  • SEO cho headless CMS — Cách decoupled frontends ảnh hưởng crawling, kết xuất, metadata, sitemaps, và canonical tags; mà kết xuất chế độ để pick; và headless-cụ thể thất bại modes bạn cần know.

Framework-cụ thể các hướng dẫn

  • React SEO — Vì sao CSR-đầu tiên React tạo lập chỉ mục risk, Cách Google renders React apps, React Router và History API, react-helmet-async cho meta tags, và Khi để reach cho tiếp theo.js.
  • Angular SEO — Angular SPA defaults, @angular/ssr (Angular Universal successor), được xây dựng-trong Tiêu đề và Meta services, prerendering, và incremental hydration trong modern Angular.
  • tiếp theo.js SEO — các trang Router so với App Router, Metadata API, next/image và CWV, ISR timing và Googlebot, sitemaps, và phần lớn phổ biến tiếp theo.js SEO mistakes.
  • Nuxt SEO — SSR theo mặc định, useSeoMeta(), Nuxt kết xuất modes, @nuxtjs/seo module ecosystem, và Cách Nuxt compares để đơn giản Vue cho indexability.
  • Vue SEO — Vue 3’s CSR default và Điều gì đó có nghĩ là cho các crawler, createWebHistory(), @unhead/vue, prerendering options không có meta-framework, và Khi Nuxt là right call.
  • Svelte SEO — Svelte so với SvelteKit, SSR theo mặc định trong SvelteKit, <svelte:head>, adapter-static + ssr: false trap, adapter choices, và AI crawler implications.
  • Astro SEO — zero-JS theo mặc định, islands architecture, @astrojs/sitemap, astro:assets, View Transitions và History API, máy chủ Islands fallback behavior, và Astro Core Web Vitals advantages.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.