Panduan Vue SEO

Vue 3 defaults untuk rendering sisi klien, so konten tidak di mentah HTML. ini adalah cara membuat Vue apps dapat di-crawl dan dapat diindeks — router mode, @unhead/vue, prerendering dengan vite-ssg, SSR/SSG dengan Nuxt, hydration, dan Core Web Vitals.

Pertama kali diterbitkan: 26 Jun 2026 · Terakhir diperbarui: 3 Agu 2026 · Lanjutan

Vue 3 defaults untuk rendering sisi klien, so sebuah plain Vite + Vue app ships sebuah empty HTML shell dan membangun halaman di browser. Google dapat render ini — tetapi rendering adalah delayed dan async data dapat menjadi missed, dan Bing dan social scrapers sering dapat't jalankan JS di semua. memperbaiki: gunakan Vue Router history mode (tidak hash mode), manage <head> dengan @unhead/vue, dan put konten di HTML dengan prerendering (vite-ssg), SSR, atau SSG melalui Nuxt. Dynamic rendering adalah deprecated — jangan bangun pada ini.

TL;DR — Vue 3 adalah CSR oleh default, so konten tidak di mentah HTML — Google renders ini kemudian melalui -nya evergreen Chromium WRS, tetapi render adalah queued dan async data fetched di onMounted dapat menjadi missed, dan Bing/social scrapers sering jangan jalankan JS di semua. Non-negotiables: Vue Router createWebHistory() (hash mode memiliki “a bad impact di SEO” (terjemahan) “sebuah buruk impact di SEO”), <head> melalui @unhead/vue / useSeoMeta(), dan sebuah rendering strategy itu mendapatkan konten ke HTML — vite-ssg prerendering untuk konten-stable situs, Nuxt untuk penuh SSR/SSG. Dynamic rendering adalah deprecated; prerender-spa-plugin adalah legacy. Watch hydration mismatches (sebuah server/client konten delta adalah sebuah SEO masalah, tidak hanya sebuah perf satu) dan CSR bundle’s hit pada LCP. untuk kerangka kerja-agnostic versi dari semua dari ini, see JavaScript SEO.

default Vite + Vue scaffold adalah client-side dirender

sebuah plain npm create vue@latest app (Vite + Vue) ships sebuah near-empty HTML shell dan sebuah JavaScript bundle. browser executes itu bundle untuk bangun DOM. ini adalah fine untuk pengguna dan sebuah masalah untuk crawler: mentah HTML berisi hampir Tidak konten, dan semuanya bergantung pada rendering.

itu’s sebuah property dari default scaffold, tidak sebuah ceiling pada Vue itself — Vue core juga mendukung server rendering (createSSRApp) dan static generation sebagai pertama-class paths, dan Vue’s own SSR guide steers sebagian besar production SSR/SSG berfungsi toward Nuxt alih-alih sebuah hand-rolled setup. So sebelum reaching untuk sebuah perbaiki, periksa apa Anda app adalah sebenarnya shipping: sebuah bare Vite SPA dengan Tidak rendering config adalah CSR; yang sama app behind Nuxt atau vite-ssg tidak.

Vue’s own SSR guide adalah direct tentang upside dari tidak melakukan ini: dengan rendering sisi server, “itu penelusuran engine crawlers akan secara langsung see itu fully dirender halaman.” (terjemahan) “ mesin pencari crawler akan secara langsung see fully dirender halaman.” flip side adalah apa Anda ship oleh default — konten itu hanya ada setelah JavaScript berjalan. Bukti untuk klaim ini Vue server-side rendering sends rendered HTML so crawlers can directly see page content. Cakupan: Vue SSR benefits; does not guarantee indexing. Tingkat keyakinan: tinggi · Diverifikasi: Vue: SSR guide

(Vue 2 reached end dari life di December 2023; semuanya di sini adalah Vue 3.)

Bagaimana Googlebot menangani sebuah Vue app

Google memproses JavaScript di phases — crawl mentah HTML, lalu render ini di sebuah evergreen, headless Chromium instance ( Web rendering Service), lalu indeks dirender hasil. Dua hal ikuti dari itu:

  • rendering adalah queued dan delayed. sebuah halaman sits di render queue — biasanya seconds untuk minutes, tetapi ini dapat spike. konten itu ada hanya setelah JS berjalan adalah tidak immediately dapat diindeks; konten di mentah HTML adalah.
  • Async data adalah nyata risk. Synchronous JavaScript renders reliably. data fetched dari sebuah API setelah mount adalah tidak guaranteed untuk menjadi caught. Vue’s SSR guide says ini plainly: “Jika Anda app dimulai dengan a loading spinner, lalu fetches konten melalui Ajax, itu crawler akan tidak tunggu untuk Anda untuk finish. Ini berarti jika Anda memiliki konten fetched asynchronously pada halaman di mana SEO adalah important, SSR mungkin menjadi necessary.” (terjemahan) “jika Anda app dimulai dengan sebuah memuat spinner, lalu fetches konten melalui Ajax, crawler akan tidak tunggu untuk Anda untuk finish. ini berarti jika Anda memiliki konten fetched asynchronously pada halaman di mana SEO adalah penting, SSR mungkin menjadi necessary.” Practically: data fetched di onMounted adalah client-hanya dan invisible untuk crawler itu jangan render — dan di risk bahkan dengan ones itu melakukan.

John Mueller memiliki described failure mode untuk SPA-style setups di mana static HTML adalah mostly identical dan semua unique konten bergantung pada JavaScript: jika itu JS dapat’t menjadi executed properly, halaman end up looking yang sama untuk Google, dan focus tetap pada boilerplate HTML alih-alih JS-dimuat konten. lesson adalah yang sama sebagai lebih luas JavaScript SEO halaman: mendapatkan konten ke DOM, fast dan reliably.

Bing dan social bot adalah worse di ini daripada Google. Bing memiliki Tidak rendering pipeline comparable untuk Google’s, dan social preview scrapers (X, Slack, iMessage) umumnya jangan jalankan JavaScript di semua — so sebuah bare CSR Vue app produces empty share previews. jika Bing traffic atau social sharing penting, prerendering atau SSR tidak opsional.

Vue Router: gunakan createWebHistory(), tidak hash mode

Vue Router memiliki dua history modes. Hash mode (createWebHashHistory()) produces URLs like example.com/#/about; Vue Router’s docs say ini “melakukan namun memiliki a bad impact di SEO” (terjemahan) “melakukan namun memiliki sebuah buruk impact di SEO” karena semuanya setelah # adalah sebuah fragment server ignores. Bukti untuk klaim ini Vue Router hash history uses a URL fragment that is not sent to the server and is discouraged for SEO. Cakupan: Vue Router hash history. Tingkat keyakinan: tinggi · Diverifikasi: Vue Router: History modes gunakan HTML5 history mode:

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [/* ... */],
})

History mode memberikan bersih URLs (example.com/about) tetapi memerlukan sebuah server fallback — apa pun direct permintaan untuk sebuah route memiliki untuk sajikan index.html so Vue dapat take di atas, jika tidak direct hits 404. Configure itu catch-semua pada Anda host (Nginx try_files, sebuah SPA rewrite pada Netlify/Vercel/Cloudflare, dan seterusnya.).

«Scope that rewrite carefully — a catch-all that’s too broad also serves index.html for missing static assets, real API routes, or pages you actually want to 404. That silently undoes the soft-404 guidance below and can hide a broken link behind a page that looks like it “worked.” » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian tiga puluh dua, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

untuk genuine tidak-ditemukan status, hindari soft-404s — sebuah client-side “tidak ditemukan” (terjemahan) “tidak ditemukan” view itu masih mengembalikan 200 dapat mendapatkan terindeks sebagai sebuah empty shell. Google’s guidance adalah untuk either redirect untuk sebuah URL itu mengembalikan sebuah nyata 404 status atau tambahkan sebuah <meta name="robots" content="noindex"> untuk halaman error, dan untuk gunakan History API untuk routing antara views.

Head dan meta management: @unhead/vue

oleh default setiap Vue route shares satu <title> dan satu deskripsi meta. tag history di sini penting karena old jawaban adalah dead ends:

  • vue-meta — Nuxt 2-era library. Legacy.
  • @vueuse/head — -nya successor, now sunset.
  • @unhead/vue — saat ini community standard, dan apa Anda harus gunakan untuk sebuah non-Nuxt Vue 3 app.

ergonomic entry poin adalah useSeoMeta() composable — jenis-safe, XSS-safe, dan aware dari 100+ meta tags including Open Graph dan Twitter Card:

import { useSeoMeta } from '@unhead/vue'

useSeoMeta({
  title: 'Vue SEO Guide',
  description: 'How to make a Vue 3 app crawlable and indexable.',
  ogTitle: 'Vue SEO Guide',
  ogDescription: 'How to make a Vue 3 app crawlable and indexable.',
  twitterCard: 'summary_large_image',
})

«Meta can be reactive — pass a getter or computed value and the tags update when your data does. For canonical tags, the safest pattern is still HTML, not JS: Google’s guidance is that “the best way to set the canonical URL is to use HTML,” and if you must inject it with JavaScript, always set it to the same value the HTML would. (I tested JS canonicals at Ahrefs and found Google does respect them — it even led Google to add an exception to its docs — but HTML is still the lower-risk path.) » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian tiga puluh sembilan, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

Pick sebuah rendering strategy

ini adalah decision itu sebenarnya moves needle. sama menu sebagai kerangka kerja- agnostic JavaScript SEO halaman, applied untuk Vue.

rendering sisi klien (CSR) — default, dan risky satu. Acceptable untuk app-like halaman behind sebuah login, dashboards, dan apa pun Anda tidak perlu terindeks. Tidak acceptable untuk konten itu harus peringkat atau menjadi shared.

Prerendering dengan vite-ssg. untuk konten-stable Vue 3 SPAs, vite-ssg generates static HTML di bangun time — tukar Anda bangun script dari vite build untuk vite-ssg build. ini ships @unhead/vue dibangun di. Great untuk marketing situs, docs, dan blogs; tidak sebuah substitute untuk SSR pada highly dynamic, per-permintaan halaman. Note itu old webpack-era prerender-spa-plugin adalah legacy dan effectively unmaintainedvite-ssg (atau Nuxt) adalah modern replacement.

rendering sisi server. Vue’s official guide covers sebuah manual SSR setup dengan @vue/server-renderer, tetapi ini explicitly steers sebagian besar projects untuk sebuah meta-kerangka kerja alih-alih rolling Anda own — dan untuk sederhana cases ini bahkan says “jika Anda hanya investigating SSR untuk improve itu SEO dari a handful dari marketing halaman … lalu Anda probably ingin SSG alih-alih dari SSR.” (terjemahan) “jika Anda’re hanya investigating SSR untuk meningkatkan SEO dari sebuah handful dari marketing halaman … lalu Anda probably ingin SSG alih-alih SSR.” jika Anda melakukan roll manual SSR, buat app, router, dan store fresh per permintaan: pada sebuah panjang-berjalan Node server, module-tingkat singletons mendapatkan reused di seluruh permintaan, dan mutating shared state dengan satu pengguna’s data dapat leak ini ke lainnya pengguna’s respons. itu’s satu lebih alasan Vue’s docs poin sebagian besar projects di Nuxt, yang menangani per-permintaan isolation untuk Anda.

Bukti untuk klaim ini Module-scope singleton state in Vue SSR can leak user-specific data across requests; create application, router and store instances per request. Cakupan: SSR and hydration Tingkat keyakinan: tinggi · Diverifikasi: Server-Side Rendering

Nuxt — recommended penuh solusi. Nuxt memberikan Anda SSR dan SSG out dari box, dibangun-di useSeoMeta() dan head management, dan @nuxtjs/seo module untuk sitemaps, robots.txt, dan data terstruktur. untuk sebagian besar Vue projects di mana SEO penting, ini adalah path Vue’s own docs poin untuk. (Nuxt memiliki -nya own depth — covered secara terpisah; treat ini sebagai cross-tautan, tidak deep dive.)

Dynamic rendering — jangan. Serving prerendered HTML untuk bot dan SPA untuk pengguna adalah selalu sebuah workaround, dan Google deprecated ini di 2024, menghapus implementation docs. bangun pada SSR atau SSG alih-alih.

untuk documentation secara khusus, VitePress adalah Vue-native static situs generator. setiap halaman ships sebagai plain HTML — Tidak JS rendering barrier — dan SEO adalah configured melalui frontmatter (title, description, head) atau transformHead bangun hook untuk canonical/dynamic tags.

Hydration mismatches adalah sebuah SEO masalah, tidak hanya sebuah perf satu

Ketika Anda melakukan SSR/SSG, client mounts dengan createSSRApp() — tidak plain createApp() — dan hydrates server-dirender HTML alih-alih rebuilding ini dari scratch. jika server HTML dan client render diverge, Vue discards dan re-renders mismatched nodes. di SEO istilah, itu berarti konten Google terindeks dari server render dapat differ dari apa pengguna sees setelah hydration — sebuah quality-sinyal inconsistency, tidak hanya sebuah flicker. umum penyebab: tidak valid HTML nesting, random nilai di templates, dan date/time discrepancies antara server dan client. Vue 3.5+ menambahkan data-allow-mismatch untuk suppress mismatch warning selectively di mana sebuah perbedaan adalah intentional — ini quiets console, ini tidak membuat server dan client output equivalent, so jangan reach untuk ini hanya untuk silence sebuah mismatch Anda haven’t sebenarnya diagnosed.

Core Web Vitals adalah sebuah Vue-spesifik concern

Default CSR Vue ships sebuah besar JS bundle itu memiliki untuk download, parse, dan execute sebelum largest konten paints — so LCP suffers jika Anda melakukan tidak ada apa pun. Levers:

  • Code splitting (Vite’s default) dan lazy-dimuat routes so Anda tidak ship seluruh app up front.
  • fetchpriority="high" pada LCP hero image.
  • Vapor Mode — sebuah opt-di compiler mode itu bypasses virtual DOM untuk eligible components, yang dapat cut hydration cost pada SSR halaman. ini adalah Vue 3,6, tidak 3,5 — masih experimental (beta/rilis-candidate sebagai dari pertengahan 2026, belum di stable 3,5.x line) — worth watching, tidak sesuatu untuk bergantung pada di production hari ini.

data terstruktur di Vue

Google executes JavaScript sebelum reading data terstruktur, so injecting JSON-LD berfungsi — @unhead/vue’s useHead() dengan sebuah script dari jenis application/ld+json adalah reliable pattern. Karena ini bergantung pada rendering, konfirmasi ini dengan pemeriksaan URL alih-alih assuming Google saw ini.

Di mana ini fits

Vue SEO adalah satu instance dari umum JavaScript SEO masalah — parity, interaction, state, timing — dan ini shares hampir semuanya dengan CMS headless situation, di mana rendering mode dari frontend decides outcome.

Satu caveat itu applies untuk setiap option di atas: SSR dan SSG mendapatkan Anda konten ke HTML, tetapi neither jaminan pengindeksan, rankings, Core Web Vitals, atau itu hydration akan match server output persis. mereka hapus JavaScript-rendering barrier — rest dari SEO (dan correctness) adalah masih pada Anda.

jika Anda remember satu hal: mendapatkan Anda konten ke HTML. Semuanya else adalah detail.

Tambahkan catatan pakar

Sematkan kutipan pakar

Orang baru? Buat profilnya yang belum diklaim di /admin/experts/ → Sematkan kutipan pakar terlebih dahulu.