Nuxt not only supports server-side rendering (SSR) but also offers powerful static site generation (SSG) features. This enables developers to easily deploy websites to any platform that supports the JAMstack architecture.
This article will explore how to generate static sites using Nuxt and provide detailed insights into controlling various behaviors and configuration options during the generation process. From pre-rendering settings to managing assets output, we'll walk through how to effectively manage static site generation with Nuxt.
Generating a static site in Nuxt is straightforward; simply run the following command:
nuxt generate
By default, Nuxt pre-renders each page when generating a static site, producing the corresponding HTML files.
If you prefer to generate a client-side rendered SPA without pre-rendering, you can disable this feature by setting ssr
to false
in your configuration.
export default defineNuxtConfig({
ssr: false
})
Nuxt uses Nitro for pre-rendering and outputs the static site to the default .output/public
directory.
If you need to change the output directory, you can customize the output path using the following configuration:
export default defineNuxtConfig({
nitro: {
output: {
dir: resolve('./.my-output'),
publicDir: path.join(__dirname, './.my-output/public'),
}
}
})
After pre-rendering and generating the static site, Nuxt creates a structured directory by default.
In this section, we'll explain the purpose of each file and directory and explore the relevant configuration options.
_nuxt
This directory contains the site's assets, including all CSS and JavaScript files.
You can customize the name of this directory by configuring app.buildAssetsDir
.
export default defineNuxtConfig({
app: {
buildAssetsDir: '/_my_assets/'
}
})
_nuxt/builds
This directory stores files related to the App Manifest, which includes information about the latest build, such as routes and timestamps.
If you don't need these files, you can disable this feature by setting experimental.appManifest
to false
, preventing the directory from being generated.
export default defineNuxtConfig({
experimental: {
appManifest: false
}
})
_nuxt/*.js
Nuxt uses Vite with Rollup for JavaScript bundling.
You can control the output format of JavaScript files by configuring vite.build
and setting rollupOptions
. Some common examples include:
output.entryFileNames
, output.chunkFileNames
)export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
entryFileNames: '_nuxt/my-[name]-[hash].js',
chunkFileNames: '_nuxt/my-[name]-[hash].js'
}
}
}
}
})
*.js
files into a single file (output.inlineDynamicImports
)export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
inlineDynamicImports: true
}
}
}
}
})
_nuxt/*.css
and Other AssetsYou can configure the output format for CSS and other assets by modifying the vite.build
configuration. Some settings include:
Customizing the output file name format (rollupOptions.output.assetFileNames
)
export default defineNuxtConfig({
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: '_nuxt/my-[name]-[hash].[ext]',
// or
assetFileNames: (assetInfo) => {
if (assetInfo?.name?.endsWith('.css'))
return '_nuxt/style-[name]-[hash].css'
return '_nuxt/[name]-[hash].[ext]'
}
}
}
}
}
})
This config will affect all assets, including images, fonts, etc.
Merging all *.css
files into a single file (cssCodeSplit
)
export default defineNuxtConfig({
vite: {
build: {
cssCodeSplit: false
}
}
})
For files stored in the assets/
directory, such as images or fonts, they may be copied to the _nuxt
directory. If you prefer to inline all assets instead of copying them, you can configure this using the following setting:
export default defineNuxtConfig({
vite: {
build: {
assetsInlineLimit: Number.MAX_SAFE_INTEGER
}
}
})
_payload.json
This file is used during SSR or pre-rendering to pass the payload data for the page.
If you don't need this file to be loaded externally and want to prevent it from being generated, you can disable it by setting payloadExtraction
to false
.
export default defineNuxtConfig({
experimental: {
payloadExtraction: false
}
})
200.html
and 404.html
These files are generated during SSG to serve as fallback pages for SPA websites.
If you don't need them, you can prevent their generation by configuring nitro.prerender.ignore
.
export default defineNuxtConfig({
nitro: {
prerender: {
ignore: ['/200.html', '/404.html']
}
}
})
index.html
Nuxt generates an index.html
file for every page on your site, serving as the entry point for the static site.
These Resource Hints help browsers load resources in advance, speeding up the website's loading time.
<!DOCTYPE html>
<html data-capo="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preload" as="fetch" crossorigin="anonymous" href="/_payload.json?93d23bea-82a5-406d-92a4-feb73d5bf1b8">
<link rel="modulepreload" as="script" crossorigin href="/_nuxt/D9xaLgge.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/BXlAlM0q.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/BRJtm5m-.js">
<link rel="prefetch" as="script" crossorigin href="/_nuxt/CZvqSstT.js">
<script type="module" src="/_nuxt/D9xaLgge.js" crossorigin></script>
</head>
<body>
...
</body>
</html>
If you need to disable preload
and prefetch
, you can customize them using Nuxt Hooks. Below is an example showing how to disable these features:
export default defineNuxtConfig({
hooks: {
'build:manifest': (manifest) => {
console.log('manifest', manifest)
for (const key in manifest) {
manifest[key].dynamicImports = []
manifest[key].prefetch = false
manifest[key].preload = false
}
}
}
})
Nuxt offers a user-friendly static site generation process, with many optimizations out of the box that save developers from performing repetitive tasks. Whether itβs pre-rendering, asset management, or directory structure, Nuxt handles everything in an organized manner.
At the same time, Nuxt allows for extensive customization, giving developers the flexibility to control every detail of the output. This balance of simplicity and flexibility makes Nuxt an ideal choice for generating efficient static websites.
This article is inspired by my recent open-source project, nuxt-single-html
π. Itβs a tool that allows you to inline all JavaScript, CSS, and other assets into a single HTML file when generating static sitesβperfect for certain specific use cases. Feel free to check it out!