frontend-craft

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Frontend Craft — Gateway

前端实践 — 网关

Triage incoming Hotwire frontend requests, apply cross-cutting principles, and route to the right specialist skill. This skill owns no implementation cookbook — each specialist carries its own.
对Hotwire前端请求进行分流处理,应用跨领域原则,并转派至合适的专业技能模块。本模块不包含实现指南——各专业模块自有对应的实现文档。

Routing Table

路由表

Request PatternRoute To
URL, history, frame navigation, Drive caching, rendering lifecycle, view transitions, page-refresh morphing
turbo-navigation-rendering
Turbo Streams, broadcasting, stream morphing, optimistic state, real-time sync via broadcasting
turbo-streams
Stimulus controller design, lifecycle, DOM behavior, browser APIs
stimulus-controllers
Form submission, validation, autosave, inline edit, submit UX
hotwire-forms
Media playback, gallery, upload preview, rich content integrations
media-content
Native bridge, web/native boundary, path configuration
hotwire-native
Broad or ambiguous frontend requestStay here — apply principles below, then route
请求模式转至目标
URL、历史记录、框架导航、Drive缓存、渲染生命周期、视图过渡、页面刷新形态转换
turbo-navigation-rendering
Turbo Streams、广播、流形态转换、乐观状态、通过广播实现实时同步
turbo-streams
Stimulus控制器设计、生命周期、DOM行为、浏览器API
stimulus-controllers
表单提交、验证、自动保存、在线编辑、提交体验
hotwire-forms
媒体播放、图库、上传预览、富内容集成
media-content
Native桥接、Web/Native边界、路径配置
hotwire-native
宽泛或模糊的前端请求留在此处 — 应用以下原则后再转派

Core Workflow

核心工作流程

Step 1: Classify the Problem

步骤1:分类问题

Determine the primary domain: navigation/rendering, streams/state sync, controller behavior, forms/submission, media UX, or native bridge. If the request clearly maps to one domain, route immediately.
确定核心领域:导航/渲染、流/状态同步、控制器行为、表单/提交、媒体体验或Native桥接。若请求明确匹配某一领域,立即转派。

Step 2: Apply Common Principles

步骤2:应用通用原则

Before routing, check whether these cross-cutting principles apply:
  1. Prefer built-in Turbo semantics first. Use
    data-turbo-*
    attributes, frame
    src
    , and stream actions before reaching for custom JavaScript.
  2. Decide ownership first. Every UI change must have a clear owner: a URL (Drive), a frame ID (Frames), or a stream target (Streams). Ambiguous ownership causes bugs.
  3. Avoid fixed timeouts as proxy for completion. Listen for lifecycle events (
    turbo:load
    ,
    turbo:submit-end
    ,
    turbo:before-stream-render
    ) instead of
    setTimeout
    .
  4. Validate back/forward/refresh behavior. Every navigation pattern must work correctly when the user presses back, forward, or refresh.
  5. Preserve focus and perceived continuity. Never suggest custom focus/caret/selection restoration without its completion binding. After a frame rerender, name or show
    data-action="turbo:frame-render@document->focus-restore#restore"
    (adapt the controller identifier to the implementation) and guard the intended frame. When the behavior depends on the response outcome, match the predicate to that behavior: use
    event.detail.fetchResponse.statusCode === 422
    for validation-error focus restoration, and reserve
    event.detail.fetchResponse.succeeded
    for success-only effects. If the binding and applicable guards are not carried through, omit the optional behavior. Frame updates must not disrupt scroll position.
  6. Design for idempotency and retry. Stream actions and form submissions must be safe to replay without duplication or corruption.
  7. Separate browser event concerns from Turbo lifecycle concerns. DOM events (click, input, resize) and Turbo events (turbo:load, turbo:before-cache) serve different purposes — do not conflate them.
  8. Classify stale navigation before prescribing cache controls. Distinguish an application-visit preview, a Turbo restoration visit, and browser bfcache; they do not share one lifecycle or fetch behavior.
