Use CSS in Gridsome

Global stylesheets and assets are usually located in the src/assets folder and imported into src/main.js.

Import a global style

Add this to src/main.js to import a global CSS file.

import '~/assets/styles.css'

💡 ~ is an alias to project /src/ folder.

Use SASS & CSS pre-processors

To enable SASS you need to install the required packages:

# Using npm
npm install -D sass-loader@^10.1.1 sass

# Using Yarn
yarn add -D sass-loader@^10.1.1 sass

The tag of version 10 for sass-loader is needed, since version 11 requires Webpack 5 - which Gridsome does not yet support.

Now you can import .scss files in src/main.js:

import '~/assets/styles.scss'

You can also use SASS in Vue Components with the lang="scss" attribute:

<style lang="scss">
.element {
  &__nested {
    color: Yay;
  }
}
</style>

Learn more about using using Pre-Processors in Vue.js

Global Preprocessor Files (ie. variables, mixins)

Often when you're working on a project, you'll have a set of variables, mixins, and framework variable overrides that you'll want to be automatically used in your components/layouts so you don't have to keep manually importing them.

Start by installing style-resources-loader:

# Using npm
npm i -D style-resources-loader

# Using Yarn
yarn add -D style-resources-loader

You'll need to add the following block to the top of your gridsome.config.js file before the existing module.exports:

const path = require('path')

function addStyleResource (rule) {
  rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, './src/assets/sass/_globals.sass'),
        // or if you use scss
        path.resolve(__dirname, './src/assets/sass/_globals.scss'),
        // you can also use a glob if you'd prefer
        path.resolve(__dirname, './src/assets/sass/*.sass'),
        // or scss
        path.resolve(__dirname, './src/assets/sass/*.scss'),
      ],
    })
}

module.exports = {
  // existing config
}

Then you'll modify the module.exports block as follows:

module.exports = {
  chainWebpack (config) {
    // Load variables for all vue-files
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']

    types.forEach(type => {
      addStyleResource(config.module.rule('sass').oneOf(type))
    })

    // or if you use scss
    types.forEach(type => {
      addStyleResource(config.module.rule('scss').oneOf(type))
    })
  }
}

Add CSS to Vue Components

In Vue Components you add styles inside a <style> tag.

// Example.vue
<template>
  <div class="banner">
    Hello!
  </div>
</template>

<style>
.banner {
  background-color: red;
}
</style>

Scoped styles in Components

It's very easy to add scoped styles in Vue. Simple add "scoped" to the style tag to automatically add suffix to any CSS class in Markup. This means that styles here will only be applied to current component regardless of the class names you use.

<style scoped>
.card {
  background: blue;
}
</style>

This will change the .card class in current component automatically to something like .card[x5u123sc5s1] and only apply the style to that class.

Learn more about Scoped styles in Vue

Enable Critical CSS

Gridsome Critical CSS plugin extracts CSS from components in selected view port size and adds the CSS inline to <head>.

Add a CSS framework

Tailwind

TailwindCSS is a highly customizable, utility-based CSS framework that gives you all of the building blocks you need to build your project without any opinionated styles you have to fight to override. When using TailwindCSS, it is recommended to use PostCSS-PurgeCSS which is a tool used to remove unused CSS; resulting in tiny file sizes.

Add TailwindCSS with a Plugin

The quickest and easiest way to get up and running with Tailwind CSS in your project is to install it with the Gridsome Tailwind Plugin. A Gridsome plugin will typically have the majority of the boilerplate and configuration done for you, eliminating a lot of the set up time.

Add TailwindCSS Manually

If you prefer to do the install and configuration on your own, you can add TailwindCSS manually with the following instructions.

To install TailwindCSS (choose one):

# Using npm
npm install tailwindcss

# Using Yarn
yarn add tailwindcss

To install PostCSS-PurgeCSS:

# Using npm
npm i -D @fullhuman/postcss-purgecss

# Using Yarn
yarn add -D @fullhuman/postcss-purgecss

Then, create a main.css file in the root of your /src directory and add the following:

@tailwind base;

@tailwind components;

@tailwind utilities;

Now import the main.css file into your project. In the main.js file add require('~/main.css'). Afterwards, your main.js file should look something like this:

// Import global styles
require('~/main.css')

import DefaultLayout from '~/layouts/Default.vue'

export default function (Vue, { router, head, isClient }) {
  // Set default layout as a global component
    Vue.component('Layout', DefaultLayout)

}

Optionally, if you would like to customize your TailwindCSS installation, you can generate a TailwindCSS config file using:

npx tailwind init

Which will generate a minimal tailwind.config.js file at the root of your project that contains:

module.exports = {
    theme: {
        extend: {}
    },
    variants: {},
    plugins: []
}

Learn more about customizing your TailwindCSS installation in Tailwind's configuration documentation

Next, gridsome.config.js needs to be updated to add our TailwindCSS and PurgeCSS configuration:

const tailwind = require('tailwindcss')
const purgecss = require('@fullhuman/postcss-purgecss')

const postcssPlugins = [
  tailwind(),
]

if (process.env.NODE_ENV === 'production') postcssPlugins.push(purgecss(require('./purgecss.config.js')))

module.exports = {
    siteName: 'Gridsome',
    plugins: [],
    css: {
        loaderOptions: {
            postcss: {
                plugins: postcssPlugins,
            },
        },
    },
}

Finally, create a purgecss.config.js file in the root of your project and add the configuration below:

module.exports = {
    content: [
        './src/**/*.vue',
        './src/**/*.js',
        './src/**/*.jsx',
        './src/**/*.html',
        './src/**/*.pug',
        './src/**/*.md',
    ],
    whitelist: [
        'body',
        'html',
        'img',
        'a',
        'g-image',
        'g-image--lazy',
        'g-image--loaded',
    ],
    extractors: [
        {
            extractor: content => content.match(/[A-z0-9-:\\/]+/g),
            extensions: ['vue', 'js', 'jsx', 'md', 'html', 'pug'],
        },
    ],
}

Be sure to restart the gridsome develop command to ensure the changes are compiled in the current build.

Bulma

...plugin coming

Buefy

Buefy provides one of the most comprehensive implementations of Bulma components, styles, and grid system available for Vue.js.

To install use:

# Using npm
npm i buefy

# Using Yarn
yarn add buefy

Then, register the Buefy plugin in your main.js file:

import Buefy from 'buefy'

import 'buefy/dist/buefy.css'

// Then add it to export function

export default function (Vue) {
  Vue.use(Buefy)
}

Buefy doesn't include icon packs in the core bundle, but many of its components use icons. If you'd like to use icons, check out the Buefy documentation to make sure you choose the right CSS to import. Below is an example of how you might import an icon font with Buefy:

import Buefy from 'buefy'

import 'buefy/dist/buefy.css'

export default function (Vue) {
  head.link.push({
        rel: 'stylesheet',
        href: 'https://use.fontawesome.com/releases/v5.2.0/css/all.css'
  })

  Vue.use(Buefy, {
    defaultIconPack: 'fas' // Font Awesome Solid
  })
}

Bootstrap

...plugin coming

BootstrapVue

BootstrapVue provides one of the most comprehensive implementations of Bootstrap V4 components and grid system available for Vue.js 2.5+, complete with extensive and automated WAI-ARIA accessibility markup.

To install use:

# Using npm
npm i vue bootstrap-vue bootstrap

# Using Yarn
yarn add vue bootstrap-vue bootstrap

Then, register BootstrapVue plugin in your main.js file:

import BootstrapVue from 'bootstrap-vue'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// Then add it to export function

export default function (Vue) {
  Vue.use(BootstrapVue)
}

Vuetify

Vuetify is a semantic component framework for Vue. It aims to provide clean, semantic and reusable components that make building your application a breeze. Based on Google's material design, it can be a quick way to get an app up and running with pre-built components available to use and customize. Updated for Vuetify 2.0.

To install use:

# Using npm
npm install vuetify --save

# Using Yarn
yarn add vuetify

Then, you will need to register the Vuetify plugin, include the Vuetify CSS file, and add a link to the head for Google's material design icons in your 'main.js' file, with Vuetify 2.0+ you will need to pass a new instance of Vuetify to appOptions. Icons and iconfonts are now built into Vuetify 2.0+. You can install them as a local dependency or add them as a stylesheet in your head from a CDN, more information on Vuetify icon installation is available here:

// v1.5
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import DefaultLayout from '~/layouts/Default.vue'

export default function (Vue, { head }) {
  head.link.push({
    rel: 'stylesheet',
    href: 'https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css',
  })
  
  head.link.push({
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900',
  });

  Vue.use(Vuetify)
  
  // Set default layout as a global component
  Vue.component('Layout', DefaultLayout)
}
// v2.0
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import DefaultLayout from '~/layouts/Default.vue'

export default function (Vue, { appOptions, head }) {
  head.link.push({
    rel: 'stylesheet',
    href: 'https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css',
  })
  
  head.link.push({
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900',
  });
  
  const opts = { ... } //opts includes, vuetify themes, icons, etc.
  Vue.use(Vuetify)
  
  appOptions.vuetify = new Vuetify(opts);
  
  // Set default layout as a global component
  Vue.component('Layout', DefaultLayout)
}

Finally, there is one last thing you will need in order to build your application with Vuetify. You will need to allowlist Vuetify in webpack in order to build.

First, install the webpack-node-externals plugin:

# Using npm
npm install -D webpack-node-externals

# Using Yarn
yarn add -D webpack-node-externals

Then modify your gridsome.server.js file to include the webpack-node-externals package, and allowlist Vuetify.

const nodeExternals = require('webpack-node-externals')

module.exports = function (api) {
  api.chainWebpack((config, { isServer }) => {
    if (isServer) {
      config.externals([
        nodeExternals({
          allowlist: [/^vuetify/]
        })
      ])
    }
  })

  api.loadSource(store => {
    // Use the Data store API here: https://gridsome.org/docs/data-store-api
  })
}

❗️Note: Before webpack-node-externals version 2.4, use whitelist instead of allowlist.

Or save your bundle size by using vuetify treeshaking.

  1. Install dependencies
# Using npm
npm install -D deepmerge fibers sass sass-loader@7.3.1 vuetify-loader

# Using Yarn
yarn add -D deepmerge fibers sass sass-loader@7.3.1 vuetify-loader

❗️Note: sass-loader must be lower than 8 version, also remove node-sass package if it's installed, otherwise build will fail.

  1. Configure webpack in gridsome.server.js
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');

module.exports = (api) => {
  api.chainWebpack((config, { isServer }) => {
    config.plugin('vuetify-loader').use(VuetifyLoaderPlugin);
  });

❗️Note: webpack-node-externals is not needed in this case.

  1. Install plugin in main.js
import Vuetify from 'vuetify/lib/framework';
import 'vuetify/dist/vuetify.min.css';

export default function (Vue, { appOptions, head }) {
  head.link.push({
    rel: 'stylesheet',
    href: 'https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css',
  });

  head.link.push({
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900',
  });

  const opts = {}; // opts includes, vuetify themes, icons, etc.
  Vue.use(Vuetify);
  appOptions.vuetify = new Vuetify(opts);
}

Then you should be able to build now! You will find the files in your dist/folder.

Edit this page on GitHub