Nuxt 4 + @nuxt/content + Vercel: Technical Stack and Architecture Decisions for a Personal Blog
An architectural perspective on the technical decisions behind this blog: why Nuxt 4 is used for an SSR developer blog, why @nuxt/content serves as the content layer, and the trade-offs around multilingual support, image optimization, deployment, and analytics.
This article is not a tutorial, but a record of technical decisions made at the beginning of the project.
The goal of this blog is not to showcase UI experiments or practice frameworks, but to serve as a long-term platform for writing and technical accumulation.
From an architectural perspective, this blog represents a typical content-driven site, whose objective is to maintain a long-term balance between content production, performance, and deployment cost.
Therefore, the technical stack must satisfy:
- Long-term maintainability
- Content-first workflow
- Minimal operational overhead
The goal is not to pursue the newest technology, but to minimize the overall maintenance cost of the project.
🧭 Technology Overview
Core stack:
- Framework: Nuxt 4
- Content: @nuxt/content
- UI: @nuxt/ui + Tailwind
- i18n: @nuxtjs/i18n
- Image: @nuxt/image + build metadata
- Deploy: Vercel
- Analytics:Google Analytics (GA4)
🚀 Why Nuxt 4 Instead of Pure Vue
Compared to static site generation (SSG), SSR provides more stable first-load performance and SEO results for continuously updated developer blogs.
Key advantages:
- Built-in SSR with strong SEO characteristics
- Convention-based routing and layouts
- Smooth integration with content, image, and i18n ecosystems
Building these manually with Vue would shift effort toward infrastructure instead of content.
📝 Choosing @nuxt/content
A blog is fundamentally a content product.
Important considerations:
- Markdown writing experience
- Git-based version tracking
- Multilingual content organization
@nuxt/content enables:
- Content stored directly in the repository
- Natural querying via queryCollection()
- Schema validation through content.config.ts
This approach aligns with a static-first architecture and avoids the operational cost of Headless CMS platforms such as Strapi or Contentful.
🎨 UI Layer: @nuxt/ui + Tailwind
Goals:
- Consistency first
- Customization later
@nuxt/ui provides structured components, while Tailwind handles visual customization.
A maintainable approach:
- Centralized theme configuration
- Brand-level styling via CSS variables
🌍 i18n as a First-Class Architectural Capability
The blog is designed as a multilingual site from day one supporting zh / ja / en.
Benefits:
- Route and language alignment
- Locale-based content filtering
- Independent evolution of UI text and articles
🖼 Image Optimization Strategy
Images are a major performance risk.
Two-layer approach:
- Runtime optimization via @nuxt/image
- Build-time metadata generation
Predefined dimensions effectively reduce Cumulative Layout Shift (CLS).
Blog performance issues are often build-time problems, not runtime problems.
☁️ Deployment with Vercel
Reasons:
- Seamless Nuxt deployment
- Fast preview environments
- Low operational overhead
📊 Analytics:Google Analytics (GA4)
Continuous optimization of a content-driven site relies on a feedback loop. For analytics, I chose Google Analytics (GA4) instead of relying on the built-in analytics provided by the hosting platform.
There are three main reasons:
- GA4 provides a more mature analytics system for content-driven sites, with richer data dimensions.
- It allows long-term data retention, which is important for observing content trends over time.
- It is decoupled from the hosting platform and does not depend on a specific deployment service.
For a personal blog, the analytics requirements are actually quite simple:
- Which articles receive consistent traffic
- Which countries or regions users mainly come from
- What kinds of topics users tend to focus on
Although GA4’s event-based data model is more complex than traditional analytics systems, in a blog scenario basic page view tracking is usually sufficient.
Integrating GA4 into a Nuxt project is also straightforward.
It can be injected globally at the application level using the nuxt-gtag module.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["nuxt-gtag"],
gtag: {
id: "G-XXXXXXXXXX",
},
});
⚖️ Trade-offs
- Dependency upgrades require attention
- Multilingual content increases workload
These costs are acceptable for sustainable iteration.
✅ Conclusion
The core logic:
- Nuxt 4 provides the engineering foundation
- @nuxt/content unifies writing and versioning
- @nuxt/ui + Tailwind balance speed and flexibility
- i18n, Image, Vercel, and Analytics support scalability
This represents a practical developer blog architecture, focused not on technical complexity, but on enabling long-term content creation.