Encountering a Vuetify CSS issue upon building for production

We recently acquired a Vue web app from a third party and have been working on enhancing it. One of the modifications we made was to integrate Vuetify in order to utilize its elements. While everything functioned smoothly during development, we encountered an issue with the CSS for Vuetify elements being missing once we built the app for production.

Despite researching online and attempting various suggested solutions, we have been unable to resolve this problem. If anyone has any insights into why npm run build might be omitting some of the CSS, your input would be greatly appreciated.

Interestingly, the UI components for Vue are fully operational, indicating that the issue specifically pertains to the absence of CSS styling.

Please find snippets of the code below for reference.

main.js:

(Code snippet for main.js goes here)

App.vue:

(Code snippet for App.vue goes here)

package.json:

(Code snippet for package.json goes here)

Answer №1

It seems a bit challenging to pinpoint the missing element. If you suspect it's just a matter of something missing, try incorporating CSS from the CDN into the HTML file and see if that resolves the issue.

<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="16606373627f706f5624386e">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet">

I notice that you are using webpack for code compilation. This could potentially be related to your webpack configuration. Check if you have rules set up for CSS and SCSS in your webpack settings since Vuetify files are typically in SCSS format.

When I encounter issues like this, my webpack configuration usually looks something like the following:

--webpack.config.js--
const path = require("path");

const VuetifyLoaderPlugin = require("vuetify-loader/lib/plugin");
const { VueLoaderPlugin } = require("vue-loader");

module.exports = {
watch: true,
entry: {
 main: 'main.js'
},
module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
      {
        test: /\.s(c|a)ss$/,
        use: [
          "vue-style-loader",
          "css-loader",
          {
            loader: "sass-loader",
            // Requires sass-loader@^8.0.0
            // options: {
            //   implementation: require('sass'),
            //   sassOptions: {
            //     fiber: require('fibers'),
            //     indentedSyntax: true // optional
            //   },
            // },
          },
        ],
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new VuetifyLoaderPlugin({
      /**
       * This function will be called for every tag used in each vue component
       * It should return an array, the first element will be inserted into the
       * components array, the second should be a corresponding import
       *
       * originalTag - the tag as it was originally used in the template
       * kebabTag    - the tag normalised to kebab-case
       * camelTag    - the tag normalised to PascalCase
       * path        - a relative path to the current .vue file
       * component   - a parsed representation of the current component
       */
      match(originalTag, { kebabTag, camelTag, path, component }) {
        if (kebabTag.startsWith("core-")) {
          return [
            camelTag,
            `import ${camelTag} from '@/components/core/${camelTag.substring(
              4
            )}.vue'`,
          ];
        }
      },
    }),
  ],
}

Answer №2

Take a look at your postcss.config.js file to troubleshoot any issues related to purgecss. You need to set up a whitelist to exclude the vuetify styles. Below is an example configuration for your guidance:

const autoprefixer = require("autoprefixer");
const postcssImport = require("postcss-import");
const purgecss = require("@fullhuman/postcss-purgecss");
const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV);
let plugins = [];
if (IS_PROD) {
  plugins.push(postcssImport);
  plugins.push(
    purgecss({
      content: [
        "./src/**/*.vue",
        "./public/**/*.html",
        `./node_modules/vuetify/src/**/*.ts`,
        `./node_modules/vuetify/dist/vuetify.css`
      ],
      defaultExtractor (content) {
        const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
        return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
      },
        safelist: [ /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/ ],

        whitelist: [
            'container',
            'row',
            'spacer',
            'aos-animate',
            'col',
            '[type=button]',
            'v-application p',
          ],
          whitelistPatterns: [
            /^v-.*/,
            /^col-.*/,
            /^theme-.*/,
            /^rounded-.*/,
            /^data-aos-.*/,
            /^(red|grey)--text$/,
            /^text--darken-[1-4]$/,
            /^text--lighten-[1-4]$/
          ],
          whitelistPatternsChildren: [
            /^post-content/,
            /^v-input/,
            /^swiper-.*/,
            /^pswp.*/,
            /^v-text-field.*/,
            /^v-progress-linear/
          ]
    })
  );
}

module.exports = {
    plugins:[
        require('cssnano')({
            preset: 'default'
        }),
        require('postcss-pxtorem')({
            remUnit:15, //value of each rem in px
            threeVersion:true
        }),
        ...plugins,autoprefixer
    ]
}``

Answer №3

If you're encountering a problem where your project is working locally but not in production, it could be due to a missing include in your main.js file. Make sure to check out the Vuetify documentation for guidance:

import 'vuetify/dist/vuetify.min.css'

By adding this line of code, webpack will include the Vuetify styles in the bundled CSS for production, potentially resolving any issues you may be facing. This solution helped me overcome a similar issue I was experiencing.

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

Challenge: CSS div challenge - making one div's height the same as another div and aligning it to the bottom of its containing div without using absolute

