Switch up the default font in your Nuxt 3 and Vuetify 3 project

I've been doing a lot of searching on Google, but I can't seem to find the solution. It seems like the challenge might be that the Nuxt 3 + Vuetify 3 combination isn't widely used yet?

My current task is to implement a custom default font. I've attempted to do this through nuxt.config.ts in the same way I did with Nuxt 2.

vuetify: {
    customVariables: ["~/assets/variables.scss"],
    treeShake: true,
  },

However, it's not working as expected.

Right now, I'm using plugins/vuetify.ts to define the theme and colors. I believe the font should be set there, but I'm unsure how to do it.

import { createVuetify, ThemeDefinition } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";

import "@mdi/font/css/materialdesignicons.css";

const myTheme: ThemeDefinition = {
    dark: false,
    colors: {
        primary: "#HEXHEX",
    },
    variables: {}
};

export default defineNuxtPlugin(nuxtApp => {
    const vuetify = createVuetify({
        components,
        directives,
        theme: {
            defaultTheme: "myTheme",
            themes: {
                myTheme
            }
    },
    });

    nuxtApp.vueApp.use(vuetify);
});

The themes are functioning correctly, but I'm uncertain about how to replace the default fonts/styles. Has anyone encountered this issue and successfully resolved it?

Answer №1

After encountering the same issue, I managed to resolve it by manually importing some CSS in my nuxt.config.js

// nuxt.config.js
export default defineNuxtConfig({
  css: ['vuetify/lib/styles/main.sass', '@/assets/main.css'],
  build: {
    transpile: ['vuetify'],
  },
  ...
})

Additionally, make sure to add the following code in your CSS file:

/* main.css */
@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 300;
    font-display: swap;
    src: url('./fonts/Roboto-Light.ttf') format('truetype');
}

Answer №2

To customize the font in Vuetify 3, you need to adjust the $body-font-family variable.
Firstly, make sure you have correctly set up Vuetify 3 and Nuxt 3 following the instructions in the official Vuetify documentation.

The majority of the relevant documentation is available at: SASS-variables

You will also require a Vuetify plugin in your Nuxt project:

/* plugins/vuetify.ts */
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import "vuetify/styles";

export default defineNuxtPlugin(nuxtApp => {
  const vuetify = createVuetify({
    components,
    directives,
    // Additional Vuetify settings can be added here
  })

  nuxtApp.vueApp.use(vuetify)
})

In your nuxt.config.js, integrate this plugin like so:

/* nuxt.config.js */
import vuetify from 'vite-plugin-vuetify'

export default defineNuxtConfig({
  css: ['@/assets/global.scss'],

  modules: [
    async (options, nuxt) => {
      nuxt.hooks.hook('vite:extendConfig', config => config.plugins.push(
        vuetify({
          styles: { configFile: new URL('assets/settings.scss', import.meta.url).pathname }
        })
      ))
    }
  ],
  
  // Other Nuxt configuration details can be added here
})

You can specify a custom font in /assets/global.scss:

// /assets/global.scss
// Customize global scss settings
@font-face {
  font-family: 'Open Sans';
  src: url("OpenSans-Regular-webfont.woff") format("woff");
  font-weight: 400;
  font-style: normal;
}

In the file assets/settings.scss, you can modify Vuetify SCSS variables such as:

// /assets/settings.scss
// Adjust specific Vuetify settings
@use 'vuetify/settings' with (
    $utilities: false,
    $button-height: 40px,
    $body-font-family: 'Open Sans'
);

If you explore /node_modules/vuetify for $body-font-family, you will discover other variables that can be tweaked to customize the Vuetify font.

Answer №3

In my setup, I'm using a combination of Nuxt3 (v3.1.1) and Vuetify3 (v3.1.3) to globally change the font for Vuetify and its utility classes like (.text-h3).

My recommendation is to first follow this tutorial to set up Vuetify + Nuxt and then utilize Treeshaking for Nuxt to dynamically import only the components you need. Your nuxt.config.js should resemble something like this:

import vuetify from "vite-plugin-vuetify";

export default defineNuxtConfig({
  css: [
    "vuetify/lib/styles/main.sass",
  ],
  build: {
    transpile: ["vuetify"],
  },
  modules: [
    async (options, nuxt) => {
      nuxt.hooks.hook("vite:extendConfig", (config) =>
        config.plugins.push(vuetify())
      );
    },
  ],
});

Afterwards, create a .scss file where you can customize Vuetify defaults:

// assets/vuetifyTheme.scss
$font: "arial", sans-serif;

@use 'vuetify' with (
  $body-font-family: $font,
);

Then, import vuetifyTheme.scss at the top of your plugins/vuetify.ts:

// plugins/vuetify.ts
import "@/assets/vuetifyTheme.scss";
import { createVuetify } from "vuetify";

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
       ssr: true,
    },
  });

  nuxtApp.vueApp.use(vuetify);
});

Your app should now display 'arial' as the default font for typography.

You may also override variables defined in vuetify/packages/vuetify/src/styles/settings/_variables.scss in a similar manner.

Hope this helps :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I'm encountering an issue where Bulma is taking precedence over the CSS of my Vue3

