How to Setup Storybook with Rails View Components in under 10 Minutes
Component driven design is one of the best things to come out of the ReactJS framework, and Storybook is an excellent way for a team to collaborate on new features while also conforming to a team style guide.
In a codebase, it’s easy for the different erb files to quickly become a mess when using a utility-style framework like Tailwind CSS. In no time at all, your app loses one of the essential elements of style.
Consistency.
View Components along with Storybook, can help solve this issue while also providing an excellent collaboration experience with your team members.
Why use Storybook with View Components
The main reason is that you can test edge cases with your design. For example, you might want to see what it looks like with different languages or different text when making a button.
- Test edge cases with your design dynamically
- Share your style guide with your team, including your managers, product managers and designers, so that they can iterate on it
- Document use cases
- Test components for accessibility issues.
If I have convinced you at all, feel free to follow along.
1. Set up a rails app (Optional)
Experienced Rails developers usually read this blog. I’m assuming that you are adding this to an existing app. If not, run the following command:
rails new Storybook
2. Install the necessary gems
To note. As of writing, there is no generator for the View Component Storybook gem, but I imagine there will be soon. Below is a summary of all the notes I took while investigating the gem. Hopefully, everything is there for you to get up and running to experience Storybook for yourself.
bundle add view_component
bundle add view_component_storybook
Add require "view_component/storybook/engine"
to config/application.rb
# config/application.rb
require_relative 'boot'
require 'rails/all'
require "view_component/storybook/engine"
....
Add */*.stories.json
to .gitignore
2. Configure Asset Hosts
If your view components depend on Javascript, CSS or other assets served by the Rails application, you will need to configure asset_hosts
appropriately for your various environments. For local development, this is a simple as adding to config/development.rb
:
Rails.application.configure do
config.action_controller.asset_host = 'http://localhost:3000'
end
Naturally, you can do the same for staging and production.
3. Install Storybook via yarn
- Add Storybook server as a dev dependency. The Storybook Controls addon isn’t needed but comes recommended.
yarn add @storybook/server @storybook/addon-controls --dev
- Add an NPM script to your package.json to start your Storybook later.
// package.json { "scripts": { "storybook": "start-storybook" } }
- Create a folder called
.storybook
. It is a dotfolder. From the command line, do the following:mkdir .storybook
- Create a file called .storybook/main.js file to configure Storybook to find the JSON stories the gem creates. Also, configure the Controls addon:
touch .storybook/main.js
// .storybook/main.js module.exports = { stories: ['../test/components/**/*.stories.json'], // stories: ['../spec/components/**/*.stories.json'], if using RSpec addons: [ '@storybook/addon-controls', ], };
- Create the .storybook/preview.js file to configure Storybook with the Rails application URL to call for the HTML content of the stories
touch .storybook/preview.js
//.storybook/preview.js export const parameters = { server: { url: `http://localhost:3000/rails/stories`, }, };
4. Your First StoryBook Component
ViewComponent::Storybook::Stories
provides a way to preview components in Storybook.
Suppose our app has a ButtonComponent
that takes a button_text
parameter:
class ButtonComponent < ViewComponent::Base
def initialize(button_text:)
@button_text = button_text
end
end
We can write a stories describing the ButtonComponent.
So in spec/components/stories or test/components/stories, put in the following
class ButtonComponentStories < ViewComponent::Storybook::Stories
story(:with_short_text) do
constructor(title: "my title")
end
story(:with_long_text) do
constructor(title: "my title")
end
end
5. Generate Storybook JSON
Generate the Storybook JSON stories by running the rake task:
rake view_component_storybook:write_stories_json
Now you should be able to start the rails app and run the Storybook rails s yarn storybook # in separate tab
Configuration (RSpec Only)
By Default ViewComponent::Storybook expects to find stories in the folder test/components/stories
. This can be configured by setting stories_path
in config/application.rb
. For example if you’re using RSpec you might set the following configuration:
config.view_component_storybook.stories_path = Rails.root.join("spec/components/stories")
Gotcha’s
I had to add rack-cors gem and configure wildcard access for development.
bundle add rack-cors
In config/development.rb, I added the following lines:
# config/development.rb
config.action_controller.asset_host = 'http://localhost:5000'
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '/rails/stories/*', :headers => :any, :methods => [:get]
end
end
Another Gotcha, I ran into. After you update the HTML for the component, you have to rerun the rake task.
Conclusion
There you have it. Hopefully, this has gotten you up and running in under 10 minutes. If not, feel free to reach out to me to see if I can help. Also, be sure to check out the docs. This gem is still under development and was even updated while I was writing this article.
Happy coding.