Skip to content

How to Style Using SCSS in Nuxt

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Introduction

SASS makes working on large projects more organized. It allows you to use variables, nested rules, mixins, and functions. The preferred styling method in Nuxt is component file styling, and integrating SASS into your project can make your component file styling appear more understandable.

How to Import SASS in Nuxt

To add SASS after setting up your Nuxt application, we will first install SASS and sass-loader. Let's run either of these commands depending on our package manager.

$ yarn add sass sass-loader --dev
# or
$ npm install sass sass-loader --save-dev

Component File Styling

With SASS and sass-loader installed in our project, we can now write SCSS in our component file.

Lets see an example:

<!-- src/components/button/button.vue -->
<template>
    <button
        class="app-button"
    >
      <slot></slot>
    </button>
</template>

<style lang="scss">
  .app-button {
    position: relative;
    display: inline-flex;
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    align-items: center;
    justify-content: center;
    vertical-align: top;
    text-decoration: none;
    outline: none;

    // variant
    &--primary {
        background-color: #0e34cd;
        color: #ffffff;
    }
}
</style>

In the example above, all we need to specify is lang="scss" on the style tag, and we can now write scss in that component.

Global File Import and Variables

To import SCSS files that are global, like variables and mixins files, we need to install style-resources:

$ yarn add @nuxtjs/style-resources --dev
# or
$ npm install @nuxtjs/style-resources --save-dev

Next, we can update our nuxt.config.js file by adding the module we just installed to the buildModules.

// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
  '@nuxtjs/style-resources',
],

Next, let's create a global variables.scss file in our assets/style folder.

Add a single variable inside:

// assets/style/variables.scss

$primary: #010933;
$white: #fff;

Next, we need to import this file inside the nuxt.config file:

 styleResources: {
    scss: [
      '~/assets/style/variables.scss',
    ],
  },

Now we have the variables in our variables.scss available in all our components for use.

Next, let's test it out by updating our button component.

<!-- src/components/button/button.vue -->
<template>
    <button
        class="app-button"
    >
      <slot></slot>
    </button>
</template>

<style lang="scss">
  .app-button {
    position: relative;
    display: inline-flex;
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    align-items: center;
    justify-content: center;
    vertical-align: top;
    text-decoration: none;
    outline: none;

    // variant
    &--primary {
        background-color: $primary;
        color: $white;
    }
}
</style>

We have updated our button variant color to be our global SCSS variable ($primary and $white).

Mixins

Mixins in SASS are used to write styles that can be reused in other parts of the code.

Let's create a sample mixin to center an item.

// assets/style/mixins.scss

@mixin center-item {
  text-align: center;
  align-items: center;
  justify-content: center;
}

Next, we need to import our mixin in Nuxt config:

 styleResources: {
    scss: [
      '~/assets/style/variables.scss',
      '~/assets/style/mixins.scss'
    ],
  },

Now, let's update our button component with our mixin:

<!-- src/components/button/button.vue -->
<template>
    <button
        class="app-button"
    >
      <slot></slot>
    </button>
</template>

<style lang="scss">
  .app-button {
    position: relative;
    display: inline-flex;
    cursor: pointer;
    white-space: nowrap;
    vertical-align: top;
    text-decoration: none;
    outline: none;
    @include center-item;

    // variant
    &--primary {
        background-color: $primary;
        color: $white;
    }
}
</style>

Functions

Functions in SASS are used to write complex operations or behaviours that can be reused in other parts of the code.

Let's create a function to handle a media query for our application.

// assets/style/functions.scss

// Get the difference between 2 numbers.
@function minus($param1, $param2) {
  @return $param1 - $param2;
}

// Get the sum of 2 numbers.
@function add($param1, $param2) {
  @return $param1 + $param2;
}

This is a basic example of what a function can be used for. More complex cases, like calculating percentage, can also be done.

Let's import our mixin in Nuxt config:

 styleResources: {
    scss: [
      '~/assets/style/variables.scss',
      '~/assets/style/mixins.scss',
      '~/assets/style/functions.scss'
    ],
 },

