SEO for SaaS Apps Built with Nuxt
SaaS products have a different SEO challenge than blogs or e-commerce sites. Most of your product is behind a login. The pages that need to rank are your landing page, pricing, feature pages, comparison pages, and blog — the marketing layer.
Here's how to get that layer right in Nuxt.
Server-side rendering is a prerequisite
Client-side-rendered Vue apps are an SEO liability. Googlebot has improved its JavaScript rendering, but it's still slower and less reliable than rendering HTML server-side.
Nuxt with SSR (the default) generates full HTML on the server for every request. Crawlers see complete, indexable content immediately.
If you're using Nuxt and haven't explicitly disabled SSR, you're already in good shape here. If you have a CSR-only configuration for performance reasons, consider adding routeRules to SSR specific routes:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { ssr: true },
'/pricing': { ssr: true },
'/features/**': { ssr: true },
'/blog/**': { ssr: true, prerender: true },
'/app/**': { ssr: false } // Authenticated app can be CSR
}
})
Meta tags with useSeoMeta
Nuxt 3 ships with useSeoMeta — a type-safe composable for all meta tags:
useSeoMeta({
title: 'Project Management for Remote Design Teams',
description: 'Async video feedback, time tracking, and client portals — all in one tool.',
ogTitle: 'Project Management for Remote Design Teams',
ogDescription: 'Async video feedback, time tracking, and client portals — all in one tool.',
ogImage: 'https://yourproduct.com/og-image.png',
twitterCard: 'summary_large_image',
canonicalUrl: 'https://yourproduct.com/'
})
Set these on every public-facing page. Don't use the same meta description across multiple pages — Google penalises duplicate meta.
Dynamic meta for parameterised pages
For pages with dynamic content (blog posts, feature pages, case studies), generate meta from the content:
<script setup>
const { data: post } = await useAsyncData('post', () =>
queryCollection('blog').path(route.path).first()
)
useSeoMeta({
title: post.value?.title,
description: post.value?.description,
ogImage: post.value?.image,
})
</script>
Sitemap
Submit a sitemap to Google Search Console. @nuxtjs/sitemap generates one automatically:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/sitemap'],
site: {
url: 'https://yourproduct.com'
},
sitemap: {
urls: async () => {
// Include any dynamically generated URLs
const posts = await fetchBlogPosts()
return posts.map(post => `/blog/${post.slug}`)
}
}
})
Exclude authenticated routes (anything under /app, /dashboard, etc.) — they're not indexable.
Structured data for rich results
Structured data (JSON-LD) helps Google understand your content and enables rich result features in search.
For a SaaS product, the most useful schemas:
- Organization — your company details, logo, social profiles
- WebSite — enables sitelinks search box
- FAQPage — FAQ sections display directly in search results
- BlogPosting — article details for blog posts
<!-- In your default layout or homepage -->
<script setup>
useSchemaOrg([
defineOrganization({
name: 'YourProduct',
url: 'https://yourproduct.com',
logo: 'https://yourproduct.com/logo.png',
sameAs: [
'https://twitter.com/yourproduct',
'https://linkedin.com/company/yourproduct'
]
})
])
</script>
Use nuxt-schema-org to handle the implementation details.
Core Web Vitals
Google uses Core Web Vitals (LCP, CLS, INP) as a ranking signal. The main frontend culprits:
LCP (Largest Contentful Paint — load speed):
- Use
@nuxt/imagefor automatic image optimisation - Preload your hero image:
<link rel="preload" as="image" href="..."> - Minimise render-blocking third-party scripts
CLS (Cumulative Layout Shift — visual stability):
- Always specify
widthandheighton images - Avoid injecting content above existing content
- Reserve space for dynamic content (ads, banners) with CSS
INP (Interaction to Next Paint — interactivity):
- Break up long JavaScript tasks
- Defer non-critical scripts
Run npx nuxi analyze to identify bundle size issues, and check Lighthouse in Chrome DevTools for CWV scores.
Comparison and alternative pages
For SaaS SEO, comparison pages ("Product vs Competitor") and alternative pages ("Best Competitor alternatives") consistently rank well and attract high-intent traffic.
These pages need:
- Honest, useful comparison (not just a table where you win every category)
- Your genuine positioning — what you're better at, and what you're not
- Clear CTA for the segment that should choose you
They're the highest-ROI content type for most B2B SaaS products.
Tracking SEO performance
- Google Search Console: which queries bring traffic, which pages rank, which have click-through rate problems
- Ahrefs or SEMrush: keyword research, competitor gap analysis, backlink monitoring
- Lighthouse: technical performance and CWV scores
Check Search Console weekly. It surfaces crawl errors, manual penalties, and opportunity keywords before you'd find them any other way.
Need a well-structured, SEO-ready marketing site? Let's build it →