In my Vue CLI 3 project, I'm utilizing Bulma and have included the import in the 'index.js' file like so: import { createApp } from 'vue' import App from './App.vue' import router from './router' require('@ ...

The imported path is not found in Tsconfig

Hey there! I've been working on getting my project's imports to play nice with typescript import paths. Every time I encounter this error : Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'app' imported from dist/index.js It seems l ...

The use of `slot` attributes in Ionic has been deprecated and flagged by the eslint-plugin-vue

I encountered an error message while using VS Code: [vue/no-deprecated-slot-attribute] `slot` attributes are now considered deprecated. eslint-plugin-vue After installing two plugins in .eslintrc.js, I have the following configurations: 'extends&ap ...

Best Practices for Structuring Front-End Data (such as Product Information) in Vue.js

How should static product information data be stored within a vue2 single page application? In the past, I have used an external JS file that contained a JSON with product attributes (such as name, weight, height, etc). I prefer not to load via AJAX beca ...

Vue component input form not providing expected result

Here is the code snippet for my "ecedata" component with an input field: <template> <div class="col-l-4"> <p style="text-align: center">Data/day (GB)</p> <div class="form-input-set" style="background: white"& ...

Navigating through various product categories in Angular's routing system

Greetings! I am currently building a Shop Page in Angular 4 and encountering an obstacle with Angular routing. The issue arises when a user clicks on a product category, the intention is for the website to direct them to the shop page. On the homepage, th ...

Eliminating event listeners in Nuxt/Vue application

In my current project on Nuxtjs 2.13, I have a question regarding the removal of event listeners. Is it necessary and how should I go about doing it? I'm not referring to traditional JavaScript methods like addEventListener and removeEventListener. I ...

What is the best way to trigger an event in VueJS?

I recently implemented a table using Vuetify in my project. The table is now split into two components - the Table component and the Row component. My challenge is how to handle the same function, this.selected = !this.selected!, when dealing with 2 differ ...

Is it possible to export an imported merged namespace in Typescript?

Within my library, I have a collection of merged declarations setup like this: export class Foo {...} export namespace Foo { export class Bar {...} ... } export default Foo These merged declarations often contain inner classes and specific errors r ...

How can I efficiently remove elements from the end of an array in Vue.js?

Is there a way to splice data starting from the back with a higher index? When clicking on the .delete div, how can I make it so the .image-box div deletes starting from the end? I need help implementing this feature in my code. Here is a snippet: < ...

Creating a completely static website using Nuxt.js without any need for API requests: a foolproof guide

Currently experimenting with Nuxt.js to create a static website. Is it feasible to achieve a completely static site by eliminating the use of API calls for data retrieval? During my testing, I have successfully generated all necessary files and hosted th ...

Typescript: Declaring object properties with interfaces

Looking for a solution to create the childTitle property in fooDetail interface by combining two properties from fooParent interface. export interface fooParent { appId: string, appName: string } export interface fooDetail { childTitle: fooParent. ...

Encapsulating functions with multiple definitions in Typescript

Struggling with wrapping a function that can have multiple return types based on input parameters in Typescript. Imagine wanting a function to return ReturnA for VariantEnum.a and ReturnB for VariantEnum.b. Consider this implementation of sampleFunction: ...

Learn to implement data binding with multiple array inputs in Vue.js

When using Vue.js for form input, I encountered an issue with my new form. Unlike a single input where the v-model and data binding work perfectly, they seem to fail on this new form. You can view the form structure below: In this new form, the v-model do ...

Is it possible to set the state of my datepicker to a previous value only if the new one is determined to be invalid?

I am currently facing an issue with a library I'm utilizing, which has the potential to generate incorrect values that may cause my page to crash. To prevent this, I want to ensure that only valid values (the result of useDateRangePickerState) are app ...

Angular 4 allows for dynamically applying the active class to a clicked button, enhancing interactivity

Issue: <button *ngFor="let button of buttons" [ngClass]="{'active': isClicked}" (click)="isClicked = !isClicked" Description: A total of 10 buttons are displayed on the screen. When I click on button number 1, each button receives the clas ...

What is the best way to trigger an event using vue-chartjs?

I am using vue js to display a graph with chartjs. I have implemented an onClick function on the graph to emit an event in the parent component and retrieve data. However, the event is not working as expected. Can you help me identify the issue? Component ...

What is the reason for receiving an error with one loop style while the other does not encounter any issues?

Introduction: Utilizing TypeScript and node-pg (Postgres for Node), I am populating an array of promises and then executing them all using Promise.all(). While pushing queries into an array during iteration over a set of numbers, an error occurs when the ...

Create a constant object interface definition

Is there a way to create an interface for an object defined with the as const syntax? The Events type does not work as intended and causes issues with enforcement. const events = { // how can I define an interface for the events object? test: payload ...

VueJS efficiently displays various v-binds, including functions and data, on the DOM

When I use v-bind on my router view to pass data objects and functions to a component, some are displayed as expected while others are rendered into the DOM without any apparent reason. I am perplexed as to why some data is displayed and some is not. Is t ...