Server rendered components with template fragments and webcomponents

As I use webcomponents more, I found myself wanting a way to define the HTML for webcomponents with a non-trivial amount of light DOM contents in a more reusable programatic way. So far, I’ve found that modelling webcomponents as template fragments is a reasonably ergonomic solution. It enables usage such as:

Show Plain Text
  1. echo $this->element('components/select_box', ['options' => $options, 'name' => 'project_id');

This approach lets us model webcomponents with an interface that feels close to server rendered components. We can easily pass our ORM entities, API responses and calculated data into self-contained ‘functional components’ that generate the necessary HTML for a webcomponent. For example our select_box template component could have the following contents:

Show Plain Text
  1. <?php
  2. $hidden = $this->templates->format('input', [
  3.     'name' => $data['name'],
  4.     'value' => $selected,
  5.     'type' => 'text',
  6.     'attrs' => $this->templates->formatAttributes($inputAttrs),
  7. ]);
  8.  
  9. $optionsSet = [];
  10. foreach ($options as $option) {
  11.     $optionsSet[] = sprintf(
  12.         '<select-box-option value="%s">%s</select-box-option>',
  13.         $option['value'] ?? null,
  14.         $option['name']
  15.     );
  16. }
  17. ?>
  18. <select-box name="{{name}}"{{attrs}}>
  19.     <?= $hidden ?>
  20.     <select-box-current>
  21.         <span class="select-box-value"></span>
  22.         <input type="text" class="select-box-input" />
  23.     </select-box-current>
  24.     <select-box-menu><?= implode("\n", $optionsSet ??></select-box-menu>
  25. </select-box>

Without any additional styling our custom HTML element will render as a div. However, we can use the custom componentn name in our CSS as well. This gives us a great way to attach our application’s CSS to named parts of the DOM. For more interactive components, you can also define a webcomponent class in JavaScript.

It’s that easy

There isn’t much to this pattern beyond that. We pair functional blocks of our application’s HTML and behavior to template fragments and webcomponents for any client-side interactions. With this solution we have a simple convention for pairing server rendered HTML and our client-side components. I’m going to continue exploring this pattern, but so far this ia a powerful and scalable way to design server rendered applications.

Comments

There are no comments, be the first!

Have your say: