Callee

Callee is excited you’re going to build some components!

Component SSR in Ruby

You can use Heartml entirely client-side, but if you want to be able to render web components on the server, “expand” components, use Declarative Shadow DOM (DSD), and other HTML-first techniques, you need a server-side rendering solution (SSR).

Heartml’s Ruby renderer can be used inside of Bridgetown, Rails, and other Ruby web frameworks. Just add heartml to your Gemfile:

bundle add heartml

Bridgetown

After adding the heartml gem, update your config/initializers.rb file:

Bridgetown.configure do |config|
  # existing configuration here

  init :heartml
end

Then you can add component pairs in your src/_components folder: an .rb file for the Ruby component definition, and a .heartml file for the HTML, CSS, and JavaScript (optional).

Here’s an example component which lets you define figures including an image and a caption easily in Markdown or other HTML file formats:

# src/_components/image_figure.rb

class ImageFigure < Bridgetown::Component
  include Heartml

  define "image-figure"

  attr_reader :caption

  def initialize(caption: nil, **attributes)
    @caption = caption
    @attributes = attributes
  end

  def show_caption = @caption && !@caption.empty?
end
<!-- src/_components/image_figure.heartml -->

<figure>
  <slot></slot>
  <figcaption server-effect="$show(.show_caption); .caption"></figcaption>
</figure>

<style>
  :host {
    display: block;
    margin-block: var(--size-8);
  }

  ::slotted(img) {
    display: block;
    margin-inline: auto;
    box-shadow: 0px 10px 18px color-mix(in oklch, var(--dark-pop-color), black 55%);
  }

  figure {
    margin: 0;
    margin-inline: calc(0rem - var(--main-padding-inline));
  }
  
  figcaption {
    margin-block: var(--size-3) 0;
    padding-inline: calc(var(--main-padding-inline) / 2);
    text-align: center;
    font-size: var(--font-size-1);
    font-style: italic;
    color: var(--emphasis-color);

    :host([caption-right]) & {
      text-align: right
    }
  }
</style>

As you can see, the effects syntax on the server matches the syntax you’d use for client-side rendering. More on this below.

Bridgetown will now automatically render this component any time you include the component tag in HTML via the Heartml Ruby renderer which hooks into Bridgetown via HTML Inspectors and Nokolexbor. For example:

# Some Markdown File.

<image-figure caption="The caption for the image." markdown="block">
  ![An Image](/images/some-image.jpg)
</image-figure>

Which renders out to:

<image-figure><template shadowrootmode="open"><figure>
  <slot></slot>
  <figcaption>The caption for the image.</figcaption>
</figure><style>
/* component styles omitted for brevity */
</style></template>
  <img src="/images/some-image.jpg" alt="An Image">
</image-figure>

Rails

docs coming TDB

Other Frameworks

docs coming TBD

Attributes

The attributes on the component tag are translated to keyword arguments in your class initializer.

**attributes

@attributes = attributes

server_args

Server Effects, Child Content, and Light/Shadow DOM