Trying Nuxt & VitePress

Trying Nuxt & VitePress

November 18, 2025

TL;DR

Ive had pening for a while to try Nuxt, and I think it is a great framework for building full-stack web applications and websites with Vue.js.

Nuxt Content CMS and its ambicious roadmap (a full MIT git based CMS) was a great surprise too: https://content.nuxt.com/docs/studio/roadmap

Intro

Almost the end of the year, time to try out some new SSG.

This time it is the turn of Nuxt

Apache v2 | Portfolio template made with Nuxt 3, Nuxt Content v3, NuxtUI v3 and TailwindCSS v4

The theme brings multilanguage/i18N working out of the box!

The first thing I noticed: it takes much more time to load compared to Astro or NextJS sites, and much more than HUGO.

You just need 2 things: NPM and NodeJS.

Setup Node and NPM - x86/ARM64/ARM32 📌
sudo apt update && sudo apt upgrade

#install NodeJS https://deb.nodesource.com/
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs

# Verify installation
node -v   # Should show Node.js version - 20.18.1
npm -v    # Should show npm version - 10.8.2

And the repo :)

Nuxt Canvas Theme

Bun | Example with NUXT - HUGO Canvas and Resend ⏬

Really cool Portfolio template made with Nuxt 3, Nuxt Content and TailwindCSS

#git clone https://github.com/HugoRCD/canvas
git clone https://github.com/JAlcocerT/canvas
#bun install
#bun dev #dev server
#bun generate #static proy
#bun start #prod server

You can spin a server and make ASTRO Remote Development in it.

Specially because the theme brings docker compose support:

sudo docker compose -f docker-compose.local.yml up -d
#sudo docker compose -f docker-compose.local.yml down

The Canvas theme was so great to me, that i decided to fork it to understand it better:

What I liked:

#make help
make install
make dev

See at localhost:3000

  1. NuxtCMS integration

alt text

  1. The search+tag system working together: and also during dev

alt text

  1. The docker compose support out of the box: i just added the makefile
make docker-up
  1. Static build and serving:
make generate
#@npx serve .output/public
#cd .output/public && python3 -m http.server 8080

only to realize that something is off…

  1. Cloudflare D1 Database x NUXT CMS?

When using serverless platforms, it’s important to note that Nuxt Content v3 relies by default on SQLite for content storage.

Since these platforms do not support SQLite natively, we recommend connecting Canvas Portfolio to an external database such as:

  • PostgreSQL
  • Turso
  • Cloudflare D1
About CF D1 x Nuxt Content Git based CMS 🌍

Cloudflare D1 is a managed, serverless SQL database offered by Cloudflare.

It is built on the SQLite query engine, giving it familiar SQL semantics, but optimized to run on Cloudflare’s global network, particularly alongside Cloudflare Workers and Pages projects.

The key features of D1 are:

  • Serverless: No infrastructure to manage, provision, or scale. It’s usage-based pricing.
  • Edge Deployment: Designed to eventually store data closer to your users globally, resulting in lower latency for read operations (though currently, write operations are generally routed to a single primary location).
  • SQLite Compatibility: Uses a familiar SQL dialect, making it easy to integrate with existing ORMs and tooling.
  • Built-in Features: Includes disaster recovery, backups, and a “Time Travel” feature for point-in-time recovery.

🤝 Relationship to Nuxt Content

Nuxt Content is a module for Nuxt applications that turns files (like Markdown, YAML, or JSON) into a powerful, database-like API.

By default, Nuxt Content reads these files directly from your repository and processes them at build time or during development. However, for a fully dynamic or large-scale application deployed on Cloudflare, Cloudflare D1 provides an optional, persistence layer for that content.

The relationship works like this:

  1. Deployment Target: Nuxt Content is designed to integrate with the Cloudflare Pages deployment preset.
  2. Database Integration: The module automatically detects the Cloudflare Pages environment and configures itself to use a D1 database binding (typically named DB).
  3. Content Persistency: Instead of reading files from the file system, the Nuxt Content module can use the D1 database to store and query your content. This makes your content dynamic and allows it to be updated or retrieved globally via the D1 database.
  4. Full-Stack DX (Developer Experience): Tools like NuxtHub and specific Nuxt modules simplify the process, allowing you to easily connect your Nuxt 3 application’s API routes (running on Cloudflare Workers) to D1 for content and data management.

In essence, D1 transforms Nuxt Content from a module that works primarily with static files into a truly full-stack, globally distributed CMS backend.

This video provides an overview of how to connect and use D1 within a Nuxt application: Cloadflare D1 database in Nuxt.

That is absolutely correct!

If your goal is to create a blog using Nuxt Content and deploy it statically, you can and should use Static Site Generation (SSG) mode.

Yes, You Can Deploy Statically (SSG) 💯

