How to Install Shoelace with Rails 7, esbuild, and Tailwind JIT
Tags: tailwindcss, rails, webcomponents, shoelace
Published: 2022-01-13 19:41:31

After struggling to get this working myself I made a guide for future users! Hope you enjoy!

Shout out to @jaredcwhite for making the [article to get me half way there ](https://dev.to/jaredcwhite/how-to-install-shoelace-with-rails-7-esbuild-and-postcss-1cg9).
 
**Using postcss instead?**
[Follow this article!](https://dev.to/jaredcwhite/how-to-install-shoelace-with-rails-7-esbuild-and-postcss-1cg9)

## Installing tailwind


If you're just starting out with a new project

` rails new your_project_name --css tailwind`

otherwise follow this:

For more documentation on tailwind installation: https://github.com/rails/tailwindcss-rails


Run `./bin/bundle add tailwindcss-rails`
Run `./bin/rails tailwindcss:install`

The second command will guide you through the setup of tailwind

## Installing Shoelace

### 1. Install via yarn 

`yarn add @shoelace-style/shoelace`

### 2a (Option 1) Move required files from node_modules manually 

You can either copy the files yourself but have a large git commit of 1k+ files or you can have a script setup (see 2b) and follow the git ignore section

`node_modules/@shoelace-style/shoelace/dist/themes/*.css` to `app/assets/stylesheets/shoelace`

`node_modules/@shoelace-style/shoelace/dist/assets` to `public/shoelace-assets`



### 2b (Option 2) Create a script to copy over files from node_modules. 
In your package.json add the following to your scripts. 


```
"scripts": {
    "build": "yarn shoelace:prepare && esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
    "shoelace:prepare": "mkdir -p public/shoelace-assets && yarn shoelace:copy-assets && yarn shoelace:copy-styles",
    "shoelace:copy-assets": "cp -r node_modules/@shoelace-style/shoelace/dist/assets public/shoelace-assets",
    "shoelace:copy-styles": "copyfiles --flat node_modules/@shoelace-style/shoelace/dist/themes/*.css app/assets/stylesheets/shoelace"
  }
```

The build command copies over the icons and such to the public assets. I git ignore these because we don't need to have thousands of them clogging up the git repo. It hydrates itself everytime you run `bin/dev` so no need to worry about them.

I use copyfiles package because it's a cleaner way to copy css only files so run 

`yarn add copyfiles` before running the scripts

once done, run `yarn shoelace:copy-styles`

### 2b.2 (Optional) Add icons to .gitignore

**Skip this if you followed 2a!!**

In your gitignore add `public/shoelace-assets` to the file

### 3. Import styles to application.tailwind.css file
Now that you've imported everything, add the following to the tailwind file right below the @tailwind imports
```
@tailwind base;
@tailwind components;
@tailwind utilities;

@import "shoelace/light";
@import "shoelace/dark";  /* Optional */

```

### Adding your desired javascript to application.js


This will be something that you'll need to keep updating as you add certain components. Say you want to add a button and icon component. You'll need to add the following to `/javascript/application.js`

The import for the button:
```
import "@shoelace-style/shoelace/dist/components/button/button.js"
```
It's important to set this when using icons because this tells shoelace where the icons are:
```
// This is the import for the icon component
import "@shoelace-style/shoelace/dist/components/icon/icon.js"
// This is the routing and importing of the icons themselves
import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js"
setBasePath("/shoelace-assets")
```
**Note: when you want to add new components from shoelace this is where you stick the import code. You're using a bundler so make sure you select bundler and add the import. Here's an image of what I'm talking about**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvp80c9plxh53t9qfch3.png)

## Test drive it

Okay cool, now that you've got this setup let's test drive it.
 
On one of your pages add the following to generate a 'follow me twitter' button with the twitter icon
```
<p><sl-button type="primary">
  <sl-icon name="twitter"></sl-icon>
  Follow on Twitter
</sl-button></p>
```

Start your server with `bin/dev` and the result should look like this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zsiv241e0iii5y5ers1.png)

And voila, you're up and running with tailwind & shoelace!

I'm sure this isn't the best way, but it works. I'm still quite new to this so apologies if this isn't best practice.

Happy coding!