Vue SEO that survives every crawler in the room.
Vue 3, Nuxt, Quasar, and Vite SPAs — all rendered to clean HTML for Google, Bing, GPTBot, ClaudeBot, and every social preview crawler. Without rewriting your reactivity layer.
Vue's reactivity is its strength and, for crawlers, its weakness. Anything bound through Composition API state, anything resolved in `onMounted`, anything fetched after navigation — invisible to bots without JS execution. UpRender solves that without forcing you onto Nuxt SSR or rebuilding around `useFetch`.
Where Vue loses crawlers.
A Vue SPA mounts at <div id="app"></div>. The runtime composes the UI, fetches data, resolves routes, and updates the DOM reactively. For human users this is the point. For crawlers it's a wall.
Googlebot will eventually render Vue, but the second-pass renderer skips routes that depend on data fetched in onMounted or async setup() blocks if they don't resolve fast enough. Nuxt SSR helps, but Nuxt requires you to author every data dependency through useFetch or useAsyncData — which is a non-trivial refactor on existing Vue projects.
Bingbot, Yandex, GPTBot, OAI-SearchBot, ClaudeBot, and every social crawler don't render Vue at all. They see the empty mount point and leave. Your Pinia / Vuex state is invisible. Your reactive <head> updates via useHead arrive after the bot is gone.
onMounteddata fetches invisible to non-JS bots — product details, reviews, prices- Vue Router routes share the same initial HTML — crawlers index one page
- Pinia / Vuex state never reaches crawlers without SSR
v-cloakand Vue transitions hide content from bots with strict render budgetsuseHead/<Head>meta updates happen client-side, too late for social bots- Hydration warnings when Nuxt SSR is partially adopted — silent SEO degradation
How UpRender fixes Vue indexability.
UpRender sits in front of your Vue or Nuxt app. Bot requests are detected at the edge and proxied through UpRender's render layer, which runs your real Vue app in a real browser, waits for reactivity to settle, captures the final DOM, and returns a clean HTML snapshot. Meta tags from useHead, Pinia-derived content, and <Suspense>-resolved components are all there.
For Nuxt SSR teams, UpRender works as a complement — it offloads bot traffic from your Nitro server, dramatically reducing the cost of being crawled by GPTBot, ClaudeBot, and the AI search agents that scrape aggressively. For Vue CSR teams, UpRender is the whole solution.
What changes the day you ship.
No Nuxt migration required
Keep your Vite + Vue 3 SPA exactly as it is. No `useFetch` rewrites, no Nuxt directory conventions, no Nitro server to operate.
Or: offload Nuxt SSR cost
Already on Nuxt SSR? UpRender absorbs bot traffic so your Nitro server only renders for human visitors — cutting infra cost on aggressive AI crawlers.
Pinia state in HTML
Pinia stores populated by `onMounted` actions show up in the bot snapshot, fully serialized into the final HTML. Reviews, prices, user-generated content — all visible.
Quasar PWA support
Quasar SPAs and PWAs render cleanly. Capacitor / Cordova hybrid stacks work too — same edge integration.
AI search citations
GPTBot, OAI-SearchBot, ClaudeBot, and Claude-SearchBot all get rendered HTML. Your Vue content becomes citable in AI answers and search summaries.
Social previews finally render
`useHead` Open Graph and Twitter Card updates are captured into the bot snapshot — link previews work on LinkedIn, Twitter, WhatsApp, Slack, Discord, and Pinterest.
Vue 2 legacy support
Still running Vue 2 with Vue Router 3? UpRender renders it cleanly while you plan the Vue 3 migration. SEO doesn't wait for tech debt.
Suspense and async components resolved
UpRender waits for `<Suspense>` boundaries and async `setup()` blocks to resolve before snapshotting — bots see the fully-composed page, not loading states.
No Nitro server to operate
For Vue CSR teams, UpRender eliminates the need to adopt Nuxt SSR and its Nitro server. No server to scale, no cold starts to optimize, no deployment complexity.
VitePress documentation indexed
VitePress doc sites with dynamic content, search, and interactive examples render completely — ensuring your documentation ranks alongside your product pages.
Sound familiar?
You built a Vue 3 SPA and Google only indexes the homepage
Your Vue Router routes all return the same HTML — a single div#app with a script tag. Google Search Console shows 1 indexed page out of hundreds. UpRender serves each route as distinct, fully-rendered HTML. Indexation coverage jumps from under 5% to over 90% within two weeks.
Your Nuxt SSR costs are climbing because of AI bot traffic
GPTBot, OAI-SearchBot, ClaudeBot, and Claude-SearchBot are crawling your Nuxt site tens of thousands of times daily, and every request hits your Nitro server. UpRender absorbs bot traffic at the edge — your Nitro server only renders for paying users. Teams typically see a 60–72% reduction in SSR compute costs.
Your Vue ecommerce site has broken social previews
Product links shared on LinkedIn and WhatsApp show blank previews because `useHead` sets OG tags client-side. Social bots don't execute JavaScript. UpRender captures the fully-resolved head tags and serves them to social crawlers — previews render correctly within minutes of deployment.
You're migrating from Vue 2 to Vue 3 and SEO can't regress
The Vue 3 migration will take months. In the meantime, both the Vue 2 production app and the new Vue 3 staging routes need to be indexable. UpRender works with both versions simultaneously — one edge worker, two Vue versions, zero SEO regression during the transition.
What crawlers actually see.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Vue App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="https://uprender.io/src/main.ts"></script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<title>Luxury Apartments in Barcelona | CityHaus</title>
<meta name="description" content="Browse 2,400+ luxury apartments..." />
<meta property="og:title" content="Luxury Apartments in Barcelona" />
<meta property="og:image" content="/images/barcelona-hero.jpg" />
<script type="application/ld+json">
{"@type":"RealEstateListing","name":"Luxury Apartments","price":"€850K"}
</script>
</head>
<body>
<div id="app">
<header><nav>Home | Listings | About</nav></header>
<main>
<h1>Luxury Apartments in Barcelona</h1>
<div class="listing-grid">
<article>2BR Penthouse · Eixample · €1.2M</article>
<article>3BR Villa · Pedralbes · €2.8M</article>
<article>1BR Loft · Born · €420K</article>
</div>
</main>
</div>
</body>
</html>Vue's reactive content resolves into the snapshot. Pinia state, useHead tags, and component output all appear in the HTML crawlers receive.
Vite middleware or edge worker.
Vue + Vite teams typically use the Vite plugin during development and a Cloudflare Worker or nginx config in production. Nuxt teams use the dedicated Nuxt module.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@uprender/nuxt'],
uprender: {
token: process.env.UPRENDER_TOKEN,
// Offload bot traffic — humans hit Nitro, bots hit UpRender
crawlers: ['google', 'bing', 'ai', 'social'],
// Recache when Nuxt content changes
revalidate: { onContentUpdate: true },
},
});- 1Install
@uprender/nuxt(Nuxt) or@uprender/vite(Vue CSR) - 2Add the module to your
nuxt.config.tsor Vite config - 3Set
UPRENDER_TOKENin your env - 4Deploy. UpRender begins serving rendered HTML to bot User-Agents immediately
- 5Validate with
curl -A 'GPTBot' https://yoursite.com/— you'll see fully composed HTML
One Vue integration. Every meta-framework.
Vue 3
Composition API, Options API, `<script setup>`
Nuxt 3
Universal, SPA, hybrid rendering
Vue 2
Legacy Vue 2 + Vue Router 3 stacks
Quasar
Quasar Framework SPA / PWA / SSR
Vite + Vue
Pure Vite SPA setups without Nuxt
VitePress
Documentation sites built on Vite
Gridsome (legacy)
Still maintained Gridsome 0.x projects
"The fastest fix we've ever shipped to production. Vue stayed Vue. Crawlers finally got HTML."
Teams shipping Vue with UpRender.
CityHaus made every listing findable before it expired.
Perishable inventory, slow crawlers. CityHaus was leaving high-intent traffic on the table because new listings weren't being indexed inside their active window. UpRender rendered the React SPA and auto-injected Schema.org/RealEstateListing markup — no frontend changes — and 91% of listings now rank within 7 days of going live.
WanderStay stopped losing bookings to broken previews
Their React SPA generated blank WhatsApp and Facebook previews — killing their referral engine. UpRender fixed it in a day.
The questions teams actually ask.
Often yes, for two reasons. First, Nuxt SSR runs on your origin — every GPTBot, OAI-SearchBot, ClaudeBot, and Claude-SearchBot crawl costs you Nitro compute. UpRender absorbs bot traffic, dramatically cutting your AI-bot bill. Second, partial-SSR setups (some pages SSR, some client-only) leave gaps that UpRender catches.
No. Stores are only used during real-user navigation. UpRender's render path is independent — it runs your Vue app in its own browser, captures the resulting HTML, and serves it. Your client store behavior is unaffected.
Yes. UpRender waits for reactivity to settle before snapshotting, which means `useHead` and `<Head>` updates — including OG tags, JSON-LD, canonical URLs — appear in the final HTML the bot receives.
Vue 2 with Vue Router 3 is fully supported. Many teams use UpRender as a bridge while migrating to Vue 3, keeping SEO intact during the transition.
Yes. UpRender's render path waits for `<Suspense>` boundaries to resolve before capturing the snapshot. Async components, lazy imports, and async `setup()` blocks all complete before the HTML is returned to the crawler.
Both libraries update meta tags client-side. UpRender's rendered HTML captures whatever they set, server-side, before the bot ever sees the page. You don't change how you author meta tags — UpRender just makes sure they reach the crawler.
Nuxt 3 supports per-route rendering rules (SSR, CSR, ISR, SWR). UpRender works regardless of which mode each route uses — it operates at the edge before Nuxt's rendering pipeline runs. Routes configured as client-only get pre-rendered by UpRender; SSR routes get their bot traffic offloaded.
Yes. Quasar PWA mode runs client-side only. UpRender serves the rendered HTML to crawlers while the PWA experience — service workers, offline caching, push notifications — continues to work for real users.
UpRender renders each localized route separately. If you use `vue-i18n` or `@nuxtjs/i18n` with path-based localization (`/en/products`, `/fr/products`), each locale gets its own cached snapshot with the correct language content, hreflang tags, and localized meta data.
Ship Vue that bots can read.
Free trial. No credit card. Most Vue teams see their first indexation lift inside 48 hours.