🚨 You are viewing the legacy v1.x docs. See the new v2 documentation →

Inspector Panels

The Lookbook preview inspector is where each preview is rendered alongside its source code, notes and more.

The inspector is made up of a number of tabbed panels, grouped into two areas - the preview area at the top (with Preview and HTML tabs) and the drawer area at the bottom (with Source, Notes, and Params tabs).

It is possible to add custom tab panels into the drawer area, as well as to hide, reposition or reorder the system-provided panels.

Adding a custom panel

You can add a custom inspector panel using the Lookbook.define_panel method when you configure your Lookbook installation:

Lookbook.define_panel(<name>, <partial_path>, <opts?>)

A unique name for the panel

Type: Symbol | String

Path to the partial template used to render the panel

Type: String

Optional Hash of panel options (see below for details)

Type: Hash

For example, a very simple ‘info’ panel could be created as follows:

# config/application.rb
Lookbook.define_panel(:info, "panels/info", {
  label: "Extra Info"
<!-- app/views/panels/_info.html.erb -->
<div class="lookbook-panel">
  <h2>Some information</h2>
    <li>You are looking at the '<%= preview.label %>' preview</li>
    <li>The preview file path is: '<%= preview.full_path %>'<li>
    <li>There are <%= examples.size %> examples in this preview<li>

Panel partial templates can be located anywhere within your app’s views directory.

Panel options

There are a number of available options when defining a panel.


The text to be displayed in the tab for the panel


keyboard shortcut to make panel become the active tab

Type: String

Disabled tabs are still accessible but are greyed out in the UI

Type: Boolean

Whether or not to display the tab/panel

Type: Boolean,Default: true

If present, the panel will display a copy button that copies the value of this property to the clipboard when clicked

Type: String

Position of the tab in the tab list

Type: Integer

A Hash of local variables that will be passed to the panel when it is rendered

Type: Hash
Lookbook.define_panel(:info, "path/to/view_partial", {
  label: "New Panel",
  position: 1,
  hotkey: "ctrl.n",
  disabled: false,
  show: true,
  copy: "Content to be copied",
  locals: {
    last_updated: '2022-03-02'

All panel option values can be provided either as a simple static value or as a lambda function. Lambdas receive a single object with data relating to the currently active preview/example. For example:

  label: "Params",
  disabled: ->(data) { data.context.params.none? } # grey out the Params tab if no params are set for the current preview

The data hash provided as the single argument to any lambda functions contains the same set of objects that are provided to the panel partial template (see below for full details):


Preview object representing the current preview


Array of rendered examples that are present in the current preview


Data about the request context


The main Lookbook app instance

Panel templates

Panel template files are just regular ERB partials. Unlike pages they are not additionally parsed as markdown.

To match the padding and styles of the system panels you should ensure your panel’s content is in an element with the .lookbook-panel class applied to it.

<div class="lookbook-panel">
  <!-- your panel content here -->

Each panel is has access to a number of variables and helpers that can be used to build dynamic content.


Any locals defined in the panel options will be available, plus the following:


The resolved panel options object (see above for details)

  This <%= panel.label %> panel can be switched
  to using the keyboard shortcut <%= panel.hotkey %>


A preview object representing the current preview.

<h2>This is the <%= preview.label %> preview</h2>


An object representing the example or group of examples currently being rendered

<h2>Currently rendering '<%= target.label %>' which is <%= "not" unless target.type == :group %> a group.</h2>


An array of rendered example objects representing the individual examples rendered in the current preview. For non-grouped (i.e. regular) previews, this array will always only have one item.

<p>This preview is showing <%= examples.size %> examples rendered together.</p>
<p>Here is the source code for each example:</p>
<% examples.each do |example| %>
    <%= example.source %>
<% end %>


Request context data


Hash of supplied preview parameters, if any


URL path of the current page

<p>Current URL path: <%= context.path %></p>


Shortcut for accessing the Lookbook.data store.

<p>My custom data variable value: <%= data.my_variable %></p>


The main Lookbook app instance.


Array of all preview objects


Array of all page objects


Lookbook logger instance

<p>There are <%= app.previews.size %> previews available.</p>
<% app.logger.info("Successfully output the number of previews") %>


The following helpers are available in panel templates:


Adds syntax highlighting to blocks of code.

The code helper is an alternative to using markdown code blocks for templates that have markdown parsing disabled, or for when more control is required.

code(<lang?>) { <block_content> }

The language the code is written in. Defaults to :ruby

Type: Symbol
<!-- Highlight Ruby code -->
<%= code do %>
  # Ruby code to highlight goes here
<% end %>

<!-- Highlight a different language (HTML) -->
<%= code :html do %>
  <!-- HTML code to highlight goes here -->
<% end %>


Displays an icon.

Lookbook uses icons from the Feather Icons set and a full list of available icon names can be found on that site.

icon(<icon_name>, <opts?>)

The name of the icon to display

Type: Symbol

Hash of options

Type: Hash
<%= icon :trash %>
<%= icon :camera, size: 6, style: "color: red;" %>

Styling panel content

If you wish to specify custom CSS rules to style the contents of the panel, just include a <style> element in the panel partial template:

  h3 {
    color: green;

  <h3>My Custom Panel</h3> <!-- will be green -->
  <!-- ... -->

The <style> element will be removed when the panel is rendered and any styles will be automagically scoped to the panel that they are defined in, so they will not affect other panels or leak out to affect the styling of the UI in general.

Utility classes

There are a number of utility classes available for use in panels to make it easier to match the look and feel of the rest of the Lookbook UI.


Apply to the panel’s root element


Apply to text content containers. Adds default prose styles to child elements.

Adding JavaScript

Lookbook uses Alpine JS for its UI, and it is available for use in panel templates too. It’s a great way to add interactivity without ever having to touch a script tag.

For example, to add a button to show/hide a piece of content in the panel, it’s as simple as this:

<div x-data="{ open: false }">
  <button @click="open = !open">Show/hide content</button>
  <div x-show="open">
    Some content here

Check out the Alpine JS documentation for more information.

Because of the way that new content is loaded in to the UI when navigation occurs, adding arbitrary JavaScript in a script tag within the panel template may not always work as expected, so it is recommended to use Alpine for adding interactivity where required.

Editing system panels

It is possible to edit, reorder or remove any of the system-provided panels, if required. The following panels are provided by Lookbook:


Renders the preview in a resizable container


The rendered preview HTML source code


The preview example method source code (or preview template source, if using)


Preview notes panel


Inputs and controls for dynamic preview parameters

Removing a panel

To remove a panel from the UI entirely you can use the Lookbook.remove_panel method.


The name of the panel to remove (see above for a list of valid panel names)

Type: Symbol
Lookbook.remove_panel(:notes) # Notes panel will not appear in the UI

Editing panel properties

If you want to tweak any properties of a system-defined panel, you can do so using the Lookbook.amend_panel method.

Lookbook.amend_panel(<name>, <opts>)

The name of the panel to edit (see above for a list of valid panel names)

Type: Symbol

A Hash of panel options to override (see above for full option details)

Type: Hash
Lookbook.amend_panel(:params, {
  label: "Knobs", # change the tab text
  hotkey: "ctrl.k", # override hotkey
  position: 1 # move to first position in the tab list