VUE.JS SEO AUDIT · CSR DETECTION · NUXT SSR · AI VISIBILITY

Free Vue.js SEO Audit

Vue.js apps render client-side by default — Googlebot sees an empty shell on the first crawl and must wait for a second-wave JavaScript render that can take days. DeepSEOAnalysis detects Vue CSR rendering gaps, metadata visibility issues, and AI visibility signals, with migration guidance for Nuxt, vite-ssg, and Vue Router configuration.

Audit my Vue.js site →How we score

WHAT WE CHECK

6 Vue.js-specific SEO checks

Beyond the 80+ general checks, the engine detects Vue.js CSR rendering gaps, checks whether metadata is present in the server-rendered HTML or only after JavaScript execution, and evaluates hash-mode vs history-mode routing — with Nuxt.js and vite-ssg migration guidance for each issue.

⚙️

CSR rendering gap detection

Plain Vue.js (created with `npm create vue@latest` or Vite) renders entirely client-side: the server sends `<div id="app"></div>` and the browser runs the JavaScript to mount the Vue component tree. Googlebot\'s first-wave crawl sees only the HTML shell — no content, no headings, no metadata. The content enters a rendering queue for a second-wave JavaScript execution pass that can be delayed by days to weeks for lower-priority URLs. During this window, the page may be indexed as empty or not indexed at all. The audit detects this pattern by comparing the server-rendered HTML (what the first wave sees) against the full rendered DOM. If headings, body text, or structured data are absent from the raw HTML response but present after JavaScript execution, the page is flagged as CSR-affected with migration guidance: Nuxt.js (SSR/SSG), `vite-ssg`, or `@vitejs/plugin-ssr`.

🏷️

Vue Router URL structure

Vue Router can generate URLs that are either SEO-friendly or problematic. The main issue: hash-mode routing (`createWebHashHistory()`) produces URLs like `example.com/#/about` — the fragment after `#` is never sent to the server, so Googlebot sees all hash-route URLs as the same page (`example.com/`). Switch to HTML5 history mode (`createWebHistory()`) for server-addressable URLs. In history mode, URL structure choices affect SEO: dynamic segments using IDs (`/post/:id`) produce non-descriptive URLs like `/post/42`; keyword slugs (`/post/:slug`) produce `/post/my-article-title` which carry semantic signal. Ensure your router uses keyword slugs for all indexable content routes. The audit checks URL patterns across crawled pages and flags hash-mode routing and numeric-ID URL patterns as on-page issues.

📝

Metadata in server-rendered HTML

`document.title = ...` and manual `meta` tag DOM manipulation set metadata after the page loads in the browser — they\'re absent from the server-rendered HTML that Googlebot sees on the first wave. Libraries like `vue-meta` (legacy) or the built-in Nuxt `useHead()` composable inject metadata during SSR, but only when SSR is actually active. Common patterns that fail: a Vue app that uses `vue-meta` but is served from a static `index.html` without SSR; a Vite-built Vue app where metadata is set in `onMounted()` or `watchEffect()` (client-only lifecycle hooks); a Nuxt app with `ssr: false` (Nuxt SPA mode) where `useHead()` only runs on the client. The audit checks every crawled page for a unique, non-empty `title` and `meta name="description"` in the server-rendered HTML (before JavaScript execution) and distinguishes between metadata present server-side vs client-only.

🗺️

Sitemap generation

Vue Router\'s route list is the source of truth for what pages exist in a Vue SPA. There\'s no built-in sitemap generation — it must be added explicitly. For Nuxt: `@nuxtjs/sitemap` reads the pages directory and dynamic route configurations and generates `sitemap.xml` automatically, including proper `lastmod` from content timestamps. For Vite + Vue Router: `vite-plugin-sitemap` generates a static sitemap from the route list at build time. For apps with database-driven content: an Express or Fastify endpoint that queries the content store and emits XML is the pattern. Common gaps: sitemap is generated but only covers static routes, missing dynamic content like blog posts and product pages; `lastmod` uses the build date rather than the content updated-at timestamp; the sitemap is not referenced by a `Sitemap:` directive in `robots.txt`. The audit checks all of these.

🤖

robots.txt configuration