Documentation accuracy: Start with the routed specialist's local, commit-pinned handbook plus its errata; these are the reproducible authority for this release. Use Context7 only to cross-check a version-sensitive API. If Context7 is unavailable or ambiguous, rely on the manifest-verified release tag/commit snapshot rather than an unpinned
main
page or memory. Examples in this plugin target Rails 8.1, Turbo 8, and turbo-rails 2.
转派前,检查是否适用以下跨领域原则:
  1. 优先使用Turbo内置语义。先使用
    data-turbo-*
    属性、frame
    src
    和流操作,再考虑自定义JavaScript。
  2. 先明确职责归属。每一处UI变更必须有明确的归属方:URL(Drive)、frame ID(Frames)或流目标(Streams)。模糊的归属会引发Bug。
  3. 避免用固定超时替代完成状态监听。监听生命周期事件(
    turbo:load
    turbo:submit-end
    turbo:before-stream-render
    )而非
    setTimeout
  4. 验证后退/前进/刷新行为。所有导航模式在用户按下后退、前进或刷新按钮时必须正常工作。
  5. 保留焦点与感知连续性。切勿仅建议自定义焦点/光标/选区恢复而不绑定完成逻辑。框架重新渲染后,指定或展示
    data-action="turbo:frame-render@document->focus-restore#restore"
    (根据实现调整控制器标识符)并锁定目标框架。当行为依赖响应结果时,匹配对应断言:使用
    event.detail.fetchResponse.statusCode === 422
    实现验证错误时的焦点恢复,仅在成功场景下使用
    event.detail.fetchResponse.succeeded
    。若未绑定相关逻辑与防护,请勿添加该可选行为。框架更新不得干扰滚动位置。
  6. 设计幂等性与重试机制。流操作与表单提交必须可安全重放,避免重复或数据损坏。
  7. 区分浏览器事件与Turbo生命周期事件。DOM事件(click、input、resize)与Turbo事件(turbo:load、turbo:before-cache)用途不同——请勿混淆。
  8. 在指定缓存控制前分类过期导航。区分应用访问预览、Turbo恢复访问与浏览器bfcache;它们的生命周期与请求行为各不相同。
文档准确性说明:以转派目标专业模块的本地提交锁定手册及勘误为准;这些是当前版本的可复现权威参考。仅在跨版本API核对时使用Context7。若Context7不可用或内容模糊,依赖清单验证的发布标签/提交快照,而非未锁定的
main
分支页面或记忆内容。本插件示例针对Rails 8.1、Turbo 8与turbo-rails 2版本。

Step 3: Resolve Overlap

步骤3:解决领域重叠

When a request spans multiple skills, assign a lead skill:
OverlapLeadSupport
Form inside a lazy-loaded frame
hotwire-forms
turbo-navigation-rendering
Stream-driven form validation
hotwire-forms
turbo-streams
Media upload with progress indicator
media-content
hotwire-forms
Optimistic UI with stream reconciliation
turbo-streams
turbo-navigation-rendering
Frame navigation with an independent controller lifecycle/async constraint
turbo-navigation-rendering
stimulus-controllers
Bridge component with form submission
hotwire-native
hotwire-forms
CSS architecture for controller-driven UI
stimulus-controllers
(reference only)
Page-refresh morphing (
<meta name="turbo-refresh-method" content="morph">
)
turbo-navigation-rendering
turbo-streams
Stream-action morphing (
turbo_stream.replace method: :morph
)
turbo-streams
turbo-navigation-rendering
View transitions during page navigation (Drive visits, frame navigation)
turbo-navigation-rendering
turbo-streams
View transitions triggered by stream updates (list animations, item add/remove)
turbo-streams
turbo-navigation-rendering
Rule: the skill that owns the hardest constraint (correctness, data integrity, platform boundary) leads. List
stimulus-controllers
as support only when the controller has an independent lifecycle, target, async-resource, or browser-API constraint; ordinary glue remains inside the lead specialist.
当请求涉及多个技能模块时,指定主导模块:
重叠场景主导模块支持模块
懒加载框架内的表单
hotwire-forms
turbo-navigation-rendering
流驱动的表单验证
hotwire-forms
turbo-streams
带进度指示器的媒体上传
media-content
hotwire-forms
带流协调的乐观UI
turbo-streams
turbo-navigation-rendering
带独立控制器生命周期/异步约束的框架导航
turbo-navigation-rendering
stimulus-controllers
带表单提交的桥接组件
hotwire-native
hotwire-forms
控制器驱动UI的CSS架构
stimulus-controllers
(仅作参考)
页面刷新形态转换(
<meta name="turbo-refresh-method" content="morph">
turbo-navigation-rendering
turbo-streams
流操作形态转换(
turbo_stream.replace method: :morph
turbo-streams
turbo-navigation-rendering
页面导航期间的视图过渡(Drive访问、框架导航)
turbo-navigation-rendering
turbo-streams
流更新触发的视图过渡(列表动画、项添加/移除)
turbo-streams
turbo-navigation-rendering
规则:拥有最严格约束(正确性、数据完整性、平台边界)的模块为主导模块。仅当控制器存在独立生命周期、目标、异步资源或浏览器API约束时,才将
stimulus-controllers
列为支持模块;普通粘合逻辑仍归主导模块负责。

Routing Examples

转派示例

User RequestClassificationRoute
"Add a modal that lets users edit their profile inline"Form + frame boundaryLead:
hotwire-forms
, Support:
turbo-navigation-rendering
"Make the notification count update in real-time across tabs"Real-time + cross-tab sync
turbo-streams
"Add a carousel for product images with swipe gestures"Media rendering + library integration
media-content
用户请求分类转派方案
"添加一个允许用户在线编辑个人资料的弹窗"表单 + 框架边界主导:
hotwire-forms
,支持:
turbo-navigation-rendering
"实现通知计数跨标签页实时更新"实时同步 + 跨标签页同步
turbo-streams
"添加带滑动手势的产品图片轮播组件"媒体渲染 + 库集成
media-content

Step 4: Route to Specialist

步骤4:转派至专业模块

Hand off to the identified specialist skill by invoking it directly. Pass along any context from Step 2 (applicable principles) and Step 3 (lead/support assignment). The specialist will load its own references, handbook, and examples as needed. For multi-skill requests, invoke the lead skill — it will escalate to the support skill when needed.
Do not compress a specialist's correctness-sensitive distinctions into only a route name. A gateway triage or handoff must:
  • Name the lead, any support roles that are present, and each relevant URL/frame/stream owner.
  • Carry through exact statuses, visit types, and lifecycle event names when they affect correctness. If code shows a lifecycle handler, also name or show its binding.
  • Keep the minimal Rails response/delivery contract in scope. Escalate deeper backend design only when the request actually implicates it.
  • Self-check completion-dependent optional behavior: never leave focus/caret/selection restoration as a bare suggestion. For a frame rerender, carry through
    data-action="turbo:frame-render@document->focus-restore#restore"
    with its controller identifier adapted to the implementation, plus an intended frame guard. When response outcome matters, use the matching predicate:
    event.detail.fetchResponse.statusCode === 422
    for validation-error focus restoration and
    event.detail.fetchResponse.succeeded
    only for success-only effects. If the binding and applicable guards are not carried through, omit it; never invent a fixed delay.
  • End with separate acceptance checks for each owner's state and failure path.
直接调用指定的专业模块进行交接。传递步骤2(适用原则)和步骤3(主导/支持分配)中的所有上下文信息。专业模块将按需加载自身的参考文档、手册与示例。对于多模块请求,调用主导模块——必要时它会升级至支持模块。
请勿将专业模块的正确性敏感区分压缩为仅路由名称。网关分流或交接必须:
  • 指定主导模块、所有存在的支持模块,以及每个相关的URL/框架/流归属方。
  • 传递影响正确性的准确状态、访问类型与生命周期事件名称。若代码包含生命周期处理器,同时指定或展示其绑定逻辑。
  • 聚焦最小化Rails响应/交付契约。仅当请求实际涉及后端设计时,才升级深入后端设计工作。
  • 自检依赖完成状态的可选行为:切勿仅提出焦点/光标/选区恢复的建议。对于框架重新渲染,传递适配实现的
    data-action="turbo:frame-render@document->focus-restore#restore"
    及目标框架防护。当响应结果重要时,使用匹配断言:
    event.detail.fetchResponse.statusCode === 422
    用于验证错误时的焦点恢复,仅在成功场景下使用
    event.detail.fetchResponse.succeeded
    。若未绑定相关逻辑与防护,请勿添加该行为;切勿设置固定延迟。
  • 为每个归属方的状态与失败路径分别设置验收检查。

Step 5: Escalate Out of Scope

步骤5:升级至超出范围的请求

SignalAction
Request requires backend architecture beyond the response contract needed by HotwireEscalate that architecture work; keep the Turbo response contract in scope
Request requires native platform APIs beyond bridge componentsRoute to
hotwire-native
Request is about deployment, CI, or infrastructureOutside this plugin's scope
Request is about non-Hotwire JavaScript frameworksOutside this plugin's scope
信号操作
请求需要Hotwire所需响应契约之外的后端架构升级该架构工作;保持Turbo响应契约在范围内
请求需要桥接组件之外的Native平台API转派至
hotwire-native
请求涉及部署、CI或基础设施超出本插件范围
请求涉及非Hotwire JavaScript框架超出本插件范围

Escalation Criteria

升级标准

This plugin covers the Hotwire frontend layer: Turbo Drive, Turbo Frames, Turbo Streams, Stimulus, view-layer patterns, and the minimal Rails response contracts those features require (matching frame markup, Turbo Stream responses, redirect/status semantics, and broadcast declarations). It does not cover:
  • Rails backend architecture beyond those response and delivery contracts
  • Database design or migrations
  • API design beyond Turbo Stream responses
  • Non-Hotwire JavaScript frameworks (React, Vue, etc.)
  • Infrastructure, deployment, or DevOps
本插件覆盖Hotwire前端层:Turbo Drive、Turbo Frames、Turbo Streams、Stimulus、视图层模式,以及这些功能所需的最小化Rails响应契约(匹配框架标记、Turbo Stream响应、重定向/状态语义与广播声明)。不包含以下内容:
  • 上述响应与交付契约之外的Rails后端架构
  • 数据库设计或迁移
  • Turbo Stream响应之外的API设计
  • 非Hotwire JavaScript框架(React、Vue等)
  • 基础设施、部署或DevOps