Panduan JavaScript SEO
cara pastikan mesin pencari dapat crawl, render, dan indeks JavaScript-dependent konten — nyata tautan, parity, lazy-memuat, infinite scroll, soft-404s, dan testing.
Bahasa
1 sinyal bukti di halaman ini
- Alat aktif terkaitRaw vs. Rendered HTML Checker
JavaScript SEO adalah tentang whether mesin pencari dapat crawl, render, dan indeks konten itu depends pada JavaScript. Google dapat run JS — failure modes adalah more spesifik: parity (raw vs rendered), interaction (Google doesn't scroll atau click), state ( renderer adalah stateless), dan timing. pertahankan tautan sebagai nyata anchors, don't block JS/CSS, prefer SSR/prerendering untuk konten itu harus peringkat, dan watch infinite scroll — sebuah tall render viewport dapat get two halaman terindeks sebagai one.
TL;DR — JavaScript SEO adalah tentang one pertanyaan: dapat mesin pencari see Anda konten? Modern situs bangun lot dari halaman di browser dengan JavaScript. jika Anda penting text dan tautan hanya tampilkan up setelah scripts run, Anda perlu confirm Google dapat masih reach them. Google biasanya dapat — trouble adalah di detail.
What JavaScript SEO adalah
Lots dari situs bangun bagian (atau semua) dari halaman di Anda browser dengan JavaScript. server mengirim beberapa HTML, dan lalu scripts run untuk fill di konten, muat more items, atau swap views without sebuah full halaman reload. JavaScript SEO adalah practice dari membuat sure mesin pencari dapat masih crawl, render, dan indeks itu konten.
Here’s order things happen di untuk Google:
- crawl — Google downloads raw HTML dari Anda URL.
- Render — Google runs halaman’s JavaScript di sebuah browser untuk bangun finished halaman ( rendering langkah).
- indeks — Google reads itu finished halaman dan files ini away.
Google documents ini sebagai three main phases untuk processing JavaScript web apps.
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 basicsjika Anda konten hanya appears setelah JavaScript runs, Google memiliki untuk render halaman successfully sebelum ini dapat see ini. sebagian besar dari time ini melakukan. When ini doesn’t, Anda konten dapat quietly go missing dari search.
baik news pertama
JavaScript adalah not buruk untuk SEO. Google runs sebuah up-untuk-date versi dari Chrome dan dapat execute yang sama JavaScript Anda pengunjung melakukan. old fear — “Google can’t read JavaScript” (terjemahan) “Google dapat’t read JavaScript” — hanya isn’t benar anymore.
What dapat go wrong adalah more spesifik:
- Anda konten perlu sebuah click atau sebuah scroll untuk muat, dan Google doesn’t click atau scroll. 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
- Anda tautan aren’t nyata tautan (mereka’re buttons atau click handlers), so Google dapat’t ikuti them. 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
- Anda accidentally blocked Anda JavaScript atau CSS files di
robots.txt, so Google dapat’t render halaman properly. - halaman looks fine di Anda browser, tetapi konten tidak pernah menampilkan up di Google’s rendered view.
sederhana checklist
- Compare Anda raw HTML (right-click → View Source) dengan rendered HTML (Google Search Console’s pemeriksaan URL alat). jika penting konten adalah missing dari rendered view, itu’s Anda masalah.
- pastikan tautan adalah nyata
<a href>tautan, not click handlers pada sebuah<div>. - Don’t block Anda JavaScript atau CSS files di
robots.txt. - jika sebuah fitur perlu sebuah click atau scroll untuk muat konten, pastikan itu konten adalah juga reachable beberapa lainnya cara.
- untuk konten itu absolutely harus peringkat, prefer rendering sisi server atau sebuah static/prerendered bangun, where konten adalah sudah di raw HTML.
ingin deeper versi — nyata failure modes, infinite-scroll trap itu gets two halaman terindeks sebagai one, dan cara test rendered HTML? Switch untuk Advanced tab. untuk how Google’s renderer itself berfungsi dan which rendering setup untuk choose, see rendering halaman.
TL;DR — Google dapat run Anda JavaScript, so “can Google read JS?” (terjemahan) “dapat Google read JS?” adalah wrong pertanyaan. failure modes adalah parity (raw vs. rendered DOM), interaction (Google doesn’t scroll atau click), state ( renderer adalah stateless), dan timing. pertahankan tautan sebagai nyata
<a href>anchors, don’t block JS/CSS, lazy-muat pada viewport not interaction, kembalikan nyata statuses untuk client-side 404s, dan remember sebuah rawnoindexdapat mencegah rendering sebelum JavaScript dapat hapus ini. Combine directives itu adalah actually processed, tetapi melakukan not assume sebuah universal raw/rendered winner. Watch infinite scroll terutama: sebuah tall render viewport dapat trigger loader dan merge two URLs ke one terindeks halaman. untuk renderer internals dan which rendering mode untuk pick, see rendering.
dapat Google read JavaScript? Yes — itu’s not pertanyaan
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 processes JavaScript apps di three phases: “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” (terjemahan) “Google processes JavaScript web apps di three main phases: 1. crawling 2. rendering 3. pengindeksan.” middle phase runs Anda JS di sebuah evergreen, headless Chrome untuk bangun DOM itu gets terindeks. “Rendering is important because websites often rely on JavaScript to bring content to the page, and without rendering Google might not see that content.” (terjemahan) “rendering adalah penting because situs web sering rely pada JavaScript untuk bring konten untuk halaman, dan without rendering Google mungkin not see itu konten.”
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 basicsSo Google dapat run Anda JavaScript. berguna pertanyaan adalah more spesifik:
- Parity — melakukan rendered DOM actually berisi what Anda think ini melakukan?
- Interaction — melakukan anything memerlukan sebuah scroll/click Google won’t perform?
- State — adalah Anda relying pada cookies/localStorage stateless renderer clears?
- Timing — adalah critical konten deferred behind slow atau late JavaScript?
pada timing specifically: Google queues sebuah di-crawl halaman (one itu dikembalikan sebuah 200) untuk
rendering, dan “the page may stay on this queue for a few seconds, but it can take
longer than that.” (terjemahan) “ halaman dapat stay pada ini queue untuk sebuah few seconds, tetapi ini dapat take
longer daripada itu.” There’s no published fixed delay atau timeout — dan sebuah halaman itu
mengembalikan sebuah non-200 status, atau itu starts out dengan sebuah noindex directive, dapat skip
render queue alih-alih wait untuk JavaScript untuk perubahan ini.
mechanics dari how Google renders — Web rendering Service, statelessness, caching, “two waves” (terjemahan) “two waves” myth — live pada rendering halaman. Here I’ll focus pada practical masalah dan fixes.
tautan harus menjadi nyata <a href> anchors
ini adalah single sebagian besar umum JS-SEO bug. “Google can only discover your links if
they are <a> HTML elements with an href attribute.” (terjemahan) “Google dapat hanya menemukan Anda tautan jika
mereka adalah <sebuah> HTML elements dengan sebuah href attribute.” sebuah clickable <div> dengan sebuah
onclick handler adalah invisible untuk Google sebagai sebuah tautan — ini won’t menjadi diikuti, dan halaman
itu depend pada ini untuk penemuan dapat go uncrawled. ini adalah perfectly fine untuk inject
tautan dengan JavaScript, sebagai panjang sebagai mereka end up sebagai nyata <a href> anchors di
rendered DOM. itu rendered anchors adalah parsed setelah JavaScript runs, though —
landing di rendered DOM membuat sebuah tautan discoverable, ini adalah not sebuah promise itu
URL gets di-crawl, terindeks, atau treated yang sama sebagai sebuah tautan present di raw HTML.
Lazy-dimuat dan interaction-gated konten
renderer doesn’t behave like sebuah curious pengguna: “Google Search does not interact with your page.” (terjemahan) “Google Search melakukan not interact dengan Anda halaman.” No scrolling, no clicking, no hovering. So apa pun konten itu hanya memuat pada one dari itu events won’t menjadi seen.
Google’s guidance: muat konten when ini enters viewport, not when pengguna acts —
“make sure that your lazy-loading implementation loads all relevant content whenever
it is visible in the viewport,” (terjemahan) “pastikan itu Anda lazy-memuat implementation memuat semua relevant konten whenever
ini adalah terlihat di viewport,” dan “don’t add lazy-loading to content that is
likely to be immediately visible when a user opens a page.” (terjemahan) “don’t tambahkan lazy-memuat untuk konten itu adalah
mungkin untuk menjadi immediately terlihat when sebuah pengguna opens sebuah halaman.” gunakan IntersectionObserver
atau native loading="lazy" untuk images — tidak pernah sebuah scroll atau click handler — so
konten memuat selama sebuah normal render.
Infinite scroll: when two halaman get terindeks sebagai one
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 ·
ini adalah one almost nobody menjelaskan, dan ini adalah worth whole bagian.
Googlebot dapat render di sebuah viewport considerably taller daripada sebuah typical browser window. Google doesn’t publish sebuah exact render viewport size — dan ini dapat perubahan — so don’t design terhadap sebuah spesifik angka; test Anda own implementation instead. What penting adalah mechanism: jika Anda infinite-scroll loader fires berdasarkan scroll position atau viewport height, sebuah taller-daripada-expected rendering viewport dapat trigger loader selama rendering itself — dan next artikel atau product halaman’s konten gets appended ke yang sama DOM. Now two distinct URLs’ konten memiliki telah rendered together, dan Google dapat indeks them sebagai one halaman. di my own experience, “occasionally, two pages get indexed as one” (terjemahan) “occasionally, two halaman get terindeks sebagai one” — I’ve memiliki halaman reported sebagai “not indexed” (terjemahan) “not terindeks” itu adalah actually terindeks sebagai bagian dari lainnya halaman (biasanya previous post di feed), because “when Google resized the viewport to be longer … it triggered the infinite scroll and loaded another article in when it was rendering.” (terjemahan) “when Google resized viewport untuk menjadi longer … ini triggered infinite scroll dan dimuat lainnya artikel di when ini adalah rendering.” Confirm whether Anda own setup melakukan ini oleh memeriksa pemeriksaan URL’s rendered HTML untuk sebuah halaman Anda’d expect untuk stop pendek — don’t assume sebuah size dan don’t assume Anda’re safe.
ada two layers untuk getting ini right.
membuat infinite scroll search-friendly di pertama place. mendukung paginated memuat
underneath infinite scroll. setiap chunk seharusnya memiliki “its own persistent, unique
URL,” (terjemahan) “-nya own persistent, unique
URL,” konten pada setiap URL seharusnya stay yang sama setiap time ini memuat, Anda harus
hindari relative parameters like ?date=yesterday, Anda harus “link sequentially to
the individual URLs so that search engines can discover the URLs in a paginated set,” (terjemahan) “tautan sequentially untuk
individual URLs so itu mesin pencari dapat menemukan URLs di sebuah paginated set,”
dan when sebuah baru chunk memuat pada scroll Anda harus “update the displayed URL using the
History API.” (terjemahan) “update displayed URL menggunakan
History API.” gunakan nyata <a href> pagination tautan dan unique URLs — “don’t use URL
fragment identifiers” (terjemahan) “don’t gunakan URL
fragment identifiers” ( bagian setelah sebuah #) untuk halaman angka, because Google ignores
them. sebagai I say di my JavaScript SEO guide, “if you have an infinite scroll setup, I still recommend a
paginated page version so that Google can still crawl properly.” (terjemahan) “jika Anda memiliki sebuah infinite scroll setup, I masih recommend sebuah
paginated halaman versi so itu Google dapat masih crawl properly.”
jika sebuah buggy loader adalah actively merging halaman, fastest fix adalah blunt: “block the JavaScript file that handles the infinite scrolling so the functionality can’t trigger.” (terjemahan) “block JavaScript file itu handles infinite scrolling so functionality dapat’t trigger.” jika loader dapat’t run selama render, ini dapat’t append next halaman’s konten, dan setiap URL renders sebagai itself again.
Soft-404s setelah client-side routing
Single-halaman apps dapat swap konten tanpa mengubah HTTP kode status, so sebuah
“not found” (terjemahan) “tidak ditemukan” view dapat masih kembalikan 200. Google dapat classify itu respons sebagai sebuah
soft 404 setelah evaluating dikembalikan konten, tetapi sebuah static fetch alone cannot prove
itu Google memiliki dibuat itu classification. Two fixes:
navigate dengan History API, dan untuk sebuah genuine not-ditemukan state either route untuk sebuah
URL itu mengembalikan sebuah nyata 404 status atau tambahkan sebuah noindex tag. dan don’t lean pada URL
fragments untuk routing — “the AJAX-crawling scheme has been deprecated since 2015, so
you can’t rely on URL fragments to work with Googlebot.” (terjemahan) “ AJAX-crawling scheme memiliki telah deprecated since 2015, so
Anda dapat’t rely pada URL fragments untuk berfungsi dengan Googlebot.”
sebuah client-side redirect memiliki yang sama evidence masalah: initial respons dapat remain
200 until JavaScript runs. Google mendukung JavaScript redirects hanya sebagai sebuah fallback
when server-side atau meta-refresh redirects adalah not mungkin. Report static status
dan observed rendered navigation separately; melakukan not rewrite HTTP status di
audit atau panggil setiap rendered URL perubahan sebuah redirect.
Don’t block JavaScript atau CSS di robots.txt
Google won’t render JavaScript dari blocked files atau pada blocked halaman. sebuah
robots.txt aturan itu disallows Anda bundle (atau /_next/, /static/, /assets/
directory ini lives di) dapat break rendering entirely — Google fetches shell, dapat’t
run scripts, dan indeks sebuah empty halaman. periksa pemeriksaan URL’s halaman resources
untuk anything blocked.
DOM parity dan stage-aware robots directives
Compare Anda raw HTML (View Source) terhadap rendered HTML (pemeriksaan URL). konten itu hanya exists di rendered HTML masih indeks — jika ini renders. konten di neither doesn’t exist untuk Google.
There’s one stage-order risk Google documents directly: “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.” (terjemahan) “When Google encounters
noindex tag, ini dapat skip rendering dan JavaScript execution, which berarti menggunakan
JavaScript untuk perubahan atau hapus robots meta tag dari noindex dapat not berfungsi sebagai
expected.” jika Anda raw HTML ships sebuah initial noindex Anda dimaksudkan untuk swap out dengan
JavaScript, Google dapat act pada itu raw noindex dan tidak pernah run script itu akan
memiliki dihapus ini.
melakukan not turn ini ke sebuah universal “rendered wins” (terjemahan) “rendered wins” aturan. Reconciliation adalah field-spesifik:
| Field | What raw/rendered comparison dapat establish |
|---|---|
| Main konten dan tautan | Google dapat gunakan konten dan nyata <a href> tautan produced selama rendering jika rendering succeeds. Raw availability reduces itu dependency. |
| judul dan deskripsi | Google dapat process JavaScript-set metadata, tetapi judul tautan dan snippets adalah selected dari several sources. tampilkan both states; melakukan not claim rendered, pertama, atau last nilai adalah guaranteed. |
| Robots directives | sebuah raw noindex dapat cause Google untuk skip rendering, so JavaScript removal dapat tidak pernah menjadi seen. menambahkan restrictions later adalah not evidence itu sebuah earlier restriction adalah cancelled. |
| Canonical | Google’s JavaScript guidance says not untuk set one nilai di source dan lalu perubahan ini dengan JavaScript. gunakan one metode dan verify one rendered-head declaration. |
| HTTP status dan redirect | JavaScript cannot perubahan respons status sudah diterima. Record static status dan apa pun observed rendered navigation sebagai separate facts. |
itu matrix adalah why sebuah auditor seharusnya pertahankan source, rendered, respons-header, dan observed-search state distinct alih-alih collapsing them ke one “effective” (terjemahan) “effective” nilai.
Pick sebuah rendering mode itu puts konten di DOM
sebagian besar JS-SEO risk comes down untuk how HTML adalah produced. pendek versi: SSR, static/prerendering, dan hydration semua put konten di (atau quickly ke) DOM, which reduces how much Anda visibilitas depends pada renderer succeeding; full client-side rendering leaves more riding pada rendering completing correctly, pada time, setiap time. Dynamic rendering adalah sebuah workaround, not sebuah peer option — sebagai dari Google’s guidance last updated December 2025, ini describes dynamic rendering sebagai sebuah workaround alih-alih sebuah panjang-istilah solusi dan recommends rendering sisi server, static rendering, atau hydration instead. sebagai I put ini di my JavaScript SEO guide, “any kind of SSR, static rendering, and prerendering setup is going to be fine for search engines.” (terjemahan) “apa pun jenis dari SSR, static rendering, dan prerendering setup adalah going untuk menjadi fine untuk mesin pencari.” full menu — CSR, SSR, SSG, hydration, ISR, edge, streaming, dan dynamic rendering — dengan sebuah trade-off table adalah pada rendering halaman. Google separately describes rendering sisi server atau pre-rendering sebagai sebuah baik idea untuk pengguna dan 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
cara test
pemeriksaan URL di Search Console adalah sumber kebenaran: run sebuah live test, lalu lihat rendered HTML, screenshot, dan halaman resources / console messages untuk see what dimuat dan what failed. Rich hasil Test gives sebuah quick rendered-HTML periksa. di scale, gunakan crawler itu executes JavaScript (Ahrefs situs Audit, Screaming Frog di JS-rendering mode) untuk diff raw vs. rendered di seluruh situs.
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 adalah not buruk untuk SEO, dan ini adalah not evil. ini adalah hanya berbeda dari what banyak SEOs adalah digunakan untuk. berfungsi dengan Anda developers, get Anda penting konten ke DOM, dan let Google’s own alat — not Anda assumptions — menjadi arbiter dari what rendered.
Where untuk go next: JavaScript SEO cluster
ini hub adalah map. setiap topic below adalah -nya own deep dive:
rendering dan architecture
- SEO untuk sebuah CMS headless — how decoupled frontends affect crawling, rendering, metadata, sitemaps, dan tag canonical; which rendering mode untuk pick; dan headless-spesifik failure modes Anda perlu know.
framework-spesifik guides
- React SEO — why CSR-pertama React membuat pengindeksan risk, how Google renders React apps, React Router dan History API, react-helmet-async untuk meta tags, dan when untuk reach untuk Next.js.
- Angular SEO — Angular’s SPA defaults,
@angular/ssr(Angular Universal’s successor), dibangun-di judul dan Meta services, prerendering, dan incremental hydration di modern Angular. - Next.js SEO — halaman Router vs App Router, Metadata API,
next/imagedan CWV, ISR timing dan Googlebot, sitemaps, dan paling umum Next.js SEO mistakes. - Nuxt SEO — SSR oleh default,
useSeoMeta(), Nuxt’s rendering modes,@nuxtjs/seomodule ecosystem, dan how Nuxt compares untuk plain Vue untuk indexability. - Vue SEO — Vue 3’s CSR default dan what itu berarti untuk crawler,
createWebHistory(),@unhead/vue, prerendering options without sebuah meta-framework, dan when Nuxt adalah right panggil. - Svelte SEO — Svelte vs SvelteKit, SSR oleh default di SvelteKit,
<svelte:head>,adapter-static+ssr: falsetrap, adapter choices, dan AI crawler implications. - Astro SEO — zero-JS oleh default, islands architecture,
@astrojs/sitemap,astro:assets, View Transitions dan History API, server Islands fallback perilaku, dan Astro’s Core Web Vitals advantages.
AI summary
sebuah condensed take pada Advanced versi:
- “Can Google read JS?” (terjemahan) “dapat Google read JS?” adalah wrong pertanyaan — ini dapat. failure modes adalah parity (raw vs. rendered), interaction (Google doesn’t scroll/click), state (stateless renderer), dan timing.
- Timing memiliki no fixed delay — Google queues sebuah
200halaman untuk rendering dan dapat wait “a few seconds” (terjemahan) “sebuah few seconds” atau longer, dengan no published timeout; sebuah non-200 status atau sebuah initialnoindexdapat skip render queue entirely. - tautan harus menjadi nyata
<a href>anchors —onclickpada sebuah<div>adalah invisible sebagai sebuah tautan. Injecting tautan dengan JS adalah fine jika mereka end up sebagai anchors, tetapi rendered anchors adalah parsed setelah JS runs — discoverable, not sebuah crawl/indeks guarantee. - Lazy-muat pada viewport, not interaction — Google “does not interact with your page.” (terjemahan) “melakukan not interact dengan Anda halaman.” gunakan IntersectionObserver / native lazy-muat; don’t gate konten behind scroll atau click.
- Infinite scroll dapat merge two halaman ke one — Googlebot dapat render di sebuah taller
viewport daripada sebuah typical browser (no exact published size — test Anda own setup),
dan itu gap dapat trigger loader dan append next halaman’s konten. Fix:
paginated URLs + nyata
<a href>tautan + History API; jika sebuah loader adalah merging halaman, block -nya JS file. - Soft-404s setelah client-side routing — mengembalikan nyata
404ataunoindex; don’t indeks empty shells; don’t rely pada URL fragments (AJAX-crawling deprecated 2015). - Don’t block JS/CSS di robots.txt — Google won’t render dari blocked files.
noindexdapat block -nya own removal — Google dapat skip rendering when ini sees sebuah initialnoindex, so JS dimaksudkan untuk hapus ini dapat tidak pernah run.- DOM parity + stage order (robots meta tags) — diff raw vs. rendered, tetapi remember
sebuah initial raw
noindexdapat stop rendering. Apply combination aturan hanya untuk directives actually processed; test canonical parity di bawah -nya own aturan. - rendering mode perubahan dependency, not outcome — SSR/static/prerender/hydration put konten di DOM sooner, reducing reliance pada rendering; full CSR relies pada ini sebagian besar; dynamic rendering adalah sebuah dated Google workaround, not sebuah peer option. Full breakdown pada rendering halaman.
- Test dengan pemeriksaan URL (rendered HTML + screenshot + console), Rich hasil Test, dan sebuah JS-rendering crawler.
Official documentation
Primary-source documentation dari mesin pencari.
- memahami JavaScript SEO basics — three phases, dapat di-crawl tautan, dan testing rendered HTML.
- Fix Search-related JavaScript masalah — soft-404 handling, History API, dan renderer constraints.
- Fix lazy-dimuat konten — muat pada viewport (not interaction), dan search-friendly infinite scroll.
- Ecommerce pagination dan incremental halaman memuat — unique URLs,
<a href>tautan, dan why Google ignores fragment identifiers. - di-Depth Guide untuk How Google Search berfungsi — where rendering sits di crawl → indeks → sajikan.
Bing / Microsoft
- bingbot Series: JavaScript, Dynamic rendering, dan Cloaking. Oh My! — Bing’s take pada rendering JS dan dynamic rendering.
Quotes dari source
pada—record statements dari Google (plus sebuah few dari my own writing). setiap search-mesin tautan adalah sebuah deep tautan itu jumps untuk quoted passage pada source halaman.
Google — rendering & tautan
- “Google processes JavaScript web apps in three main phases: 1. Crawling 2. Rendering 3. Indexing.” (terjemahan) “Google processes JavaScript web apps di three main phases: 1. crawling 2. rendering 3. pengindeksan.” Jump untuk quote
- “Google can only discover your links if they are <a> HTML elements with an href attribute.” (terjemahan) “Google dapat hanya menemukan Anda tautan jika mereka adalah <sebuah> HTML elements dengan sebuah href attribute.” Jump untuk quote
- “Rendering is important because websites often rely on JavaScript to bring content to the page, and without rendering Google might not see that content.” (terjemahan) “rendering adalah penting because situs web sering rely pada JavaScript untuk bring konten untuk halaman, dan without rendering Google mungkin not see itu konten.” Jump untuk quote
- “The page may stay on this queue for a few seconds, but it can take longer than that.” (terjemahan) “ halaman dapat stay pada ini queue untuk sebuah few seconds, tetapi ini dapat take longer daripada itu.” — pada render-queue timing, no fixed delay published. Jump untuk quote
- “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.” (terjemahan) “When Google encounters noindex tag, ini dapat skip rendering dan JavaScript execution, which berarti menggunakan JavaScript untuk perubahan atau hapus robots meta tag dari noindex dapat not berfungsi sebagai expected.” Jump untuk quote
Google — interaction, lazy-muat & infinite scroll
- “Google Search does not interact with your page.” (terjemahan) “Google Search melakukan not interact dengan Anda halaman.” Jump untuk quote
- “…loads all relevant content whenever it is visible in the viewport.” (terjemahan) “…memuat semua relevant konten whenever ini adalah terlihat di viewport.” Jump untuk quote
- “Give each chunk its own persistent, unique URL.” (terjemahan) “Give setiap chunk -nya own persistent, unique URL.” — search-friendly infinite scroll. Jump untuk quote
- “Don’t use URL fragment identifiers (the text after a # in a URL) for page numbers in a collection. Google ignores fragment identifiers.” (terjemahan) “Don’t gunakan URL fragment identifiers ( text setelah sebuah # di sebuah URL) untuk halaman angka di sebuah collection. Google ignores fragment identifiers.” Jump untuk quote
Google — soft-404 & routing
- “We recommend using the History API to load different views.” (terjemahan) “kami recommend menggunakan History API untuk muat berbeda views.” Jump untuk quote
Patrick Stox (my own berfungsi — JavaScript SEO: sebuah Definitive Guide)
- pada meta robots tags specifically: “With meta robots tags, Google is always going to take the most restrictive option it sees — no matter the location… Google will choose the most restrictive statements between HTML and the rendered version of a page.” (terjemahan) “dengan meta robots tags, Google adalah selalu going untuk take paling restrictive option ini sees — no penting location… Google akan choose paling restrictive statements antara HTML dan rendered versi dari sebuah halaman.”
- “If you have an infinite scroll setup, I still recommend a paginated page version so that Google can still crawl properly.” (terjemahan) “jika Anda memiliki sebuah infinite scroll setup, I masih recommend sebuah paginated halaman versi so itu Google dapat masih crawl properly.”
- pada merge: “occasionally, two pages get indexed as one” (terjemahan) “occasionally, two halaman get terindeks sebagai one” — caused when “Google resized the viewport to be longer … it triggered the infinite scroll and loaded another article in when it was rendering.” (terjemahan) “Google resized viewport untuk menjadi longer … ini triggered infinite scroll dan dimuat lainnya artikel di when ini adalah rendering.” fix: “block the JavaScript file that handles the infinite scrolling so the functionality can’t trigger.” (terjemahan) “block JavaScript file itu handles infinite scrolling so functionality dapat’t trigger.”
JavaScript-SEO checklist
sebuah quick pass untuk confirm Google dapat render dan indeks Anda JS-dependent konten:
- penting konten appears di rendered HTML (periksa pemeriksaan URL, not hanya View Source).
- tautan adalah nyata
<a href>anchors — notonclickhandlers pada<div>/<span>. - JavaScript dan CSS files adalah not blocked di
robots.txt. - tanpa konten adalah gated behind sebuah click, scroll, atau hover (Google doesn’t
interact); lazy-muat pada viewport via IntersectionObserver atau
loading="lazy". - Above—fold konten adalah not lazy-dimuat.
- Robots directives match antara raw dan rendered HTML (no JS injecting
noindex) — Google takes sebagian besar restrictive. - Client-side route perubahan itu hit sebuah missing resource mengembalikan nyata
404ataunoindex(no soft-404 shells). - Infinite scroll memiliki sebuah paginated versi dengan unique
<a href>URLs dan History API updates — dan isn’t merging halaman di sebuah tall viewport. - konten itu harus peringkat menggunakan SSR / static / prerendering, not full CSR (see rendering halaman).
- Anda’ve spot-diperiksa rendered screenshot dan console errors di URL Inspection’s live test.
mental models
1. “Can Google run my JS?” (terjemahan) “dapat Google run my JS?” adalah wrong pertanyaan. ini dapat. nyata pertanyaan adalah tentang parity, interaction, state, dan timing:
- Parity — melakukan rendered DOM berisi what Anda think ini melakukan?
- Interaction — melakukan anything memerlukan sebuah scroll/click Google won’t perform?
- State — adalah Anda relying pada cookies/localStorage stateless renderer clears?
- Timing — adalah critical konten deferred behind slow/late JS?
2. jika ini adalah not di rendered DOM, ini doesn’t exist. View Source menampilkan raw HTML; pemeriksaan URL menampilkan rendered DOM. indeks decisions adalah dibuat pada rendered DOM — so itu’s artifact untuk periksa, setiap time.
3. nyata tautan atau no tautan.
penemuan rides pada <a href> anchors. Click handlers, buttons, dan JS navigation itu
tidak pernah produces sebuah anchor adalah dead ends untuk crawling.
4. Design untuk sebuah bot itu tidak pernah touches halaman. No scroll, no click, no hover. jika konten perlu sebuah tindakan untuk appear, assume Google won’t see ini — muat ini pada viewport instead.
5. Test untuk tall-viewport trap di infinite scroll. Googlebot dapat render di sebuah viewport taller daripada sebuah typical browser (no fixed size adalah published, so don’t design terhadap sebuah spesifik angka), so sebuah scroll/height-triggered loader dapat fire selama render dan merge next halaman di. Design untuk ini: paginated URLs + nyata tautan + History API; jika ini adalah actively merging, block loader’s JS.
6. Let alat arbitrate. Anda browser adalah not Googlebot. pemeriksaan URL’s rendered HTML, screenshot, dan console adalah sumber kebenaran — not “it looks fine on my machine.” (terjemahan) “ini looks fine pada my machine.”
JavaScript-SEO gotchas — cheat sheet
| Thing | What actually happens |
|---|---|
robots.txt blocks Anda JS/CSS | Google won’t render dari blocked files — dapat break whole halaman |
Raw index + JS-injected noindex | Google obeys sebagian besar restrictive → noindex wins |
tautan sebagai onclick pada sebuah <div> | Not discoverable — harus menjadi <a href> |
| konten memuat pada scroll/click | Not dimuat — Google doesn’t interact; gunakan viewport lazy-muat |
URL fragment (#page=2) untuk pagination | Ignored — gunakan nyata unique URL |
Client-side 404 dengan 200 status | Soft-404 risk — kembalikan nyata 404 atau noindex |
| Infinite scroll di sebuah tall viewport | dapat merge two URLs ke one terindeks halaman — paginate + block loader jika needed |
Which rendering mode? (dependency pada rendering succeeding)
| Mode | Dependency |
|---|---|
| Static / prerender (SSG) | Lowest — konten adalah sudah di HTML |
| rendering sisi server (SSR) | rendah — konten adalah di HTML per permintaan |
| Hydration (isomorphic) | rendah — konten lands di DOM quickly |
| Full rendering sisi klien (CSR) | Highest — konten hanya exists setelah rendering succeeds |
| Dynamic rendering | Workaround hanya — Google panggilan ini sebuah stopgap, not sebuah fix |
ini isn’t sebuah guarantee dari outcome — SSR/SSG/hydration masih perlu untuk render correctly dan pass setiap lainnya periksa di ini artikel. Full breakdown (ISR, edge, streaming, dynamic rendering, dan trade-offs) pada rendering halaman.
See what Googlebot sees
rendering bugs hide di gap antara raw HTML (what server mengirim) dan rendered HTML (what exists setelah JS runs). sebuah few quick command-line memeriksa sebelum Anda reach untuk sebuah full crawler.
Fetch raw HTML (what comes back sebelum apa pun JS runs)
macOS / Linux:
# Raw HTML as the server sends it — this is the "first fetch"
curl -sL -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://example.com/page/ -o raw.html
# Is your important text actually in the raw HTML? (empty result = JS-dependent)
grep -o "Your headline text" raw.htmlWindows (PowerShell):
$ua = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
Invoke-WebRequest -Uri "https://example.com/page/" -UserAgent $ua -OutFile raw.html
Select-String -Path raw.html -Pattern "Your headline text"jika text adalah missing dari raw.html tetapi terlihat di Anda browser, ini adalah menjadi ditambahkan
oleh JavaScript — so ini depends pada rendering. (untuk rendered HTML, gunakan URL
Inspection’s “View Crawled Page → rendered HTML,” (terjemahan) “View di-crawl halaman → rendered HTML,” atau sebuah headless-Chrome crawler — sebuah
plain curl dapat’t run JS.)
Confirm Anda aren’t blocking JS/CSS di robots.txt
macOS / Linux:
curl -sL https://example.com/robots.txt | grep -iE "disallow.*\.(js|css)|Disallow:\s*/(_next|static|assets|dist)"Windows (PowerShell):
(Invoke-WebRequest "https://example.com/robots.txt").Content |
Select-String -Pattern "Disallow.*\.(js|css)","Disallow:\s*/(_next|static|assets|dist)"sebuah Disallow itu matches Anda JavaScript atau CSS berarti Google dapat’t render halaman
properly — almost selalu sebuah mistake. (pemeriksaan URL lists blocked halaman resources too;
grep hanya catches obvious ones fast.)
alat untuk debugging JavaScript SEO
See difference antara raw HTML dan what Google renders dengan Render Gap:
- Paste full URL dari halaman Anda ingin test — sebuah JavaScript-heavy template halaman menampilkan paling.
- jelas anti-abuse periksa dan press Test halaman; ini fetches raw HTML pertama dan hanya renders di headless Chrome when itu HTML looks like sebuah empty shell.
- Read colour-coded verdict, lalu scan Initial HTML vs Rendered DOM table untuk rows flagged changed.
- Switch untuk Raw vs rendered diff tab untuk see line-oleh-line what JavaScript ditambahkan atau dihapus.
- pemeriksaan URL (Google Search Console) — sumber kebenaran. Run sebuah live test, lalu view rendered HTML, screenshot, halaman resources (what dimuat vs. what adalah blocked), dan JavaScript console messages.
- Rich hasil Test — sebuah fast cara untuk periksa rendered HTML dan data terstruktur untuk sebuah URL without verifying situs.
- Chrome DevTools — compare View Source (raw HTML) dengan Elements panel (rendered DOM); Console surfaces JS errors itu dapat blank out konten.
- JavaScript-rendering crawler — Ahrefs situs Audit dan Screaming Frog SEO Spider (JS-rendering mode) execute JS so Anda dapat diff raw vs. rendered di scale.
- View-rendered-source alat — browser extensions itu tampilkan rendered DOM side-oleh-side dengan raw HTML untuk quick spot memeriksa.
- server log analysis — confirm Googlebot adalah actually fetching Anda JS/CSS resources (see log file analysis).
Prompts untuk JavaScript SEO diagnosis
Compare raw dan rendered HTML
Paste raw respons dan rendered DOM untuk yang sama URL. hapus customer data dan tokens pertama.
Act as a technical SEO reviewer. Compare RAW_HTML and RENDERED_HTML below. Report only
meaningful differences in title, meta robots, canonical, headings, body copy,
structured data, and crawlable <a href> links. For each difference, label its likely
indexing impact, show the exact conflicting snippets, and give a verification step.
Do not infer content that is not present.
RAW_HTML:
[paste]
RENDERED_HTML:
[paste]Triage sebuah route sample
Review this CSV of JavaScript routes with columns URL, HTTP_STATUS, RAW_TITLE,
RENDERED_TITLE, RAW_CANONICAL, RENDERED_CANONICAL, RAW_WORDS, RENDERED_WORDS. Group
failures into shared-shell duplicates, restrictive-directive conflicts, soft 404s,
and likely render timeouts. Rank groups by affected URL count. Return the exact rows
that support each conclusion and a test to confirm it; do not invent thresholds.
[paste CSV] Validate sebuah JavaScript SEO perubahan
Prove route konten exists sebelum JavaScript
Test untuk run: Fetch representative routes dengan curl dan inspect respons
body. Expected hasil: setiap respons berisi -nya unique judul, primary heading,
copy, dan dapat di-crawl tautan. Failure interpretation: deployment masih menyajikan sebuah
shared app shell. Monitoring window: Immediate. Rollback trigger: sebuah formerly
server-terlihat route becomes dependent pada rendering.
Prove directives agree di seluruh processing stages
Test untuk run: Compare raw HTML dengan pemeriksaan URL’s rendered HTML untuk robots dan
tag canonical. Expected hasil: One intended directive set appears di both, dengan
no more-restrictive nilai di raw shell. Failure interpretation: JavaScript adalah
trying untuk overwrite sebuah pengindeksan signal too late. Monitoring window: Immediate di
local rendering; setelah recrawl di Search Console. Rollback trigger: noindex atau
sebuah incorrect canonical appears di either stage.
Prove tautan remain dapat di-crawl
Test untuk run: Disable JavaScript dan inspect navigation untuk representative routes.
Expected hasil: Destinations remain di nyata anchor href attributes. Failure
interpretation: Client handlers, not tautan, own penemuan. Monitoring window:
Immediate. Rollback trigger: penting routes disappear dari tautan graph when
scripts fail.
Resources worth Anda time
My related writing
- JavaScript SEO: sebuah Definitive Guide — my full guide untuk rendering, DOM parity, paling-restrictive-directive aturan, infinite scroll, dan two-halaman-sebagai-one masalah. ini artikel adalah condensed, source-ditautkan versi.
- Beginner’s Guide untuk SEO teknis — where JavaScript SEO fits di bigger picture.
My speaking
- How Search berfungsi (SlideShare) — my walkthrough dari crawling, rendering, pengindeksan, dan peringkat. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.” (terjemahan) “ini adalah my understanding dari sistem… not going untuk menjadi 100% complete atau accurate.”)
dari others
- r/TechSEO — community untuk debugging render/indeks masalah.
- web.dev — rendering pada Web — canonical explainer dari rendering trade-offs dari Chrome team.
- Google Search Central — JavaScript SEO — official primary-source docs pada three-phase process, dapat di-crawl tautan, dan testing rendered HTML.
- Onely — JavaScript SEO hub — deep technical posts pada rendering, two-waves pengindeksan, dan JS SEO auditing dari sebuah specialist agency.
- Martin Splitt’s JavaScript SEO playlist — official Google video series walking melalui setiap JS SEO concept, produced oleh Google’s web ecosystem team.
- mesin pencari Journal — JavaScript SEO coverage — industry news dan practitioner guides pada JS rendering issues sebagai mereka emerge.
Podcasts
- Search Off Record (Google Search Relations) — Martin Splitt, John Mueller, dan Gary Illyes regularly cover JavaScript SEO dan rendering dari inside. Listen
Videos
- Google Search Central (YouTube) — Martin Splitt’s JavaScript SEO series adalah best official video walkthrough dari how Google handles Anda JS. Channel
Stats worth citing
- saat ini official framing: no fixed delay. Google’s own documentation (updated
2026-03-04) says sebuah di-crawl
200halaman “may stay on this queue for a few seconds, but it can take longer than that” (terjemahan) “dapat stay pada ini queue untuk sebuah few seconds, tetapi ini dapat take longer daripada itu” — there’s no published fixed delay atau timeout, dan halaman itu mengembalikan non-200 status atau start out dengannoindexdapat skip rendering entirely. Jump untuk quote - Historical data poin (dated) — ~5 kedua median render delay. di earlier conference remarks, Google staff (Martin Splitt dan Tom Greenaway) described halaman reaching renderer di sebuah median dari ~5 seconds, dengan 90th percentile di minutes — not “weeks” (terjemahan) “weeks” old fear implied. I cite ini di my JavaScript SEO guide. Treat ini sebagai sebuah historical data poin dari itu talk, not sebuah saat ini published metric — Google hasn’t republished ini sebagai sebuah ongoing figure, dan queue-timing quote above adalah saat ini official framing.
- “Two waves of indexing” (terjemahan) “Two waves dari pengindeksan” adalah fading, per Martin Splitt (2019 remarks). di sebuah August 2019 conversation dengan John Mueller, Splitt said two-wave pengindeksan “play[s] less and less of a role” (terjemahan) “play[s] less dan less dari sebuah role” sebagai rendering gets cheaper dan crawling, rendering, dan pengindeksan converge — dengan no timeline given untuk when ini mungkin stop entirely. Coverage ini adalah Splitt’s characterization dari itu spesifik conversation, not sebuah dated, citable Google spec — gunakan ini sebagai directional context, not sebuah saat ini guarantee either cara.
Make rendering an architecture decision before launch: if revenue pages depend on JavaScript for primary content or links, verify what search engines receive instead of assuming the browser experience is enough.
- Client-side rendering, interaction-gated content, and nonstandard links are structural risks that cost more to correct after launch.
- Raw-versus-rendered parity testing shows whether important content, links, and status signals survive the crawl, render, and index process.
- Server-rendered or static primary content with JavaScript used only for enhancement may require no special remediation.
A short, template-level diagnostic before a build or replatform can prevent later re-architecture and focus spending on the routes with organic traffic at risk.
Risiko jika diabaikan: Search engines may miss primary content, interaction-gated elements, or internal links, leaving revenue pages under-indexed even though they work for users in a browser.
Tanyakan kepada tim Anda: What do our top revenue templates return before JavaScript runs, and have we verified their content and links in rendered output before release?
Google processes JavaScript apps melalui crawling, rendering, dan pengindeksan.
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 ini umumnya melakukan crawl tautan when mereka
adalah anchors dengan href attributes. 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
Google describes rendering sisi server atau pre-rendering sebagai sebuah baik idea untuk pengguna dan
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 Google Search juga
melakukan not interact dengan sebuah halaman untuk trigger konten. 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
Log perubahan
Diperbarui 27 Jul 2026.
Ringkasan editorial dan detail perubahan yang tercatat.Detail perubahan
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
Perbandingan lengkap tidak tersedia — tidak ada cuplikan sebelumnya yang diarsipkan untuk revisi ini.
Diperbarui 18 Jul 2026.
Ringkasan editorial dan detail perubahan yang tercatat.Detail perubahan
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
-
Catatan perubahan terperinci saat ini tersedia dalam bahasa Inggris.
Perbandingan lengkap tidak tersedia — tidak ada cuplikan sebelumnya yang diarsipkan untuk revisi ini.