Let's update our button component with our function:

<!-- src/components/button/button.vue -->
<template>
    <button
        class="app-button"
    >
      <slot></slot>
    </button>
</template>

<style lang="scss">
  .app-button {
    position: relative;
    display: inline-flex;
    cursor: pointer;
    white-space: nowrap;
    vertical-align: top;
    text-decoration: none;
    outline: none;
    @include center-item;
    width: minus(30px, 100%);

    // variant
    &--primary {
        background-color: $primary;
        color: $white;
    }
}
</style>

We have been able to add SASS to our Nuxt project, and also looked at some ways in which SASS can make our codebase look cleaner.

I hope this article has been helpful to you. If you encounter any issues, you can reach out to me on Twitter or Github.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools cover image

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools

In the ever-evolving world of web development, Nuxt.js has taken a monumental leap with the launch of Nuxt DevTools v1.0. More than just a set of tools, it's a game-changer—a faithful companion for developers. This groundbreaking release, available for all Nuxt projects and being defaulted from Nuxt v3.8 onwards, marks the beginning of a new era in developer tools. It's designed to simplify our development journey, offering unparalleled transparency, performance, and ease of use. Join me as we explore how Nuxt DevTools v1.0 is set to revolutionize our workflow, making development faster and more efficient than ever. What makes Nuxt DevTools so unique? Alright, let's start delving into the features that make this tool so amazing and unique. There are a lot, so buckle up! In-App DevTools The first thing that caught my attention is that breaking away from traditional browser extensions, Nuxt DevTools v1.0 is seamlessly integrated within your Nuxt app. This ensures universal compatibility across browsers and devices, offering a more stable and consistent development experience. This setup also means the tools are readily available in the app, making your work more efficient. It's a smart move from the usual browser extensions, making it a notable highlight. To use it you just need to press Shift + Option + D (macOS) or Shift + Alt + D (Windows): With simple keystrokes, the Nuxt DevTools v1.0 springs to life directly within your app, ready for action. This integration eliminates the need to toggle between windows or panels, keeping your workflow streamlined and focused. The tools are not only easily accessible but also intelligently designed to enhance your productivity. Pages, Components, and Componsables View The Pages, Components, and Composables View in Nuxt DevTools v1.0 are a clear roadmap for your app. They help you understand how your app is built by simply showing its structure. It's like having a map that makes sense of your app's layout, making the complex parts of your code easier to understand. This is really helpful for new developers learning about the app and experienced developers working on big projects. Pages View lists all your app's pages, making it easier to move around and see how your site is structured. What's impressive is the live update capability. As you explore the DevTools, you can see the changes happening in real-time, giving you instant feedback on your app's behavior. Components View is like a detailed map of all the parts (components) your app uses, showing you how they connect and depend on each other. This helps you keep everything organized, especially in big projects. You can inspect components, change layouts, see their references, and filter them. By showcasing all the auto-imported composables, Nuxt DevTools provides a clear overview of the composables in use, including their source files. This feature brings much-needed clarity to managing composables within large projects. You can also see short descriptions and documentation links in some of them. Together, these features give you a clear picture of your app's layout and workings, simplifying navigation and management. Modules and Static Assets Management This aspect of the DevTools revolutionizes module management. It displays all registered modules, documentation, and repository links, making it easy to discover and install new modules from the community! This makes managing and expanding your app's capabilities more straightforward than ever. On the other hand, handling static assets like images and videos becomes a breeze. The tool allows you to preview and integrate these assets effortlessly within the DevTools environment. These features significantly enhance the ease and efficiency of managing your app's dynamic and static elements. The Runtime Config and Payload Editor The Runtime Config and Payload Editor in Nuxt DevTools make working with your app's settings and data straightforward. The Runtime Config lets you play with different configuration settings in real time, like adjusting settings on the fly and seeing the effects immediately. This is great for fine-tuning your app without guesswork. The Payload Editor is all about managing the data your app handles, especially data passed from server to client. It's like having a direct view and control over the data your app uses and displays. This tool is handy for seeing how changes in data impact your app, making it easier to understand and debug data-related issues. Open Graph Preview The Open Graph Preview in Nuxt DevTools is a feature I find incredibly handy and a real time-saver. It lets you see how your app will appear when shared on social media platforms. This tool is crucial for SEO and social media presence, as it previews the Open Graph tags (like images and descriptions) used when your app is shared. No more deploying first to check if everything looks right – you can now tweak and get instant feedback within the DevTools. This feature not only streamlines the process of optimizing for social media but also ensures your app makes the best possible first impression online. Timeline The Timeline feature in Nuxt DevTools is another standout tool. It lets you track when and how each part of your app (like composables) is called. This is different from typical performance tools because it focuses on the high-level aspects of your app, like navigation events and composable calls, giving you a more practical view of your app's operation. It's particularly useful for understanding the sequence and impact of events and actions in your app, making it easier to spot issues and optimize performance. This timeline view brings a new level of clarity to monitoring your app's behavior in real-time. Production Build Analyzer The Production Build Analyzer feature in Nuxt DevTools v1.0 is like a health check for your app. It looks at your app's final build and shows you how to make it better and faster. Think of it as a doctor for your app, pointing out areas that need improvement and helping you optimize performance. API Playground The API Playground in Nuxt DevTools v1.0 is like a sandbox where you can play and experiment with your app's APIs. It's a space where you can easily test and try out different things without affecting your main app. This makes it a great tool for trying out new ideas or checking how changes might work. Some other cool features Another amazing aspect of Nuxt DevTools is the embedded full-featured VS Code. It's like having your favorite code editor inside the DevTools, with all its powerful features and extensions. It's incredibly convenient for making quick edits or tweaks to your code. Then there's the Component Inspector. Think of it as your code's detective tool. It lets you easily pinpoint and understand which parts of your code are behind specific elements on your page. This makes identifying and editing components a breeze. And remember customization! Nuxt DevTools lets you tweak its UI to suit your style. This means you can set up the tools just how you like them, making your development environment more comfortable and tailored to your preferences. Conclusion In summary, Nuxt DevTools v1.0 marks a revolutionary step in web development, offering a comprehensive suite of features that elevate the entire development process. Features like live updates, easy navigation, and a user-friendly interface enrich the development experience. Each tool within Nuxt DevTools v1.0 is thoughtfully designed to simplify and enhance how developers build and manage their applications. In essence, Nuxt DevTools v1.0 is more than just a toolkit; it's a transformative companion for developers seeking to build high-quality web applications more efficiently and effectively. It represents the future of web development tools, setting new standards in developer experience and productivity....

