AgentSkillsCN

bubble-components-pubsub

全面的Bubble技能,适用于组件/页面的创作、Props与Emits的绑定、Router的使用,以及Pub/Sub主题生命周期模式的实现。请务必为以.bub.js或.bubble.js结尾的文件启用此技能。适用于前端的Bubble任务;若仅涉及后端改动,则可跳过此步骤。

SKILL.md
--- frontmatter
name: bubble-components-pubsub
description: Comprehensive Bubble skill for component/page authoring, props-emits wiring, router usage, and pub-sub topic lifecycle patterns. Always apply for files ending in .bub.js or .bubble.js. Use for frontend Bubble tasks; skip for backend-only changes.
license: MIT
metadata:
  author: card-room
  tags: bubble, components, props, emits, pubsub, router, sfc

Bubble Components + PubSub

Canonical Bubble patterns for this repository, with GitHub-first references and local integration rules.

Overview

This skill is optimized for two recurring task families:

  • Building or refactoring Bubble SFC-style components/pages.
  • Wiring app events via Bubble pub-sub (bubble.events.topic(...)) with stable lifecycle handling.

Use this skill to avoid regressions around props behavior and topic listener leaks.

Skill Format

This skill uses progressive disclosure:

  • SKILL.md = routing and decision layer.
  • references/*.md = deep implementation guides.
  • scripts/*.sh = optional audits you can run quickly.

When To Apply

Apply when the request involves any of:

  • New Bubble component/page creation.
  • Child component registration with props/emits.
  • Fixing old this.props.foo.value usage.
  • Adding or refactoring game/session event listeners.
  • Bubble router setup or route updates.

Automatic trigger rules:

  • Always activate this skill when the task touches files ending with .bub.js.
  • Always activate this skill when the task touches files ending with .bubble.js.

Do not apply when:

  • Task is server-only (Express/TS/socket backend without Bubble UI integration).
  • Task is unrelated to Bubble runtime behavior.

Sources (GitHub first)

Primary source of truth:

  • Repo root: https://github.com/antocorr/bubble/
  • Framework source: https://github.com/antocorr/bubble/tree/main/src
  • Examples: https://github.com/antocorr/bubble/tree/main/examples
  • Prompt baseline: https://github.com/antocorr/bubble/blob/main/ai-component-creation-prompt.md

Priority Map

PriorityAreaRiskReference
1Props model correctnessHighreferences/props-emits.md
2Pub-sub listener lifecycleHighreferences/pubsub-lifecycle.md
3Component authoring conventionsMediumreferences/components-core.md
4Router wiring and route dataMediumreferences/router-patterns.md
5Legacy migration checksMediumreferences/migration-checks.md

Default Rules

  1. Component shape
  • Export plain object with name, template(), data(), methods.
  • template() returns one root element.
  • Add /* html */ above template literals.
  • Caveat: do not use x-if on the root element of custom Bubble components.
  • Caveat 2: WORK IN PROGRESS but as of today you can either use class="" or :class="" Use x-show on root, or apply x-if in the parent around the component tag.
  1. Reactive state
  • Read/write component state with this._data.key.value.
  • Arrays/objects in signal values can be mutated through .value proxy.
  1. Props behavior (critical)
  • In component JS: this.props.foo is raw value.
  • Never use this.props.foo.value.
  • In templates: props are available by key ({{ foo }}), not {{ props.foo }}.
  1. Emits contract
  • Child declares emits: ["eventName"].
  • Child emits with this.emit("eventName", payload).
  • Parent listens with @eventName="handler".
  1. Pub-sub contract
  • Use bubble.events.topic("name"), not bubble.topic("name").
  • Keep stable handler refs on this and .off previous before .on in init().
  1. Attribute bindings (critical)
  • attr="{{signal}}" does NOT work for reactive attribute binding. Mustache interpolation is for text content only.
  • Always use :attr="expression" to bind a reactive value to an HTML attribute.
  • Correct: :src="imageUrl", :disabled="isLoading", :class="activeClass".
  • Wrong: src="{{imageUrl}}", disabled="{{isLoading}}".
  • {{ }} interpolation remains valid inside text nodes (e.g. <p>{{ count }}</p>).

Rapid Workflow

  1. Classify task: component | props/emits | pubsub | router | migration.
  2. Open relevant reference file(s) below.
  3. Apply minimal scoped changes aligned with existing style.
  4. Run script audit (optional): bash .agents/skills/bubble-components-pubsub/scripts/audit-bubble-patterns.sh.
  5. If touching docs/prompts/examples, keep props guidance aligned with runtime.

References

  • Core authoring: references/components-core.md
  • Props and emits: references/props-emits.md
  • Pub-sub lifecycle: references/pubsub-lifecycle.md
  • Router patterns: references/router-patterns.md
  • Migration checks: references/migration-checks.md
  • Source map (GitHub/local): references/source-map.md

Problem -> Reference Mapping

ProblemStart with
Child prop does not update / wrong value shapereferences/props-emits.md
Event handlers duplicate after re-initreferences/pubsub-lifecycle.md
New page/component scaffold neededreferences/components-core.md
Route data/props not reaching componentreferences/router-patterns.md
Legacy code still using old patternsreferences/migration-checks.md

Quality Gate

Before finalizing Bubble-related edits:

  • No this.props.*.value remains.
  • No attr="{{signal}}" patterns in HTML attributes; use :attr="expression" instead.
  • No mixed topic APIs (bubble.topic vs bubble.events.topic) in touched files.
  • Event listeners are attached with stable handler refs and detached before re-attach.
  • Templates keep one root and use directives idiomatically.