You can treat Nuxt Content exactly like you would treat Astro or any other static site generator (SSG).

  1. No D1 (or Database) Required: If you are only using the files (Markdown, YAML, etc.) stored in your local repository’s content/ directory, you do not need Cloudflare D1, SQLite, or any other database.
  2. Build Time Rendering: In SSG mode (often configured using ssr: true and a static adapter), Nuxt Content reads all your Markdown files during the build process (npm run build). It renders every page into a static HTML file.
  3. Deployment: The resulting output folder (typically .output/public or dist) contains only HTML, CSS, and JavaScript. You can deploy this entire folder to any static hosting provider (Netlify, Vercel, Cloudflare Pages, GitHub Pages, etc.).

How Nuxt Content Works in SSG Mode

The nuxt-content module acts as a powerful parser and query engine at build time:

ComponentSSG Mode Behavior
Data SourceReads files directly from the local content/ directory.
APIThe Content API (/api/_content...) is pre-rendered into static JSON files during the build.
Dynamic FeaturesAny dynamic content is usually handled by client-side JavaScript fetching the pre-rendered JSON.
PersistenceNone required; the HTML and JSON are the “persistence.”

💡 When You Would Need D1

You would only need to consider Cloudflare D1 if:

  1. You want a true CMS backend where you can update content without redeploying the entire site (i.e., you want to update content via an API/UI).
  2. You have a large, highly dynamic site where querying content live is necessary, and you are deploying on the Cloudflare ecosystem (Workers/Pages).

For a typical blog where you update content by committing a new Markdown file, SSG is the simplest and fastest way to deploy.

Would you like help setting up your nuxt.config.ts file for optimal SSG deployment?

  1. Integration with Resend mail API to get leads

Resend mail API working with NUXT Canvas Theme

About Nuxt

Nuxt is a free and open-source framework (not an SSG!)

Wth an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.

MIT | The Intuitive Vue Framework.

Nuxt and Next.js both offer full stack features but have differences reflecting their Vue and React bases, respectively.

Nuxt Full Stack Features

  • Nuxt (based on Vue) provides built-in server-side rendering (SSR), static site generation (SSG), automatic routing, and zero-config TypeScript support. It includes a server framework to create APIs, handle backend logic, and fetch data from databases within the same codebase.
  • It uses Vite as a bundler for fast development with hot module replacement and code splitting.
  • Nuxt emphasizes convention-over-configuration, providing a modular architecture with pre-built modules for authentication, PWA support, and SEO optimization, speeding up development.
  • The Nitro engine in Nuxt enables flexible deployment targets and backend functionality, supporting a full-stack experience seamlessly integrated with Vue syntax.
FeatureNuxt (Vue)Next.js (React)
Base FrameworkVue.jsReact
SSR / SSG SupportBuilt-in SSR & SSGSSR, SSG, and advanced ISR
Backend/API HandlingBuilt-in server framework (Nitro)API routes for backend logic
Development SpeedConvention-over-configurationMore configuration, flexible
PerformanceFast with Vite bundlerHigh performance with Turbopack (upcoming)
Deployment IntegrationSupports various targetsOptimal integration with Vercel
Ecosystem & CommunitySmaller but active Vue communityLarger React ecosystem and tooling

Overall, Nuxt excels in developer velocity for Vue-based full stack apps with intuitive setup and modularity, while Next.js offers greater flexibility, advanced React features, and scalability for complex projects.

Nuxt is an open-source, full-stack framework for building web applications using Vue.js.

It simplifies the development of complex applications by providing an opinionated structure, automatic routing, and multiple rendering modes out of the box.

Nuxt is inspired by Next.js, a similar framework for React.

Nuxt and SSG (Static Site Generators)

Nuxt is not just a static site generator, but it can act as one.

It offers several rendering modes, including static site generation (SSG), which puts it in a similar category to frameworks like Astro or Hugo, but with some key differences.

Nuxt’s Rendering Modes

Nuxt provides a versatile rendering system that allows you to choose the best approach for your project:

  1. Single-Page Application (SPA): The entire application is rendered by the browser after it loads the initial HTML, CSS, and JavaScript. This is the traditional way of building a Vue app, and it’s great for highly interactive web apps.
  2. Server-Side Rendering (SSR): The server renders the initial HTML for each page, which is then sent to the browser. This improves initial load performance and SEO. Once loaded, the page becomes a fully interactive SPA. Nuxt calls this “Universal” rendering.
  3. Static Site Generation (SSG): Nuxt generates a static HTML, CSS, and JavaScript file for each page at build time. These files can be served from any static host or CDN. This provides the best performance and security and is ideal for content-heavy sites like blogs or documentation.

Nuxt and JavaScript ☕️

Nuxt is deeply rooted in JavaScript, as it’s built on top of the Vue.js framework, which is a JavaScript library for building user interfaces.

⚠️
See more about TS and JS Frameworks

It uses JavaScript to handle almost every aspect of an application, from front-end interactivity to server-side logic.

  • Vue.js: Nuxt is a meta-framework for Vue.js. It leverages Vue’s component-based architecture and reactivity system. All the components and pages you create in a Nuxt application are essentially Vue components written in JavaScript (or TypeScript).
  • Node.js and Nitro: Nuxt’s server-side capabilities are powered by a server engine called Nitro, which is built on Node.js. This allows Nuxt to run JavaScript code on the server, which is essential for features like Server-Side Rendering (SSR) and API routes.
  • Tooling: Nuxt integrates popular JavaScript build tools like Vite or Webpack to bundle and optimize your application’s code for production.

