Back to Blog
Vue
Nuxt
Technical SEO

Vue & Nuxt SEO Guide: From CSR Pitfalls to SSR Success

Vue.js apps face the same SEO challenges as React. Learn how to fix them with Nuxt, and the key differences that make Nuxt the SEO powerhouse of the Vue ecosystem.

RankCLI TeamJanuary 21, 20268 min read

Vue.js is fantastic for building interactive UIs. But like React, a vanilla Vue SPA is invisible to search engines.

This guide covers SEO for both Vue (with workarounds) and Nuxt (the proper solution).

Part 1: Vue.js SPA SEO Challenges

The Core Problem

A Vue CLI or Vite-created Vue app renders client-side:

html
<body>
  <div id="app"></div>
  <script type="module" src="/src/main.ts"></script>
</body>

Search engines see an empty div.

Workaround 1: Vue Meta

Add meta tag management with @vueuse/head:

bash
npm install @vueuse/head
ts
// main.ts
import { createHead } from '@vueuse/head';

const head = createHead();
app.use(head);
vue
<!-- pages/About.vue -->
<script setup>
import { useHead } from '@vueuse/head';

useHead({
  title: 'About Us | MyApp',
  meta: [
    { name: 'description', content: 'Learn about our mission' },
    { property: 'og:title', content: 'About Us' },
  ],
});
</script>

Workaround 2: Prerendering

Use vite-plugin-prerender for static pages:

ts
// vite.config.ts
import prerender from 'vite-plugin-prerender';

export default {
  plugins: [
    prerender({
      routes: ['/', '/about', '/pricing'],
    }),
  ],
};

When Workarounds Aren't Enough

If you need:

  • Dynamic pages (blog posts, products)
  • Real-time content updates
  • Full SSR capabilities

It's time for Nuxt.

Part 2: Nuxt - Vue's SEO Solution

Nuxt is to Vue what Next.js is to React: the full-stack framework with SSR built in.

Setup

bash
npx nuxi init my-app
cd my-app
npm install
npm run dev

The Power of useSeoMeta

Nuxt's useSeoMeta composable is SEO perfection:

vue
<script setup>
useSeoMeta({
  title: 'About Us',
  description: 'Learn about our mission and team',
  ogTitle: 'About Us | MyApp',
  ogDescription: 'Learn about our mission and team',
  ogImage: '/og-about.png',
  twitterCard: 'summary_large_image',
});
</script>

For dynamic pages:

vue
<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute();
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`);

useSeoMeta({
  title: () => post.value?.title,
  description: () => post.value?.excerpt,
  ogTitle: () => post.value?.title,
  ogImage: () => post.value?.image,
});
</script>

Nuxt Image Optimization

Install the official module:

bash
npm install @nuxt/image
ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/image'],
});
vue
<template>
  <NuxtImg
    src="/hero.jpg"
    alt="Hero image"
    width="1200"
    height="630"
    loading="lazy"
    format="webp"
  />
</template>

Automatic Sitemap Generation

bash
npm install @nuxtjs/sitemap
ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/sitemap'],
  sitemap: {
    hostname: 'https://mysite.com',
  },
});

Dynamic routes are automatically included!

robots.txt

ts
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/dashboard/**': { robots: false },
  },
});

Or create public/robots.txt manually.

Common Nuxt SEO Mistakes

1. Using <script> Instead of <script setup>

The <script setup> syntax ensures proper SSR hydration.

2. Fetching Data Client-Side Only

vue
<!-- Bad - won't be in initial HTML -->
<script setup>
const { data } = useFetch('/api/posts', { server: false });
</script>

<!-- Good - SSR'd -->
<script setup>
const { data } = await useFetch('/api/posts');
</script>

3. Missing useHead for Static Meta

For truly static meta (like on the homepage):

ts
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      title: 'MyApp - The Best Thing',
      meta: [
        { name: 'description', content: 'Default description' },
      ],
      link: [
        { rel: 'canonical', href: 'https://myapp.com' },
      ],
    },
  },
});

4. Not Using Nuxt Content for Blogs

If you have a blog, use Nuxt Content:

bash
npm install @nuxt/content
md
---
title: My Blog Post
description: A great blog post
---

# My Blog Post

Content here...

Automatic SEO, sitemap integration, and markdown rendering.

Nuxt SEO Checklist

  • Use useSeoMeta on every page
  • Install @nuxt/image for image optimization
  • Set up @nuxtjs/sitemap
  • Add robots.txt with proper rules
  • Use useFetch with SSR (not client-only)
  • Add JSON-LD structured data
  • Test with nuxi preview before deploying

Quick Audit

bash
# Build and preview
npm run build
npm run preview

# Audit in another terminal
npx rankcli audit --url http://localhost:3000

RankCLI has built-in checks for Vue and Nuxt apps. Run a free audit.

Try RankCLI

Catch SEO issues before they hurt your rankings. Run your first audit in seconds.