Nuxt 3

Nuxt is a meta-framework over Vue 3: file-based routing, server-side rendering, static generation, auto-imported components and composables, and a server runtime for API routes.

The convenience features are pleasant and not the reason to adopt it. The reason is rendering.

Why rendering strategy is the deciding question

A plain Vite and Vue application ships an empty HTML shell and builds the page in the browser. This is invisible on a fast connection and has two consequences that matter for anything public.

Search engines and link previews see the shell. Google executes JavaScript, with delays and imperfectly; most other crawlers and every social preview generator do not. For a public data portal — findability being much of the point — client-side rendering means the content effectively does not exist to anything that has not run it.

The other is time to first content on a slow connection or a modest device. Empty shell, download the bundle, parse, execute, fetch data, render. Server rendering sends HTML that is already the page.

Nuxt makes rendering a per-route decision: server-rendered where it matters, static where content rarely changes, client-side for authenticated views where neither concern applies. The UCO portal is the case in this garden where that mattered.

What it costs

Code runs in two places. A component may execute on the server and again in the browser, so anything touching window, document, or localStorage breaks during server rendering. The fixes exist and the mental overhead is constant — every piece of code now carries an implicit question about where it runs.

Hydration mismatches are the characteristic Nuxt bug. Server-rendered HTML must match what the client would produce; if it does not — a timestamp formatted in a different timezone, a random ID, anything reading browser state — the framework warns and re-renders. The errors are unhelpful and the causes are usually small.

A server to operate. Server rendering means a running Node process, not static files on a CDN. That is real deployment surface, and it removes the main operational advantage of a static frontend.

For an authenticated internal application none of these are worth paying, and plain Vue with Vite is the better choice.

See also: Vue 3, Vite underneath, Node.js, Pinia with its SSR caveats, and the UCO portal.