Constructing the required layout has proven to be much more difficult than anticipated. Even with a diagram illustrating how it should look, aligning div D to the bottom of div A without using absolute positioning is causing some trouble (as it messes up t ...

Adjusting Position for Parallax Effect using Jquery

I am currently experimenting with a basic Scrolldeck Jquery Parallax effect to scroll items at varying speeds. However, I am encountering some difficulties in making items move from top to bottom. In the example provided below, you will see a shoe moving f ...

How come my image isn't cooperating with text-align and vertical-align?

Hey everyone! I'm a newcomer to this community and a newbie when it comes to HTML. :D I encountered a problem recently and discovered that Stackoverflow is full of amazing developers. That's why I've decided to share my problem here and am ...

How do you update the bind value in VueJs when using :value="text"?

My attempts at updating a string when the content is changed inside a textarea are not successful. Vue component: <template> <div> <textarea :value="text" @change="changed = true" @keyup="changed = true"&g ...

Issue with background in list items

I am struggling with aligning the background of my vertical menu to the right and center from the top. Here is the code I have tried: ul.nav { margin:0; background-position:center; background-image: url(../images/nav_bg.gif);font-family: "Century Go ...

Book Roulette: Your Next Random Read

I created a code for a random quote generator and now I want to create something similar, but with images this time. I am looking to add a feature on my page where it can recommend a book by displaying its cover image when a button is clicked. For the pre ...

Pedaling back and forth along a sequence

Is there a way to implement forward and backward buttons for a clickable list without using arrays, as the list will be expanding over time? I have already achieved changing color of the listed items to red, but need a solution to navigate through the list ...

Setting the border of a different element when focus is on an input control: tips and tricks

I've created a form with different input controls structured like this: <div class="form-group mb-3"> <div class="input-group"> <input asp-for="Email" class="form-control" ...

Missing 'id' property in object {`id`} when utilizing GraphQL with Typescript

As a newcomer to coding and Typescript, I apologize for my limited knowledge. I am currently facing an issue where my application is unable to communicate with my API due to an error caused by the primary id key having a "?" symbol, like so: export interfa ...

Securing some room beneath the table

I need some extra room below my table. <table border="0" class="medtable"> <tr> <th>User</th> <th>From</th> <th>To</th> </tr> <tr> ... </tr> ...

Managing Laravel/Vue Component Registration and Vue Initialization

I am a beginner VueJs developer and there is one aspect that is causing me some confusion: Utilizing multiple single page components in the app.js file. These are the queries I'm struggling with: Do I need to list ALL of my top-level (parent) compo ...

Steps to automatically show the keyboard when the page is loaded

Currently, I am working on a mobile application using NativeScript-Vue. One issue I encountered is that the keyboard does not automatically display when the page or screen loads. My goal is to have the keyboard show up without the user having to tap on the ...

seamless blending effect as the opacity transitions smoothly on an element with a applied filter

I've been working with a DIV that has a blur filter applied to it, and I'm attempting to smoothly "fade in" the DIV using CSS opacity (going from 0 to 1) with a one-second transition. However, even though the DIV does fade in, it's quite gli ...

With vuejs, only one place can control the changing of v-model

Hello, I am currently working on integrating VueJS2 code with Laravel Blade. However, I have encountered an issue with the following VueJS2 code: new Vue({ el:'.add_item_to_price_menu', data:{ percentage:null, }, methods: ...

Enable synchronized scrolling and a fixed/sticky header with splitpanes feature

Sandbox.vue <template> <v-container fluid> <Splitpanes class="default-theme" style="height: 400px" > <Pane v-for="i in 2" :key="i" > & ...

The Vue app's Axios request deployed on Amazon S3 fetches the home page of the website

My Vue app is deployed as a "static" site on Amazon S3 and the CORS configuration remains default. To prevent 404 errors on routing, I include the following line after building the app: <script>history.pushState({}, "Application entry", location.has ...

Double Marker Challenge in Brochure

I am currently using Leaflet in conjunction with VueJs. I have encountered an issue where a double marker is appearing at a specific location when I add a marker: The code responsible for this behavior is as follows: mounted() { this.map = L.ma ...

Reposition and resize an image. Creating a grid layout

I'm having trouble with positioning and cropping an image correctly on my website. I want it to look like this (hero-section): The entire project is based on a grid layout. I need a circular image that is larger than the container, positioned to the ...

Making the height of two divs equal within the same parent element using CSS

Looking for a way to make two adjacent divs, #innerwrapper .sidebar and #innerwrapper > .content, from the same parent container, #innerwrapper, have equal heights due to them being floated left. I initially used jQuery in a separate file to resolve th ...

To insert a <div> element within a <tr> element while preserving the exact position of the <tr> tag - here's how you can do it:

I have a challenge with my table where I need to add a green progress bar in the form of a div element within a tr. The width of this progress bar should change dynamically from 0% to 100%, reflecting the current runtime of the video associated with that p ...