Announcing Our New Starter.dev Kit: Nuxt 3 with Pinia and Vuetify cover image

Announcing Our New Starter.dev Kit: Nuxt 3 with Pinia and Vuetify

We're thrilled to unveil our brand new starter.dev kit: a Nuxt 3 kit using Pinia as the state manager and Vuetify for styles. While Nuxt 2 is still reliable and powerful, Nuxt 3, being the latest iteration of this versatile framework, brings an array of innovative features and enhanced flexibility that make it an ideal choice for your next development project. Now, let's explore what this kit offers, and how it can help you in your upcoming application development. Nuxt 3 vs Nuxt 2 First, why Nuxt 3? Let's delve into what Nuxt 3 is and why we've opted for this technology for our kit. Nuxt 3 is a modern web development framework based on Vue 3 for building server-side rendered applications, single-page applications, or statically rendered websites. It's an evolution of Nuxt 2 and provides an improved developer experience and better performance. Let’s see what features it has to offer in comparison to Nuxt 2! - Built on Vue 3: Nuxt 3 is built from the ground up using Vue 3, which brings a host of new features including conditional suspending of component rendering via the Suspense API, more flexibility for global mounting, and a Virtual DOM rewrite for better performance and improved TypeScript support. - Nitro Engine: Nitro, the new rendering server for Nuxt 3, is built for serverless architectures and offers extremely fast cold-start times. Nuxt 3 is planned to support Incremental Static Regeneration (ISR) using the Nitro renderer. - Native Composition API Support: Nuxt 3 has native support for the Vue Composition API, a feature that Nuxt 2 had to rely on an external library to use. The Composition API changes how code is written in Vue and is now built-in with Nuxt 3 since it is built on top of Vue 3. - Faster Hot Reloads with Vite: Nuxt 3 uses Vite for Hot Module Replacement (HMR), which is used when the server re-renders the updated components of your application in both development and production. This leads to faster hot reloads. - Additional Features: There are several other salient features of Nuxt 3, including a new Nuxt CLI (nuxi), NuxtJS Dev tools, and global auto imports of common functions such as `​. Nuxt 3 brings remarkable performance enhancements, significantly reducing the size of server deployments and client bundles. These improvements are made possible by implementing a new renderer, faster hot reloads, and built-in support for native TypeScript and Composition API, as mentioned earlier. With such impressive features at our disposal, the decision to choose this framework was undoubtedly the right one. Pinia Let's talk about the state management library we've chosen. As the successor to Vuex, Pinia is now the default state management library for Vue 3. Pinia shines when sharing global state within your application; it ensures security and ease of use, especially when using SSR, which is often the case with Nuxt. Pinia's integration with Nuxt 3 is seamless, benefiting from Vue 3's inbuilt Composition API. The use of Pinia greatly simplifies the state management in Vue-based applications. Vuetify Vuetify is an exceptional Material Design framework for Vue.js that assists in building elegant, responsive, and interactive web applications. In Nuxt 3, the integration of Vuetify can be done smoothly, thanks to Nuxt's flexibility. This makes the process of building modern, visually appealing applications more efficient and enjoyable. What's inside the Nuxt 3 Kit? Our aim in developing the starter.dev kit is to equip you with essentials while maintaining flexibility. The kit incorporates a counter component that manages state using a Pinia store, and a Fetch component showcasing data fetch in Nuxt 3. We decided to omit Storybook and testing from this starter.dev kit. Storybook is currently incompatible with Nuxt 3, but rest assured, we will incorporate it as soon as compatibility support is introduced. Regarding testing, tools like Vitest and others have been excluded for now. The current Nuxt 3 testing landscape is still under development and not deemed production-ready. As the testing environment matures, we will update our starter.dev kit to include the most efficient and reliable testing solutions. Furthermore, the kit includes configurations for ESLint, Prettier, and is written entirely in TypeScript. This saves you significant time by taking the hassle out of setting up these tools in a new project. How do I use the kit? Use our starter.dev CLI! This is by far the easiest method. Simply run the command ` This will display a list of available starter.dev kits. Select the one that fits your needs - in this case, the ` one! You'll be asked to provide a name for your new project, and once that's inputted, the CLI will begin preparing the kit for you! Once installed, you can cd into your new project directory with the name you provided earlier, and start coding. But don’t forget to install the required dependencies with your package manager of choice (I recommend pnpm 🫣). For a deeper insight into the kit, visit https://starter.dev/kits/nuxt3-pinia-vuetify/ where you can read the README.md file for more detailed documentation, as well as take a look at the source code. Don't forget to read the package.json file to see the scripts available for the kit. Conclusion In a nutshell, our new starter.dev kit integrates Nuxt 3, Pinia, and Vuetify.. This article not only introduces you to the kit but also delves into the features and advantages that make it stand out - the improved performance of Nuxt 3, the ease of state management with Pinia, and the sophisticated stylings of Vuetify. As the digital landscape evolves, we will keep this kit updated with tools like Storybook and comprehensive testing capabilities as soon as they become Nuxt 3-compatible. That's it, folks! We're eager for you to take this kit for a spin in your next project. We've built it with much care and attention to detail, ensuring it brings significant value to your development process. We hope you find it as enjoyable to use as we did creating it. Happy coding!...

