Vue.js

Using Nuxt.js when a marketing site needs Vue and SEO

VUE

A client wanted the interactivity of a Vue single-page application for their product marketing site, but the site's traffic depends heavily on organic search, and a client-rendered SPA is a real risk for SEO if crawlers do not execute JavaScript reliably.

The core problem with a plain Vue SPA here

A standard Vue single-page app ships a nearly empty HTML shell and lets JavaScript build the actual page content in the browser. Search engine crawlers have gotten better at executing JavaScript before indexing a page, but "better" is not the same as "reliable," and for a client whose business genuinely depends on organic search ranking, betting the whole site on a crawler successfully executing a JavaScript bundle correctly, every time, was not a risk we were willing to take on their behalf.

How Nuxt solves it

Nuxt.js, which came out of the Vue ecosystem this year, solves this directly by rendering Vue components on the server and sending fully-formed HTML to the browser, then "hydrating" it into a normal client-side Vue app once the JavaScript loads. We get server-rendered pages for search engines and a fast, app-like experience for real visitors, from the same Vue components, with no separate templating system to maintain in parallel.

What we liked about the developer experience

  • File-based routing removed a chunk of boilerplate we would otherwise have written by hand with vue-router, since a new page is just a new file in the `pages` directory rather than a route definition plus a component plus a manual wiring step
  • The `asyncData` hook gave us a clean, documented place to fetch data that needs to be present before the initial server render, rather than the awkward "fetch after mount, show a loading state briefly" pattern a plain SPA needs
  • Built-in support for meta tags per page made handling per-page SEO metadata — title, description, Open Graph tags — far simpler than the manual `document.title` manipulation we would have needed otherwise

What we had to adjust for

Deploying it needed a small Node server rather than the plain static hosting we would use for a client-only SPA, which is a minor added cost in both hosting bill and operational surface area — there is now a running process that can crash or need scaling, where a purely static site would have none of that concern. We put it behind PM2 to at least get automatic restarts on a crash, treating it with the same seriousness we would any other production Node service rather than as an afterthought.

Some third-party libraries we would otherwise have reached for without a second thought assume a browser environment exists — they read from `window` or `document` at module load time — and needed either a server-side-safe alternative or a check to skip that code path during server rendering. This was the single biggest source of friction porting an existing component library over, and it is worth budgeting real time for on any Nuxt project pulling in an established component ecosystem that was not written with server rendering in mind from the start.

Results

Search Console showed the client's key marketing pages being indexed with their full rendered content within days of launch, compared to the client's previous templated site where crawl and indexing had generally been reliable but slow to reflect content updates. Time to first meaningful paint for real visitors also improved compared to what a pure client-rendered SPA would have delivered, since the browser has actual content to show immediately from the server response rather than waiting for a JavaScript bundle to download, parse, and execute before rendering anything at all.

For an SEO-sensitive marketing site that also wants genuine interactivity, the tradeoff was clearly worth it, and we expect Nuxt, or something like it, to become our default recommendation any time a client's Vue ambitions run into a genuine SEO requirement that a plain SPA cannot responsibly meet.

← Back to the journal

Have a project in mind?
Let’s talk.

Tell us where you are and where you want to go. We'll map the fastest route between the two.

Currently accepting new clients