Nuxt Content CMS

If you have been finding that connecting a CMS to a SSG is hard, Nuxt Content CMS is a great option.

MIT | The powerful Git-based CMS designed specifically for Nuxt developers.

Nuxt vs. Astro and Hugo

While all three can be used to generate static sites, they have different philosophies and use cases:

  • Hugo: This is a pure static site generator written in Go. Its primary focus is on lightning-fast build times and serving static content. It’s not a JavaScript framework, so it doesn’t provide the same level of client-side interactivity or component-based development as Nuxt or Astro. It’s best suited for blogs, portfolios, or documentation websites where content is king and interactivity is minimal.

  • Astro: Astro is a modern SSG that champions a “zero-JS by default” approach. It uses a unique “Islands Architecture,” where pages are pre-rendered to static HTML, with small, interactive “islands” of JavaScript-enabled components added only where needed. This results in incredibly fast websites with a minimal JavaScript payload. Astro is framework-agnostic, meaning you can use components from different frameworks like Vue, React, or Svelte within the same project. It is great for content-heavy sites that need a bit of interactivity.

  • Nuxt: Nuxt is a full-stack Vue framework. While it can be used as an SSG, its main strength lies in its ability to build complex, full-stack applications with server-side rendering, API routes, and a rich ecosystem of modules. Nuxt ships with more JavaScript by default than Astro, as its core philosophy is building a complete, cohesive application, whether it’s an SPA, SSR, or SSG.


Conclusions

The good thing about SSGs is that they power content with markdown.

Allowing you to plug easily these kind of LLMs:

Dont forget to validate the web performance:

And…VitePress SSG

VitePress is a Vue-powered static site generator and a spiritual successor to VuePress, built on top of Vite.

MIT | Vite & Vue powered static site generator.

Effortlessly create beautiful documentation sites with just markdown.

#npx vitepress init
npm install vitepress --save-dev

#npm run docs:dev
npx vitepress dev docs #go to localhost:5173 and there you go!
git clone https://github.com/vuejs/vitepress
cd vitepress/docs
npm install
npm run dev

Have a look to: https://vitepress.dev/guide/routing

VitePress is a Vue-powered static site generator and a spiritual successor to VuePress, built on top of Vite.


FAQ

Good Practices for Web Repositories📌
  • Add a .gitignore and include the node_modules folder
node_modules
  • Add a docker ignore if you plan to build images:
#add .env files if any

Outro

Brand colors with F/OSS

npm i bootstrap-icons

Official open source SVG icon library for Bootstrap.

⚡️ Icon Explorer with Instant searching, powered by Iconify

npm install --save-dev @iconify-icon/react

Universal icon framework. One syntax for FontAwesome, Material Design Icons, DashIcons, Feather Icons, EmojiOne, Noto Emoji and many other open source icon sets (over 150 icon sets and 200k icons). SVG framework, React, Vue and Svelte components!

And more! Font Awesome works with Require.js, Rails with Turbolink, and jQuery!

add this to your css

@import "../../node_modules/light-icons/dist/light-icon.css";

Handpicked collection of premium & light-wighted icons as font

Simply beautiful open-source icons

FavIcons for NextJS

  1. Go to the theme folder
  2. Add a /static folder
  3. Add the files generated with the website

Adding addsense

Including the Google AdSense script in theof every page generated by Hugo is straightforward.

  1. Step 1: Locate Your Header Template

In A Hugo site’s directory, navigate to the layouts folder: themes/PaperMod/layouts/partials/head.html

Find the partial template responsible for thesection of your pages.

This is commonly located in layouts/partials and might be named head.html or similar.

If you use astro, they are normally at src/layouts/BaseLayout.astro

You will add something like this script:

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1234567890"
     crossorigin="anonymous"></script>

You also need to get the ads.txt (get it here https://www.google.com/adsense/new/u/0/pub-1816803660718163/sites/detail/url=yourwebsite.com)

to the root directory, for example in /public, with info similar to:

google.com, pub-123456789, DIRECT, abcd124fgthrk9876

You can plug google adsense not only to Nuxt, but to any other website you build.

How to add ads.txt to a HUGO Website - Google Adsense 📌
  1. Create an ads.txt file in your Hugo project’s static directory. The static folder in Hugo is where you put any files you want to be copied directly to the root of your build output.

alt text

  1. Add your content to the ads.txt file:
google.com, pub-123456, DIRECT, abcdef123456
  1. Build your Hugo site:

  2. Verify the output by checking the public directory (Hugo’s default output folder). You should find the ads.txt file in the root of public:

  3. Deploy your site as usual. The ads.txt file should now be available at https://yourdomain.com/ads.txt.

This method ensures that ads.txt is part of your site’s root directory in the final build output, as required by ad networks.

HUGO adsense txt