### Generate React Starter Project Source: https://github.com/spencerc99/playhtml/blob/main/templates/README.md Use this command to scaffold a new project with the React starter template. Install dependencies and start the development server. ```bash npx degit playhtml/playhtml/templates/react-starter my-project cd my-project bun install bun dev ``` -------------------------------- ### Start PartyKit Dev Server Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Starts the PartyKit development server for real-time synchronization. ```bash bun dev-server ``` -------------------------------- ### Start Extension Dev Server Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Starts the browser extension development server with WXT hot reload. ```bash bun dev-extension ``` -------------------------------- ### Start Local Development Server Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Starts the local development server, typically accessible at `localhost:4321`. This command is used for active development and previewing changes in real-time. ```bash bun dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Installs all necessary dependencies for your Astro + Starlight project. Run this after cloning the repository or creating a new project. ```bash bun install ``` -------------------------------- ### Install @playhtml/react Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/using-react.md Install the React package for PlayHTMLL. Compatible with React 16.8 and above. ```bash npm install @playhtml/react ``` -------------------------------- ### Run Local Smoke Tests Source: https://github.com/spencerc99/playhtml/blob/main/smoke-tests/README.md Execute the local smoke tests after building the site. This includes installing necessary browsers if it's a one-time setup. ```bash bun build-site bun run -C smoke-tests install-browsers # one-time bun smoke ``` -------------------------------- ### Install playhtml React Packages Source: https://github.com/spencerc99/playhtml/blob/main/README.md For React projects, install the necessary playhtml packages using npm. ```bash npm install @playhtml/react @playhtml/common ``` -------------------------------- ### Create Astro Project with Starlight Template Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Use this command to create a new Astro project pre-configured with the Starlight template. Ensure you have Bun installed. ```bash bun create astro@latest -- --template starlight ``` -------------------------------- ### Composed Grid Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/capabilities.mdx Demonstrates a composed grid of interactive cards, each linking to a live experiment. These examples showcase combinations of can-play, per-user awareness, and shared state. ```html
EXPERIMENT ยท 04 Every color A page where every visitor adds one color. can-play + per-user awareness + an ever-growing shared palette. COMMUNITY ยท FRIDGE Fridge poetry can-move + can-play + selector-id. Arrange magnets with strangers. Saves forever. EXPERIMENT ยท 05 Minute faces (together) 1,440 minutes in a day, one color per minute. Paint the clock with everyone who shows up that minute.
``` -------------------------------- ### Initialize PlayHTML with Basic Options Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/init-options.md Demonstrates the basic initialization of playhtml with a specified room and cursor settings. This is a common starting point for integrating playhtml into an application. ```javascript import { playhtml } from "playhtml"; playhtml.init({ room: "my-room", cursors: { enabled: true }, // โ€ฆ }); ``` -------------------------------- ### Vanilla HTML Setup for PlayHTMl Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/integrations/building-with-ai.md Configure custom properties and initialize PlayHTMl for vanilla HTML elements. Ensure all properties are set before calling playhtml.init(). ```javascript const element = document.getElementById("myElement"); element.defaultData = { /* ... */ }; element.onClick = (e, { data, setData }) => { /* ... */ }; element.updateElement = ({ data }) => { /* ... */ }; import { playhtml } from "https://unpkg.com/playhtml"; playhtml.init(); ``` -------------------------------- ### Vanilla HTML: Import + Manual Init (npm) Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/getting-started.mdx Install playhtml via npm and import it into your project when using a bundler. Ensure playhtml.init() runs after your interactive elements are in the DOM. ```bash npm install playhtml ``` ```javascript import { playhtml } from "playhtml"; playhtml.init({ cursors: { enabled: true } }); ``` -------------------------------- ### Install Claude Code Plugin for playhtml Source: https://github.com/spencerc99/playhtml/blob/main/README.md Install the playhtml plugin for Claude Code to enhance its ability to build playhtml elements. ```bash claude plugin marketplace add spencerc99/playhtml claude plugin install playhtml@playhtml ``` -------------------------------- ### Create a Changeset Source: https://github.com/spencerc99/playhtml/blob/main/CONTRIBUTING.md Run this command to create a changeset for your changes. It will guide you through selecting affected packages, choosing a version bump type, and providing a summary. ```bash bun run changeset ``` -------------------------------- ### Initialize PlayHTML in React Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/index.mdx This snippet demonstrates how to set up PlayHTML within a React application using the provided components. Ensure you have installed the necessary packages. ```tsx // npm install @playhtml/react @playhtml/common import { PlayProvider, CanToggleElement } from "@playhtml/react"; ``` -------------------------------- ### React: Setup for Duplicating Elements Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/capabilities.mdx React integration for 'can-duplicate' typically requires setupPlayElement for new clones to register correctly. Refer to 'Dynamic elements' for details. ```tsx // React wiring for can-duplicate typically pairs with setupPlayElement // so freshly-mounted clones register themselves. See "Dynamic elements". ``` -------------------------------- ### Initialize PlayHTML with Development Mode and Capabilities Source: https://github.com/spencerc99/playhtml/blob/main/website/test/shared-test-source.html Initializes PlayHTML with a specified host, enabling development mode and custom capabilities like 'can-post'. This setup is crucial for enabling features such as dynamic data updates and element registration. ```javascript import { playhtml } from "../../packages/playhtml/src"; console.log("๐ŸŽฏ Initializing PlayHTML..."); try { // Initialize playhtml with development mode and can-post capability await playhtml.init({ host: "localhost:1999", extraCapabilities: { "can-post": { defaultData: [], defaultLocalData: { addedEntries: new Set() }, updateElement: ({ data: entries, localData: { addedEntries }, setLocalData, }) => { const entriesToAdd = entries.filter( (entry) => !addedEntries.has(`${entry.name}-${entry.timestamp}`) ); const guestbookDiv = document.getElementById("guestbookMessages"); if (!guestbookDiv) return; entriesToAdd.forEach((entry) => { const newEntry = document.createElement("div"); newEntry.classList.add("guestbook-entry"); const entryDate = new Date(entry.timestamp); const time = entryDate.toTimeString().split(" ")[0]; const isToday = entryDate.toDateString() === new Date().toDateString(); const dateString = (() => { const now = new Date(); if ( now.getFullYear() !== entryDate.getFullYear() || now.getMonth() !== entryDate.getMonth() ) { return "Sometime before"; } else if (isToday) { return "Today"; } else if (now.getDate() - entryDate.getDate() === 1) { return "Yesterday"; } else if (now.getDate() - entryDate.getDate() < 7) { return "This week"; } else { return "Sometime before"; } })(); newEntry.innerHTML = `${dateString} at ${time} ${entry.name} ${entry.message}`; guestbookDiv.prepend(newEntry); addedEntries.add(`${entry.name}-${entry.timestamp}`); }); setLocalData({ addedEntries }); }, onMount: ({ getElement, getData, setData }) => { const element = getElement(); element.addEventListener("submit", (e) => { e.preventDefault(); e.stopImmediatePropagation(); const formData = new FormData(e.target); const inputData = Object.fromEntries(formData.entries()); if (!inputData.name || !inputData.message) { return false; } const timestamp = Date.now(); const newEntry = { name: inputData.name, message: inputData.message, timestamp, }; setData((d) => { d.push(newEntry); }); // Clear form element.querySelector('input[name="message" ]').value = ""; return false; }); }, }, }, }); // Update domain display const currentUrl = window.location.host + window.location.pathname; document.getElementById("current-domain").textContent = currentUrl; document.getElementById("current-domain-lamp").textContent = currentUrl; document.getElementById("current-domain-readonly").textContent = currentUrl; document.getElementById("current-domain-guestbook").textContent = currentUrl; console.log("๐ŸŽฏ Source page loaded - shared elements should be registered"); // Dynamic discovery test functionality const sourceLogContainer = document.getElementById("source-log"); function addSourceLog(message, type = "") { const entry = document.createElement("div"); entry.textContent = `${new Date().toLocaleTimeString()}: ${message}`; if (type) entry.style.color = type === "discovery" ? "#007acc" : "#dc3545"; sourceLogContainer.appendChild(entry); sourceLogContainer.scrollTop = sourceLogContainer.scrollHeight; } // Dynamic test for source page let dynamicSourceAdded = false; document .getElementById("add-dynamic-source-btn") .addEventListener("click", () => { if (dynamicSourceAdded) return; addSourceLog("Adding dynamic shared element (source)...", "discovery"); const dynamicDiv = document.createElement("div"); dynamicDiv.id = "dynamic-shared-source"; dynamicDiv.setAttribute("shared", ""); dynamicDiv.setAttribute("can-move", ""); dynamicDiv.className = "moveable-box"; dynamicDiv.innerHTML = `
๐Ÿ†• Dynamic Source
โœจ Added after init
`; document.getElementById("dynamic-source-container").innerHTML = ""; document .getElementById("dynamic-source-container") .appendChild(dynamicDiv); // This should register it as a new shared element playhtml.setupPlayElement(dynamicDiv); dynamicSourceAdded = true; document.getElementById("add-dynamic-source-btn").disabled = true; document.getElementById("remove-dynamic-source-btn").di }); } catch (e) { console.error("Error initializing PlayHTML:", e); } ``` -------------------------------- ### React Setup with PlayHTMl Provider Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/integrations/building-with-ai.md Wrap your React components with PlayProvider to enable PlayHTMl functionality. This is required for using PlayHTMl in React applications. ```javascript import { PlayProvider } from "@playhtml/react"; function App() { return ( ); } ``` -------------------------------- ### CanPlayElement Usage Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/react-api.md Demonstrates using CanPlayElement to manage shared state for a toggleable button, passing state and update functions via children. ```tsx {({ data, setData }) => ( )} ``` -------------------------------- ### Add Dynamic Shared Source Element Source: https://github.com/spencerc99/playhtml/blob/main/website/test/shared-test-source.html Adds a dynamic shared source element and calls its setup function. This is used for testing discovery-related functionalities. ```javascript document.getElementById("add-dynamic-source-btn").addEventListener("click", () => { document.getElementById("dynamic-source-container").innerHTML = "Dynamic element added"; dynamicSourceAdded = true; document.getElementById("add-dynamic-source-btn").disabled = true; document.getElementById("remove-dynamic-source-btn").disabled = false; addSourceLog( "Dynamic shared source element added and setup called", "discovery" ); }); ``` -------------------------------- ### Get Help with Astro CLI Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Displays help information for the Astro CLI, listing available commands and their options. Useful for understanding the full capabilities of the CLI. ```bash bun astro -- --help ``` -------------------------------- ### Vanilla HTML: Cloning Elements Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/capabilities.mdx Utilize 'can-duplicate' to clone elements. This example shows cloning a bunny image and includes a script to reset spawned clones. ```html ``` -------------------------------- ### Initialize Playhtml with Cursors Enabled (JavaScript) Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/cursors.md Enable cursor tracking by setting `cursors.enabled` to true during Playhtml initialization. This is the basic setup for JavaScript projects. ```javascript import { playhtml } from "playhtml"; playhtml.init({ cursors: { enabled: true, } }); ``` -------------------------------- ### Initialize PlayHTML and Track Cursors Source: https://github.com/spencerc99/playhtml/blob/main/website/test/cursor-test.html Initializes PlayHTML for cursor tracking and sets up event listeners for mouse movement and cursor updates. This is the primary setup for enabling collaborative cursor features. ```typescript import { playhtml } from "../packages/playhtml/src/index.ts"; const statusElement = document.getElementById("status"); const proximityElement = document.getElementById("proximity-info"); const cursorInfoElement = document.getElementById("cursor-info"); let proximityCount = 0; function updateStatus(message) { statusElement.textContent = message; } function updateCursorInfo() { if (window.cursors) { cursorInfoElement.innerHTML = ` Color: โ— ${window.cursors.color}
Name: ${window.cursors.name}
Active Users: ${window.cursors.count}
All Colors: ${window.cursors.allColors.length} `; } } // Track real cursor position window.lastMouseX = window.innerWidth / 2; window.lastMouseY = window.innerHeight / 2; document.addEventListener("mousemove", (e) => { window.lastMouseX = e.clientX; window.lastMouseY = e.clientY; }); // Initialize PlayHTML playhtml.init({ onCursorUpdate: updateCursorInfo, onProximity: addProximityEvent, onPlayerJoin: (player) => { updateStatus(`Player ${player.name} joined.`); updateCursorInfo(); }, onPlayerLeave: (player) => { updateStatus(`Player ${player.name} left.`); updateCursorInfo(); }, }); updateStatus("Initializing cursor tracking..."); updateCursorInfo(); ``` -------------------------------- ### Generate HTML Starter Project Source: https://github.com/spencerc99/playhtml/blob/main/templates/README.md Use this command to scaffold a new project with the HTML starter template. Then, open the generated index.html file in your browser. ```bash npx degit playhtml/playhtml/templates/html-starter my-project open my-project/index.html ``` -------------------------------- ### playhtml.init() with Options Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/init-options.md Demonstrates how to initialize playhtml with various configuration options, such as specifying a room, enabling cursors, and defining event listeners. ```APIDOC ## playhtml.init() ### Description Initializes the playhtml library with a set of configuration options. These options control aspects like room connection, cursor display, event handling, custom capabilities, and development mode. ### Method `playhtml.init(initOptions: InitOptions)` ### Parameters #### `initOptions` Object - **`room`** (string) - Optional - The room to connect users to. If not provided, it defaults to the current URL's pathname and search. It's automatically prefixed with `window.location.hostname`. - **`cursors`** (object) - Optional - Configuration for cursor display. Example: `{ enabled: true }`. - **`host`** (string) - Optional - The public PartyKit host. Use this to self-host the syncing server. - **`events`** (Record) - Optional - An object where keys are event names and values are `PlayEvent` objects, used to declare event listeners inline at init time. - **`extraCapabilities`** (Record) - Optional - An object for shipping custom capabilities alongside built-ins. Keys are capability names (e.g., `"can-pulse"`), and values are `ElementInitializer` objects. - **`defaultRoomOptions`** (DefaultRoomOptions) - Optional - Configuration for the auto-derived URL-based room. - **`onError`** (() => void) - Optional - A callback function executed upon connection failures. - **`developmentMode`** (boolean) - Optional - Enables an in-page devtools panel for debugging. Defaults to `false`. Recommended for development builds only. ### Request Example ```js import { playhtml } from "playhtml"; playhtml.init({ room: "my-room", cursors: { enabled: true }, events: { confetti: { type: "confetti", onEvent: () => window.confetti({ particleCount: 100 }), }, }, extraCapabilities: { "can-pulse": { defaultData: { on: false }, updateElement: ({ element, data }) => { element.classList.toggle("pulsing", data.on); }, onClick: (_e, { data, setData }) => setData({ on: !data.on }), }, }, onError: () => { document.body.classList.add("playhtml-offline"); console.warn("playhtml could not connect"); }, developmentMode: true, }); ``` ### Response This method does not return a value. It initializes the playhtml instance. ``` -------------------------------- ### React Integration for Transformed Canvas Cursors Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/cursors.md Example of initializing PlayHTMLL cursors within a React application, specifying a container element for anchoring. This setup is useful for pages with dynamic pan and zoom functionality applied via React state. ```tsx
{/* pan/zoom transform applied here via React state */} {words.map(w => )}
``` -------------------------------- ### Build Website for Production Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Builds the playhtml website for production deployment. ```bash bun build-site ``` -------------------------------- ### Build Production Site Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Builds the production-ready version of your website, outputting the static files to the `./dist/` directory. This is the command to run before deployment. ```bash bun build ``` -------------------------------- ### Deploy PartyKit to Production Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Deploys the PartyKit real-time sync server to the production environment. ```bash bun deploy-server ``` -------------------------------- ### Acceptable Nested Data Shape Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/data-essentials.md An example of an acceptable one-level nesting for `defaultData` where fields are clearly related. Deeper nesting should generally be avoided. ```javascript defaultData: { position: { x: 0, y: 0 }, color: "#ff0000" } ``` -------------------------------- ### Vanilla HTML: Import + Manual Init (CDN) Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/getting-started.mdx This path is suitable when you need to pass options to playhtml.init() or are using a bundler. For CDN usage without a bundler, place the script at the end of the body. ```html ``` -------------------------------- ### Flat Data Shape Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/data-essentials.md Example of a good, flat data shape for `defaultData`. Keeping shapes flat improves performance, reduces sync bandwidth, and makes refactoring easier. ```javascript defaultData: { x: 0, y: 0, color: "#ff0000", size: 100 } ``` -------------------------------- ### Avoid Deeply Nested Data Shape Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/data-essentials.md An example of a data shape to avoid in `defaultData` due to deep nesting. Deeply nested objects are harder to update, slower to sync, and more prone to conflicts. ```javascript defaultData: { position: { coords: { x: 0, y: 0 } }, style: { appearance: { color: "#ff0000" } }, } ``` -------------------------------- ### Getting Own Identity Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/index.mdx Retrieve the identity information for the current local user. ```js // Your own identity const me = playhtml.presence.getMyIdentity(); ``` -------------------------------- ### Props-Dependent withSharedState Config Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/react-api.md Example of using a callback for the config in withSharedState when defaultData depends on component props. ```tsx export const Reaction = withSharedState( ({ reaction: { count } }) => ({ defaultData: { count } }), ({ data, setData }, props) => /* โ€ฆ */, ); ``` -------------------------------- ### Project Structure Overview Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md This is a typical project structure for an Astro + Starlight site. Markdown and MDX files for documentation should be placed in `src/content/docs/`. ```bash .\nโ”œโ”€โ”€ public/\nโ”œโ”€โ”€ src/\nโ”‚ โ”œโ”€โ”€ assets/\nโ”‚ โ”œโ”€โ”€ content/\nโ”‚ โ”‚ โ””โ”€โ”€ docs/\nโ”‚ โ””โ”€โ”€ content.config.ts\nโ”œโ”€โ”€ astro.config.mjs\nโ”œโ”€โ”€ package.json\nโ””โ”€โ”€ tsconfig.json ``` -------------------------------- ### Clearing Custom Presence Channel Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/index.mdx Example of clearing a custom 'status' channel by setting its value to null. ```js // Clear: null playhtml.presence.setMyPresence("status", null); ``` -------------------------------- ### Deploy PartyKit to Staging Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Deploys the PartyKit real-time sync server to the staging environment. ```bash bun deploy-server:staging ``` -------------------------------- ### Setting Custom Presence Channel Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/index.mdx Example of setting a custom 'status' channel to indicate a user is typing. ```js // Set: replace semantics per channel playhtml.presence.setMyPresence("status", { text: "typing" }); ``` -------------------------------- ### Get and Subscribe to Cursor Presences Source: https://github.com/spencerc99/playhtml/blob/main/packages/common/CHANGELOG.md Retrieve all cursor presences and subscribe to changes. The presences are keyed by a stable ID. ```typescript const presences = playhtml.cursorClient.getCursorPresences(); const unsubscribe = playhtml.cursorClient.onCursorPresencesChange( (presences) => { // presences is Map }, ); const identity = playhtml.cursorClient.getMyPlayerIdentity(); const stableId = identity.publicKey; // Persists across sessions ``` -------------------------------- ### Initialize PlayProvider in App Source: https://github.com/spencerc99/playhtml/blob/main/packages/react/README.md Wrap your application with the PlayProvider component to initialize the playhtml client and set up the server connection. You can optionally provide initOptions for room and host configuration. ```tsx import { PlayProvider } from "@playhtml/react"; export default function App() { return ( {/* rest of your app... */} ); } ``` -------------------------------- ### Updating PlayHTMl Data Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/integrations/building-with-ai.md Examples of updating data in PlayHTMl, including simple updates and array modifications using draft.js. ```javascript - Simple: setData({ count: data.count + 1 }) - Arrays: setData((draft) => { draft.items.push(item) }) - LIMITATIONS: In mutator form, use splice() not shift()/pop()/[i]=value ``` -------------------------------- ### Preview Production Build Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/README.md Locally previews the production build of your site before deploying. This helps ensure that the deployed version will function as expected. ```bash bun preview ``` -------------------------------- ### Editable Content with Children Source: https://github.com/spencerc99/playhtml/blob/main/website/test/playground.html Indicates a section of content that is editable and can contain child elements. This setup is typically managed by a framework or library. ```html CONTENT EDITABLE WITH CHILDREN ``` -------------------------------- ### Initialize PlayHTML with Event Handlers Source: https://github.com/spencerc99/playhtml/blob/main/website/test/shared-test-source.html Initializes PlayHTML and sets up event handlers for dynamic discovery tests. Includes error handling for initialization failures. ```javascript addSourceLog( "Dynamic discovery test handlers initialized", "discovery" ); } catch (error) { console.error("๐ŸŽฏ Failed to initialize PlayHTML:", error); } ``` -------------------------------- ### Interactive Content Editable Source: https://github.com/spencerc99/playhtml/blob/main/website/test/playground.html Placeholder for content that can be edited directly. This example does not include specific JavaScript for interaction but indicates the element's capability. ```html CONTENT EDITABLE ``` -------------------------------- ### Playhtml Initialization (New Method) Source: https://github.com/spencerc99/playhtml/blob/main/packages/playhtml/CHANGELOG.md This snippet demonstrates the new explicit `playhtml.init()` call required for Playhtml versions 2.0.0 and above. It also shows how to optionally specify a room and host. ```html ``` -------------------------------- ### Initialize PlayHTML with a Custom Host Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/init-options.md Specifies a custom PartyKit host for self-hosting the syncing server. This is recommended for enhanced control, custom server-side logic, or to meet data-residency requirements. ```javascript playhtml.init({ host: "mypartykit.user.partykit.dev", }); ``` -------------------------------- ### Use playhtml in React Application Source: https://github.com/spencerc99/playhtml/blob/main/README.md Integrate playhtml into your React application using the PlayProvider and CanToggleElement components. This example shows how to make an image toggleable. ```tsx import { PlayProvider, CanToggleElement } from "@playhtml/react"; ``` -------------------------------- ### Get My Player Identity Source: https://github.com/spencerc99/playhtml/blob/main/packages/react/CHANGELOG.md Obtain the stable player identity, which includes a public key that persists across sessions. This is useful for correlating user data. ```typescript const identity = playhtml.cursorClient.getMyPlayerIdentity(); const stableId = identity.publicKey; // Persists across sessions ``` -------------------------------- ### Vanilla HTML Cursor Configuration Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/integrations/building-with-ai.md Enable and configure cursors for real-time collaboration in vanilla HTML using playhtml.init(). ```javascript playhtml.init({ cursors: { enabled: true, room: "page" } }) ``` -------------------------------- ### Build Core Library Package Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Builds the core playhtml library package. ```bash bun run -C packages/playhtml build ``` -------------------------------- ### Vanilla HTML: Drop-in Script Initialization Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/getting-started.mdx Use this method for the fastest integration without needing a build step or module syntax. Add the script tag at the end of your body to ensure interactive elements are present when playhtml initializes. ```html ``` -------------------------------- ### Initialize playhtml with Vanilla HTML Source: https://github.com/spencerc99/playhtml/blob/main/README.md To use playhtml in a vanilla HTML project, include the script from a CDN and initialize playhtml. This enables features like 'can-toggle' on elements. ```html ``` -------------------------------- ### Build All Library Packages Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Builds all library packages within the monorepo. ```bash bun build-packages ``` -------------------------------- ### React can-move Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/capabilities.mdx Implements the `can-move` capability in React using the `CanMoveElement` component. It allows for draggable elements within defined boundaries, syncing their positions. ```tsx import { CanMoveElement } from "@playhtml/react";
``` -------------------------------- ### Playhtml Initialization (Old Method) Source: https://github.com/spencerc99/playhtml/blob/main/packages/playhtml/CHANGELOG.md This snippet shows the previous method of initializing Playhtml via a direct script import. Use this if you need to pin to a version 1.3.1 or earlier. ```html ``` -------------------------------- ### Build React Bindings Package Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Builds the React wrapper components package for playhtml. ```bash bun run -C packages/react build ``` -------------------------------- ### Filter Visible Cursors with `shouldRenderCursor` Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/data/presence/cursors.md Use the `shouldRenderCursor` function to control which cursors are displayed. This example renders only cursors from the same page, even when `room` is set to 'domain'. ```javascript cursors: { enabled: true, room: "domain", // Connect everyone shouldRenderCursor: (presence) => { // Only render cursors from the same page return presence.page === window.location.pathname; } } ``` -------------------------------- ### React PlayProvider Initialization with Cursors Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/reference/init-options.md Demonstrates how to initialize PlayHTML with cursor options within a React application using the PlayProvider component. ```tsx import { PlayProvider } from "@playhtml/react"; {/* your app */} ; ``` -------------------------------- ### Build Browser Extension Source: https://github.com/spencerc99/playhtml/blob/main/CLAUDE.md Builds the browser extension for Chrome. ```bash bun build-extension ``` -------------------------------- ### Vanilla HTML can-move Example Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/src/content/docs/capabilities.mdx Demonstrates the `can-move` attribute for creating draggable elements within specified bounds. The `can-move-bounds` attribute defines the container for the draggable items. ```html
``` -------------------------------- ### Initialize PlayHTML with Cursors Source: https://github.com/spencerc99/playhtml/blob/main/claude-plugin/skills/building-playhtml-elements/SKILL.md Enable and configure cursor synchronization for real-time presence indication. Specify the room scope ('page', 'domain', or 'section') for cursor data. ```javascript playhtml.init({ cursors: { enabled: true, room: "page" } }); // "page"|"domain"|"section" window.cursors.allColors.length; // user count ``` -------------------------------- ### Recipe Folder Structure Source: https://github.com/spencerc99/playhtml/blob/main/apps/docs/plans/live-editor.md Illustrates the expected file structure for a single recipe within the project. Includes frontmatter, HTML entry, and optional React component. ```tree recipes/ toggle-basic/ recipe.md # frontmatter + narrative body (MDX optional) index.html # vanilla entry (required for MVP) component.tsx # React entry (optional, future) preview.png # static preview (optional; auto-generated fallback) ```