Web Components で実現する Hotwire とフロントエンドフレームワークの橋渡し / Bridging with Web Components
by
Daichi KUDO
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Web Componentsで実現する Hotwireとフロントエンドフレーム ワークの橋渡し 2025.9.26 Kaigi on Rails 2025 Daichi KUDO (@da1chi24)
Slide 2
Slide 2 text
自己紹介 ● Daichi KUDO ○ GitHub @kudoas ○ Twitter @da1chi24 ● Classi 株式会社 ● Ruby歴 3年 ● Startup Angular 運営
Slide 3
Slide 3 text
https://corp.classi.jp/careers/ 「Classi」「tetoru」 は Ruby on Rails で作られています
Slide 4
Slide 4 text
この発表で伝えたいこと ● Web Components で Rails/Hotwire サービスに フロントエンドフレームワークのコンポーネントを 少しずつ導入 できること ● Web Components と Rails の 連携方法 や 活用のヒント
Slide 5
Slide 5 text
この発表の対象者 ● Hotwire に関心がある/すでに利用している人 ● フロントエンドの知識やコンポーネントの資産を 活かして開発したい人
Slide 6
Slide 6 text
この発表では話さないこと ● Hotwire とはなにか ● Hotwire での UI/UX の実現方法
Slide 7
Slide 7 text
Hotwireとは何か知りたい方はおすすめです 猫でもわかるHotwire入門 Turbo編 - zenn
Slide 8
Slide 8 text
Hotwire 実践編はこちらがおすすめです Hotwire or React? 〜Reactの録画機能をHotwireに置き換えて得られた知見〜 高度なUI/UXこそHotwireで作ろう
Slide 9
Slide 9 text
アジェンダ ● Web Components を選択した背景 ● 段階的な導入事例 ● まとめ
Slide 10
Slide 10 text
アジェンダ ● Web Components を選択した背景 ● 段階的な導入事例 ● まとめ
Slide 11
Slide 11 text
新規サービスの立ち上げ 少人数エンジニア・スピード重視
Slide 12
Slide 12 text
新規サービスの立ち上げ 少人数エンジニア・スピード重視 単一の Rails アプリで開発できる Hotwire⚡採用
Slide 13
Slide 13 text
自社サービス間のデザインを統一したい課題 サービスA サービスB サービスC 共通化のために UIコンポーネント を利用している Angular製
Slide 14
Slide 14 text
提供されるコンポーネント例 Storybook - Classi Design System 他にモーダルやカレンダー などのよく利用されるものが 用意されている
Slide 15
Slide 15 text
Classiの一般的なアーキテクチャ Angular SPA Rails API Angular UIコンポーネント Angular SPA Rails API Angular SPA Rails API
Slide 16
Slide 16 text
今回の場合 Rails + Hotwire これができれば理想 Angular UIコンポーネント
Slide 17
Slide 17 text
今回の場合 そのままテンプレートに 埋め込んでも動かない Rails + Hotwire Angular UIコンポーネント
Slide 18
Slide 18 text
今回の場合 Angular UIコンポーネント Angular Rails + Hotwire サービスで管理するものを 増やしたくない
Slide 19
Slide 19 text
橋渡し役の Web Components を採用した Rails + Hotwire Web Components Angular UIコンポーネント
Slide 20
Slide 20 text
Web Components とは Web標準に基づく 新しいカスタムの、再利用可能な、カプセル化された HTMLタグを作成できる Webプラットフォーム APIのセット Introduction - webcomponents.org
Slide 21
Slide 21 text
Custom Element(カスタム要素) 任意の振る舞いを定義したクラスでHTML要素を登録 UIコンポーネントを HTML要素 として使える カスタム要素の使用 - Web API | MDN JavaScript
Slide 22
Slide 22 text
HTML要素なので Hotwire と共存できる サーバーで HTML をレスポンスする 名前: Daichi KUDO メール: example@com テンプレート(ERB)
Slide 23
Slide 23 text
Railsと疎結合で変更に強い HTML標準の インターフェース でやり取りする Rails + Hotwire Web Components Angular UIコンポーネント
Slide 24
Slide 24 text
アジェンダ ● Web Components を選択した背景 ● 段階的な導入事例 ● まとめ
Slide 25
Slide 25 text
コンポーネントを Web Components に変換 Rails + Hotwire Web Components Angular UIコンポーネント
Slide 26
Slide 26 text
コンポーネントを Web Components に変換 Web Components (Custom Element) フロントエンド コンポーネント Rails起動時に登録 フレームワーク・ライブラリ
Slide 27
Slide 27 text
コンポーネントを Web Components に変換 HTML属性/DOMプロパティ Custom Event 入力 出力 Web Components (Custom Element) 変換する実装の詳細はこの発表では割愛します フロントエンド コンポーネント インターフェースは Web標準にマッピング
Slide 28
Slide 28 text
Angular UIコンポーネント Web Components を Rails に導入する Rails + Hotwire Web Components Web Components
Slide 29
Slide 29 text
※実際のサービスに存在する画面ではありません この画面を題材に導入します
Slide 30
Slide 30 text
段階的な導入事例 ● 相互作用しない独立したもの ● Railsからデータを連携するもの ● ユーザー入力を連携するもの シンプルなものから 複雑なものの順に導入します
Slide 31
Slide 31 text
段階的な導入事例 ● 相互作用しない独立したもの ● Railsからデータを連携するもの ● ユーザー入力を連携するもの シンプルなものから 複雑なものの順に導入します
Slide 32
Slide 32 text
アイコン フッター
Slide 33
Slide 33 text
● 標準のHTML要素と同じ ● HTML属性も設定できる 利用方法
Slide 34
Slide 34 text
これだけで導入完了
Slide 35
Slide 35 text
段階的な導入事例 ● 相互作用しない独立したもの ● Railsからデータを連携するもの ● ユーザー入力を連携するもの
Slide 36
Slide 36 text
ヘッダー エラーメッセージ
Slide 37
Slide 37 text
ユーザー情報(ハッシュ) 学校名(文字列) エラーメッセージ(文字列) 表示切り替え(真偽値)
Slide 38
Slide 38 text
Custom Elementへのデータの渡し方 app/views/layouts/application.html.erb
Slide 39
Slide 39 text
Custom Elementへのデータの渡し方 app/views/layouts/application.html.erb HTML属性で渡す 文字列のみ・宣言的
Slide 40
Slide 40 text
Custom Elementへのデータの渡し方 app/views/layouts/application.html.erb DOMプロパティで渡す 柔軟なデータ型・命令的
Slide 41
Slide 41 text
Custom Elementへのデータの渡し方 JSONに変換してエスケープを外す ⚠注意が必要 ⚠ app/views/layouts/application.html.erb
Slide 42
Slide 42 text
ユーザー入力が含まれる場合の脆弱性 Restrictions for contents of script elements - HTML Standard 任意のDOMを挿入できる で script タグを強制終了
Slide 43
Slide 43 text
カスタムデータ属性を利用した安全な渡し方 JSONをエスケープして データ属性に渡す データ属性をパースする Embedding custom non-visible data with the data-* attributes - HTML Standard
Slide 44
Slide 44 text
サービスの骨格が完成
Slide 45
Slide 45 text
段階的な導入事例 ● 相互作用しない独立したもの ● Railsからデータを連携するもの ● ユーザー入力を連携するもの
Slide 46
Slide 46 text
日付入力要素
Slide 47
Slide 47 text
1.2 フォーム要素を生成するヘルパー form_with で生成されるフォームビルダーオブジェクトには、 「テキストフィールド」「チェックボックス」「ラジオボタン」などの一般的な フォーム要素を生成するためのヘルパーメソッドが多数用意されていま す。 通常 Rails でフォームを組み立てる場合 フォーム要素を生成するヘルパー - Railsガイド
Slide 48
Slide 48 text
フォームヘルパーとモデルの連携 Userモデルに紐づいたフォーム
Slide 49
Slide 49 text
フォームヘルパーとモデルの連携 Userモデルに紐づいたフォーム Railsの規約に基づいた HTML属性を付与 生成される HTML フォーム入力の命名規約とparamsハッシュ - Railsガイド
Slide 50
Slide 50 text
最初に試したこと:カレンダーだけを導入する 日付イベント発火 Custom Element フォームヘルパーの input 要素 日付クリック 👇 Custom Event
Slide 51
Slide 51 text
フォームとカレンダーの連携 Custom Element Custom Event の連携 雰囲気だけ見てください
Slide 52
Slide 52 text
フォームとカレンダーの連携 雰囲気だけ見てください 赤い部分が連携のための実装
Slide 53
Slide 53 text
フォームとカレンダーの連携 雰囲気だけ見てください 赤い部分が連携のための実装 毎回連携するのが面倒
Slide 54
Slide 54 text
理由:再利用する単位が間違っていた カレンダー input要素 Rails モデル 面倒なポイント フォームヘルパー Custom Element
Slide 55
Slide 55 text
本来こうした方が再利用しやすい カレンダー input要素 Rails モデル フォームヘルパー Custom Element 日付入力要素として1 つにまとめる
Slide 56
Slide 56 text
目指す形:フォームヘルパーだけで導入できる UI Model連携 フォームバリデーション 機能 デザイン
Slide 57
Slide 57 text
Custom Elements を1つにまとめる デザイン カレンダーと input 要素を 1つにする Custom Element 属性 を input 要素に連携する ステップ1
Slide 58
Slide 58 text
Custom Elements を1つにまとめる デザイン Custom Element 属性 を input 要素に連携する input 要素と 同じ属性を設定できるように するのがポイント ステップ1
Slide 59
Slide 59 text
フォームヘルパーと連携する フォームビルダーをカスタマイズする - Railsガイド フォームビルダーを カスタマイズして ヘルパーを追加できる ステップ2
Slide 60
Slide 60 text
Custom Elment フォームヘルパーを上書きして input を差し替え input 要素の属性を引き継いで Custom Element に差し替える 既存の input 要素 ステップ2
Slide 61
Slide 61 text
フォームビルダー (MyFormBuilder)の実装例
Slide 62
Slide 62 text
フォームビルダー( MyFormBuilder)の実装例 作成した Custom Element に input要素の属性を詰め替える
Slide 63
Slide 63 text
フォームビルダー( MyFormBuilder)の実装例 インターフェースが同じなのでシンプル 作成した Custom Element に input要素の属性を詰め替える
Slide 64
Slide 64 text
builderオプションで 自動的に処理を引き継げる Custom Element を利用するヘルパーが完成 共通で適用したい場合 ActionView::Base.default_form_builder
Slide 65
Slide 65 text
一通り導入完了
Slide 66
Slide 66 text
アジェンダ ● Web Componentsを選択した背景 ● 段階的な導入事例 ● まとめ
Slide 67
Slide 67 text
まとめ ● Web Componentsを利用した事例の紹介 ○ Custom Element とRails は Web標準の仕様で連携可能 ● 利用のヒント ○ シンプルなものから少しずつ導入する ○ カスタムデータ属性で安全にデータを渡す ○ 利用しやすい単位で Custom Element を再設計する ○ Rails の書き味を変えない工夫
Slide 68
Slide 68 text
ご清聴ありがとうございました EOL 2025.9.26 Kaigi on Rails 2025 Daichi KUDO (@da1chi24)