How to use Stitches in Vue and Nuxt

  Diego Artiles   •     6 Min

If you came here, you will know that stitches does not have a vue-friendly package like @stitches/react in react, however, it has @stitches/core that is framework agnostic.

In this post we will learn about how to use Stitches with @stitches/core package directly and through a vue-stitches too.

At the moment when I write this post, the latest version is 1.2.6, so I'll use that version in the examples.

To get started, obviously we have to install it. If you want know how to do this, click here.

Making the theme and css

The theme is not very important to use stitches in vue, so you can skip this step. For the other persons that's wants to know how to do its, I'll explain to you.

You need to create a config file that contains the main settings of your theme likes utils, variables, media, etc. And export css function to use it in your components. Let see an example:

//stitches.config.js

import { createStitches } from "@stitches/core";

export const { css } = createStitches({
  theme: {
    colors: {
      primary: "orange"
    }
  },
  prefix: "coco",
  utils: {
    myCustomColor: (value) => ({
      backgroundColor: value,
      color: "black"
    })
  },
  media: {
    md: "(max-width: 640px)"
  }
});
This is only an example you can put your own config or skip this step
// Button.styles.js

import { css } from "../../stitches.config.js";
// If you do not have a stitches.config.js you can import css directly from package
// import { css } from "@stitches/core";

export const buttonStyles = css({
  backgroundColor: "blue",
  borderRadius: "9999px",
  fontSize: "13px",
  lineHeight: "1",
  fontWeight: 500,
  paddingTop: "10px",
  paddingBottom: "10px",
  paddingLeft: "16px",
  paddingRight: "16px",
  border: "0",
  "@md": {
    myCustomColor: "purple"
  },
  "&:hover": {
    transform: "translateY(-2px)",
    boxShadow: "0 10px 25px rgba(0, 0, 0, .3)"
  },
  variants: {
    color: {
      orange: {
        backgroundColor: "orange"
      }
    }
  }
});

Using @stitches/core directly

To use css function in our vue components we have many alternatives. Let's see some of them:

// Button.vue

<template>
  <button :class="buttonStyles">
    <slot></slot>
  </button>
</template>

<script>
import { buttonStyles } from "./Button.styles.js";

export default {
  name: "Button",
  data: () => ({
    buttonStyles: buttonStyles().className,
  }),
};
</script>

Perfect, but... What about variants? How can I use it?

// Button.vue

<template>
  <button :class="buttonStyles">
    <slot></slot>
  </button>
</template>

<script>
import { buttonStyles } from "./Button.styles.js";

export default {
  name: "Button",
  data: () => ({
    buttonStyles: buttonStyles({ color: "orange" }).className,
  }),
};
</script>
The css function return another function that receive an object with the variants

We can pass an object with any variants we want. Also you can pass props from the main component.

As you can see, this is not a friendly way to use with Vue if we compare it to React.

Let's remember with React we can create components directly with styled function and use variants with props in the element/component. Is there something similar in Vue?

The answer is, actually not but there is a friendly way with vue 🙂. Let's take a look at vue-stitches

Using vue-stitches (Alpha version)

I am currently working with stitches in a Vue project and I did notice the experience is not very well to me, so I create a vue-friendly package to use stitches.

Let's see what we can do with it

Installation

npm install vue-stitches@latest
or
yarn add vue-stitches@latest

Usage

To use the directive we need to use it as plugin. Let's see an example in Vue 2, Vue 3 and Nuxt.

Vue 2 and Vue 3

Use it in the file where you mount the app as plugin

import Vue from "vue";
import App from "./App.vue";
import VueStitches from "vue-stitches";

Vue.use(VueStitches);
new Vue({
  el: "#app",
  render: (h) => h(App)
});
Vue 2
import { createApp } from "vue";
import App from "./App.vue";
import VueStitches from "vue-stitches";

const app = createApp(App);
app.use(VueStitches);
app.mount("#app");
Vue 3

Nuxt

Create a file in plugins folders and add it to plugin property at nuxt.config.js.

import Vue from "vue";
import VueStitches from "vue-stitches";

Vue.use(VueStitches);
plugins/vue-stitches.js
plugins: ['~/plugins/vue-stitches.js']
nuxt.config.js

Using vue-stitches in our components

To use it, we need to add v-stitches directive in the element or component what  you want.

The directive expect an array with two position, the first one css function reference and the second is an object with variants that you need.

You can pass css function reference directly if you won't need to use variants
// Button.vue

<template>
  <button v-stitches="[buttonStyles, { color }]">
    <slot></slot>
  </button>
  <button v-stitches="buttonStyles" />
</template>

<script>
import { buttonStyles } from "./Button.styles.js";

export default {
  name: "Button",
  data: () => ({
    color: 'orange',
    buttonStyles
  }),
};
</script>
Using stitches through vue-stitches

That's all, I know is not the best way to use stitches in vue, but I have good news, I working to improve it, so stay tuned in Github or NPM 🤩.

If you have any ideas or suggestions, please let me know in the comments below or on Github.