Vue apps deployed as static files (via Vite build output, Netlify, Vercel, or similar) serve `robots.txt` from the `public/` directory — `public/robots.txt` maps to `/robots.txt`. This file must exist in the source; it\'s not generated automatically. Common gaps: `robots.txt` is missing entirely (Googlebot gets a 404, which is treated as "no restrictions" but is a signal gap); the file blocks AI crawlers (GPTBot, ClaudeBot, PerplexityBot) accidentally via an overly broad `Disallow: /`; hash-mode routing means all URLs appear as one to robots.txt (another reason to use history mode); the `Sitemap:` directive is missing. For Nuxt: `robots.txt` in `public/` is served directly. The `@nuxtjs/robots` module provides config-driven robots.txt generation with per-route noindex control. The audit checks the file at `/robots.txt`, all AI crawler user-agents, and the Sitemap directive.

🧠

AI visibility for Vue apps

Serve `llms.txt` from the `public/` directory in both Vite + Vue and Nuxt projects — `public/llms.txt` maps to `/llms.txt` via static file serving. FAQPage JSON-LD must be in the server-rendered HTML, not added client-side. In Nuxt: use `useSchemaOrg()` from `nuxt-schema-org` or a `script type="application/ld+json"` block in `<template>` (rendered server-side). In plain Vue with SSG (`vite-ssg`): JSON-LD in the template is included in the pre-rendered HTML. In Vue CSR: `useHead({ script: [{ type: \'application/ld+json\', children: JSON.stringify(schema) }] })` only runs client-side and won\'t reach the first-wave crawl. The audit checks all five AI visibility signals — llms.txt presence, AI crawler access, FAQPage/HowTo schema in server-rendered HTML, question-heading ratio (≥20%), and content chunkability (avg section ≤400w) — with Vue/Nuxt-specific fix guidance.

HOW IT WORKS

Audit your Vue.js site in 60 seconds

  1. Enter your Vue.js site URL. Works with plain Vue + Vite, Nuxt.js, Quasar, VitePress, and any deployment (Netlify, Vercel, Cloudflare Pages, self-hosted Node). No access to the source code or build config needed — the audit crawls the live site.
  2. We crawl and analyse. The engine detects the rendering mode (CSR vs SSR vs SSG), compares server-rendered HTML against the fully rendered DOM to find content gaps, checks URL patterns for hash-mode routing and numeric IDs, validates JSON-LD in the server-rendered HTML, tests sitemap and robots.txt, measures CrUX Core Web Vitals, and evaluates all five AI visibility signals.
  3. You get a prioritised report. Vue-specific issues first — CSR rendering gap, hash-mode routing, metadata visibility, sitemap configuration, AI crawler access — then general SEO, each with Nuxt.js composable names, Vite plugin names, and Vue Router API references for the fix.

FAQ

Questions about the Vue.js SEO audit

Does Vue.js have SEO problems?

Vue.js apps built without a meta-framework (no Nuxt, no Quasar SSR) render client-side by default. The HTML sent to Googlebot is an empty shell — `<div id="app"></div>` — with no content or metadata. Content appears after JavaScript executes in the browser, but Googlebot may delay that second-wave rendering by days or weeks. The practical result: new Vue CSR pages can take much longer to rank, or may not index at all until Googlebot completes the render queue. The fix: add Nuxt.js for SSR/SSG, or use `vite-ssg` for static generation, or use `Vue Server Renderer` directly. DeepSEOAnalysis detects Vue CSR rendering gaps on every audit.

Is Nuxt.js better for SEO than Vue.js?

Yes — Nuxt is Vue with SSR or SSG built in. A Nuxt page configured with SSR (`ssr: true`, the default) or SSG (`nuxt generate`) sends complete HTML to Googlebot on the first HTTP response, with no rendering delay. Nuxt also provides `useHead()` and `useSeoMeta()` composables that inject metadata into the server-rendered HTML. If you\'re starting a new Vue project that needs to rank, use Nuxt. If you already have a Vue CSR app and migrating to Nuxt is impractical, the next best option is `vite-plugin-ssr` or `vite-ssg` to pre-render content pages at build time.

How do I generate a sitemap for a Vue.js site?

For Nuxt: use `@nuxtjs/sitemap` (`npx nuxi module add sitemap`), which auto-generates `sitemap.xml` from your pages directory and dynamic routes. For plain Vue with Vite: use `vite-plugin-sitemap` in `vite.config.ts` to generate the sitemap at build time from your route list. For Vue Router apps served by Node/Express: generate the sitemap server-side via an Express route that queries your data store and emits XML. The DeepSEOAnalysis audit checks sitemap presence, URL coverage relative to crawled pages, `lastmod` recency, and the `Sitemap:` directive in `robots.txt`.

Is the Vue.js SEO audit free?

Yes. The complete audit is free with no signup and no email gate. Paid plans add saved history, scheduled monitoring, larger crawls (up to 1,000 pages), and agency workflows.