Testing Vue Composables with Jest cover image

Testing Vue Composables with Jest

In this post, we will take a look at how to test Vue composables with Jest. What Are Composables? When developing large scale frontend applications, we reuse logic for repetitive tasks. With composables, we are able to resuse logic in a stateful manner with the help of the composition API. Testing For this example, we create a composable to handle changes in screen size. Depending on how complex your composable is, you can simply test the reactivity directly or load it into a wrapper component, and then test the wrapper component. ` Let's write the following tests for this composable. - check currect value of screen size - check currect value of screen size after resize event is fired To test that the resize event changes the current value when fired, we need to load our composable in a component. ` From the implementation we completed above, the core logic of our breakpoint method is in an external function called "composable", and we can simply reuse it across our frontend code. Any manipulation to the state of a composable should be done directly within the composable to avoid bugs and make it easier to read. I hope this article has been helpful. If you have any questions or run into any trouble, feel free to reach out on Twitter or Github....

The simplicity of deploying an MCP server on Vercel cover image

The simplicity of deploying an MCP server on Vercel

The current Model Context Protocol (MCP) spec is shifting developers toward lightweight, stateless servers that serve as tool providers for LLM agents. These MCP servers communicate over HTTP, with OAuth handled clientside. Vercel’s infrastructure makes it easy to iterate quickly and ship agentic AI tools without overhead. Example of Lightweight MCP Server Design At This Dot Labs, we built an MCP server that leverages the DocuSign Navigator API. The tools, like `get_agreements`, make a request to the DocuSign API to fetch data and then respond in an LLM-friendly way. ` Before the MCP can request anything, it needs to guide the client on how to kick off OAuth. This involves providing some MCP spec metadata API endpoints that include necessary information about where to obtain authorization tokens and what resources it can access. By understanding these details, the client can seamlessly initiate the OAuth process, ensuring secure and efficient data access. The Oauth flow begins when the user's LLM client makes a request without a valid auth token. In this case they’ll get a 401 response from our server with a WWW-Authenticate header, and then the client will leverage the metadata we exposed to discover the authorization server. Next, the OAuth flow kicks off directly with Docusign as directed by the metadata. Once the client has the token, it passes it in the Authorization header for tool requests to the API. ` This minimal set of API routes enables me to fetch Docusign Navigator data using natural language in my agent chat interface. Deployment Options I deployed this MCP server two different ways: as a Fastify backend and then by Vercel functions. Seeing how simple my Fastify MCP server was, and not really having a plan for deployment yet, I was eager to rewrite it for Vercel. The case for Vercel: * My own familiarity with Next.js API deployment * Fit for architecture * The extremely simple deployment process * Deploy previews (the eternal Vercel customer conversion feature, IMO) Previews of unfamiliar territory Did you know that the MCP spec doesn’t “just work” for use as ChatGPT tooling? Neither did I, and I had to experiment to prove out requirements that I was unfamiliar with. Part of moving fast for me was just deploying Vercel previews right out of the CLI so I could test my API as a Connector in ChatGPT. This was a great workflow for me, and invaluable for the team in code review. Stuff I’m Not Worried About Vercel’s mcp-handler package made setup effortless by abstracting away some of the complexity of implementing the MCP server. It gives you a drop-in way to define tools, setup https-streaming, and handle Oauth. By building on Vercel’s ecosystem, I can focus entirely on shipping my product without worrying about deployment, scaling, or server management. Everything just works. ` A Brief Case for MCP on Next.js Building an API without Next.js on Vercel is straightforward. Though, I’d be happy deploying this as a Next.js app, with the frontend features serving as the documentation, or the tools being a part of your website's agentic capabilities. Overall, this lowers the barrier to building any MCP you want for yourself, and I think that’s cool. Conclusion I'll avoid quoting Vercel documentation in this post. AI tooling is a critical component of this natural language UI, and we just want to ship. I declare Vercel is excellent for stateless MCP servers served over http....

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co