Javascript not working when using Tailwind Elements with Ruby on Rails

920 Views Asked by At

I just started a new rails 7 project with TailwindCSS using the new rails new my-app --css tailwind syntax. Tailwind CSS is working properly. I wanted to add a navbar from tailwind elements, and I followed the steps from https://tailwind-elements.com/quick-start/. The css in the navbar works, but the opening and closing of submenus (which I presume is all run by javascript) does not.

When digging into the details, I am seeing these lines in the rails s logs

Started GET "/TW-ELEMENTS-PATH/dist/js/index.min.js" for 127.0.0.1 at 2023-02-02 09:13:48 -0600

ActionController::RoutingError (No route matches [GET] "/TW-ELEMENTS-PATH/dist/js/index.min.js"):

I did the npm install tw-elements install and the tailwind.config.cs edits, what am I missing? Is there some conflict that with Ruby on Rails that I am not aware of? Do I really need to create a route, or is that a sign that something is not installed correctly?

Here is the application.html.erb where I am inserting my <script> line

<!DOCTYPE html>
<html>
<head>
    <title>MyApp</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag "tailwind" , "inter-font" , "data-turbo-track" : "reload" %>
    <%= stylesheet_link_tag "application" , "data-turbo-track" : "reload" %>
    <%= javascript_importmap_tags %>
    <!--here is the line I added -->
    <script src="./TW-ELEMENTS-PATH/dist/js/index.min.js"></script>
</head>
<body>
    <%= render 'layouts/navigation' %>
    <main class="container mx-auto mt-28 px-5 flex">
        <%= yield %>
    </main>
</body>
</html>

I did try the alternate step 4 by putting import 'tw-elements'; in app/javascript/controllers.index.js but nothing is working.

2

There are 2 best solutions below

2
On

==== EDIT ====

Came back to update - there's actually a page for installing tailwind on Rails, and it just works :)

==== EDIT END ====

Just had the same issue and posting the solution here.

After you have completed the steps in the tailwind elements setup, instead of the last step (the script tag):

  1. Add these to your assets.rb initializer
Rails.application.config.assets.paths << Rails.root.join('node_modules/tw-elements/dist/js')
Rails.application.config.assets.precompile += %w( tailwind.css tw-elements.umd.min.js )
  1. Add this line in application.rb
//= require tw-elements.umd.min
  1. Add the script tag in your application.html.erb - note the type module at the end:
    <%= javascript_include_tag 'tw-elements.umd.min', 'data-turbolinks-track': 'reload', type: "module" %>

The solution was based on this post.

Hope this helps!

0
On

Here's my working setup with Tailwind Elements, Rails 7, importmaps -- notably NO nodejs, package.json, esbuild/webpack, etc.

After running:

bin/importmap pin --download tw-elements
bin/importmap pin --download tw-elements/dist/plugin.cjs

I have in my config/importmap.rb:

pin "tw-elements", to: "tw-elements.js", preload: true # @1.1.0
pin "tw-elements/dist/plugin.cjs", to: "tw-elements--dist--plugin.cjs.js" # @1.1.0

I reference these from config/tailwind.config.js thus:

module.exports = {
  content: [
    './public/*.html',
    './app/helpers/**/*.rb',
    './app/javascript/**/*.js',
    './app/views/**/*.{erb,haml,html,slim}',
    './vendor/javascript/tw-elements.js',  // TW-ELEMENTS //
  ],
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/aspect-ratio'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/container-queries'),
    require('../vendor/javascript/tw-elements--dist--plugin.cjs.js'), // TW-ELEMENTS //
  ],
}

Note the ../ is required in one place, but forbidden in the other! That's because when we call require in the plugins section our working dir is RAILS_ROOT/config, but in content the paths are relative to RAILS_ROOT.