Nuxt 3, Vuetify, and Material Design Icons: A Production Build Headache
The Problem: You've successfully implemented Vuetify and Material Design Icons in your Nuxt 3 project, but when you build for production, the icons disappear!
Why is this happening?
The root cause lies in how Nuxt 3 handles asset loading in production. By default, it bundles all your assets (like images, fonts, etc.) into a single file. While this optimizes loading times, it can cause issues when you're working with external libraries that expect assets to be loaded independently.
Let's break it down:
Scenario: You have a simple Nuxt 3 app using Vuetify and Material Design Icons:
<template>
<v-app>
<v-main>
<v-icon>mdi-home</v-icon>
</v-main>
</v-app>
</template>
<script setup>
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import { createRouter, createWebHistory } from 'vue-router';
import { registerComponents } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
import 'vuetify/styles';
import '@mdi/font/css/materialdesignicons.css';
const app = createApp({});
const router = createRouter({
history: createWebHistory(),
routes: [],
});
const pinia = createPinia();
app
.use(router)
.use(pinia)
.use(registerComponents({ components, directives }))
.mount('#app');
</script>
This code will work perfectly in development mode. You'll see the home icon rendered correctly. However, in production, the icon will be missing.
Solution:
The solution is to tell Nuxt 3 to treat the Material Design Icons font as a separate asset that should not be bundled. This can be achieved using Nuxt's css
configuration.
Modify your nuxt.config.ts
file:
export default defineNuxtConfig({
css: [
'vuetify/styles',
'@mdi/font/css/materialdesignicons.css', // This is the key change
],
// ... other configurations
});
This tells Nuxt 3 to include the Material Design Icons font as a separate CSS file, ensuring it's correctly loaded in your production build.
Explanation:
- Vuetify: Provides the framework for the UI components.
- Material Design Icons: Offers a wide range of icons, which are typically loaded as a font.
- Nuxt 3 Bundling: Nuxt 3, by default, combines all your assets into a single bundle, which may conflict with the way external libraries like Material Design Icons expect assets to be loaded.
css
Configuration: Thecss
configuration withinnuxt.config.ts
allows you to specifically control how Nuxt 3 handles CSS files. By listing'@mdi/font/css/materialdesignicons.css'
in thecss
array, you tell Nuxt 3 to treat it as a separate asset, ensuring it's properly loaded.
Important Considerations:
- Caching: You might need to clear your browser cache after implementing this change to ensure the new CSS is loaded.
- Other Libraries: If you're using other libraries that rely on external fonts or assets, you might need to apply similar adjustments to their configurations within your Nuxt 3 project.
By making this small configuration change, you can ensure your Material Design Icons are correctly loaded in your production build, preserving the sleek look of your Vuetify application.