Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tailwind CSS in Rails Engines

A demonstration repository showing two different approaches for integrating Tailwind CSS with Rails engines.

Overview

This repository contains two example Rails engines that demonstrate different strategies for using Tailwind CSS:

  1. blogh_isolate - Isolated Tailwind build approach
  2. blogh_main_app_layout - Shared Tailwind build approach

Each approach has its own trade-offs and is suitable for different use cases.

Approach 1: Isolated Tailwind Build (blogh_isolate)

The engine maintains its own Tailwind CSS build system, completely independent of the host application.

Key Features

  • Engine has its own Tailwind build process
  • Uses the tailwindcss-rails gem as a dependency
  • Provides its own layout with isolated styles
  • Auto-builds Tailwind CSS in development mode
  • Includes Rake tasks for building and watching CSS

File Structure

blogh_isolate/
├── app/
│   ├── assets/
│   │   ├── builds/blogh/
│   │   │   └── tailwind.css          # Compiled output
│   │   ├── tailwind/blogh/
│   │   │   └── application.css       # @import "tailwindcss"
│   │   └── stylesheets/blogh/
│   │       └── application.css       # @import url("tailwind.css")
│   └── views/
│       ├── layouts/blogh/
│       │   └── application.html.erb  # Engine's own layout
│       └── blogh/home/
│           └── index.html.erb        # Uses Tailwind classes
├── lib/
│   ├── blogh/
│   │   └── engine.rb                 # Auto-builds in development
│   └── tasks/
│       └── blogh_tasks.rake          # Build & watch tasks
└── blogh.gemspec                     # Includes tailwindcss-rails

Setup

1. Gemspec Configuration (blogh.gemspec)

spec.add_dependency "rails", ">= 8.1.1"
spec.add_dependency "tailwindcss-rails"

2. Engine Configuration (lib/blogh/engine.rb)

module Blogh
  class Engine < ::Rails::Engine
    isolate_namespace Blogh

    initializer 'blogh.tailwindcss', before: :load_config_initializers do
      if Rails.env.development?
        Rails.application.config.after_initialize do
          begin
            require 'rake'
            require 'tailwindcss-rails'
            Rails.application.load_tasks
            Rake::Task['blogh:tailwindcss:build'].invoke
          rescue LoadError => e
            Rails.logger.warn "Blogh: Could not load tailwindcss-rails: #{e.message}"
          rescue StandardError => e
            Rails.logger.warn "Blogh: Failed to build Tailwind CSS: #{e.message}"
          end
        end
      end
    end
  end
end

3. Tailwind Input (app/assets/tailwind/blogh/application.css)

@import "tailwindcss";

4. Stylesheet Manifest (app/assets/stylesheets/blogh/application.css)

@import url("tailwind.css");

5. Layout (app/views/layouts/blogh/application.html.erb)

<!DOCTYPE html>
<html>
<head>
  <title>Blogh</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <%= stylesheet_link_tag "blogh/application", media: "all" %>
</head>
<body>
  <%= yield %>
</body>
</html>

6. Rake Tasks (lib/tasks/blogh_tasks.rake)

The engine includes custom Rake tasks for building and watching Tailwind CSS:

# Build once
rake blogh:tailwindcss:build

# Watch for changes
rake blogh:tailwindcss:watch

Advantages

  • Complete isolation - engine styles won't conflict with host app
  • Engine can be used standalone or in multiple applications
  • Full control over Tailwind configuration and build process
  • Works even if host application doesn't use Tailwind

Disadvantages

  • Adds tailwindcss-rails as a dependency
  • Requires separate build process
  • Larger overall CSS bundle if host app also uses Tailwind
  • More complex setup and maintenance

When to Use

  • Engine needs to work in applications without Tailwind
  • Engine requires specific Tailwind configuration
  • Complete style isolation is critical
  • Engine is distributed as a standalone gem

Approach 2: Shared Tailwind Build (blogh_main_app_layout)

The engine integrates with the host application's Tailwind build by adding its content paths to the main app's configuration.

Key Features

  • Uses the host application's Tailwind build
  • No additional dependencies required
  • Relies on host app's layout
  • Minimal setup required
  • Lighter weight approach

File Structure

blogh_main_app_layout/
├── app/
│   └── assets/
│       └── stylesheets/blogh/
│           └── application.css       # Can be empty or minimal
├── lib/
│   └── blogh/
│       └── engine.rb                 # Adds content paths
└── blogh.gemspec                     # No tailwindcss-rails dependency

Setup

1. Gemspec Configuration (blogh.gemspec)

spec.add_dependency "rails", ">= 8.1.1"
# Note: No tailwindcss-rails dependency

2. Engine Configuration (lib/blogh/engine.rb)

module Blogh
  class Engine < ::Rails::Engine
    isolate_namespace Blogh

    initializer "blogh.tailwind" do |app|
      app.config.tailwind_content_paths ||= []
      app.config.tailwind_content_paths += [
        root.join("app/views/**/*.{erb,slim}").to_s,
        root.join("app/components/**/*.rb").to_s,
        root.join("app/helpers/**/*.rb").to_s,
        root.join("app/javascript/**/*.js").to_s
      ]
    end
  end
end

3. Host Application Setup

The host application must:

  • Have Tailwind CSS configured (e.g., via tailwindcss-rails)
  • Include the engine styles in the layout
  • Use the main application layout for engine views

Advantages

  • Minimal setup required
  • No additional dependencies
  • Single Tailwind build for entire application
  • Smaller overall CSS bundle
  • Automatically shares design system with host app

Disadvantages

  • Requires host application to use Tailwind CSS
  • Engine cannot be used standalone
  • Less control over styling
  • Potential for style conflicts with host app

When to Use

  • Building an engine for a specific application
  • Host application already uses Tailwind CSS
  • Want to share design system between engine and host app
  • Prefer minimal dependencies and simple setup
  • Engine won't be distributed as a standalone gem

Comparison Table

Feature Isolated Build Shared Build
Dependencies Requires tailwindcss-rails No additional deps
Setup Complexity More complex Minimal
Build Process Separate engine build Uses host app build
Style Isolation Complete isolation Shares with host app
Standalone Usage Yes No
Host App Requirements None Must use Tailwind
CSS Bundle Size Larger (if host uses Tailwind) Smaller
Maintenance More overhead Less overhead

Testing the Examples

Prerequisites

  • Ruby 3.x
  • Rails 8.1.1+
  • Node.js (for Tailwind CSS)

Running blogh_isolate

cd blogh_isolate
bundle install

# Build Tailwind CSS
bundle exec rake blogh:tailwindcss:build

# Run the test application
cd test/dummy
bin/rails server

# Visit http://localhost:3000

Running blogh_main_app_layout

cd blogh_main_app_layout
bundle install

# The host application must have Tailwind CSS configured
cd test/dummy
bin/rails server

# Visit http://localhost:3000

Recommendations

Choose Isolated Build If:

  • You're building a gem for public distribution
  • The engine needs to work in various applications
  • You require specific Tailwind configuration
  • Complete style isolation is essential

Choose Shared Build If:

  • Building an engine for a specific application
  • The host app already uses Tailwind CSS
  • You want to minimize dependencies
  • Sharing the design system is beneficial

Additional Resources

License

MIT

About

a tutorial of using tailwind with Rails engine

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages