### Run Getting Started Example Source: https://github.com/shopify/remote-dom/blob/main/examples/getting-started/README.md This command executes the 'getting-started' example using pnpm, filtering for the specific example package within the repository. ```bash pnpm --filter example-getting-started start ``` -------------------------------- ### Run Custom Element Example Source: https://github.com/shopify/remote-dom/blob/main/examples/custom-element/README.md Command to start the custom element example using pnpm. This command filters for the 'example-custom-element' package and executes its start script. ```bash pnpm --filter example-custom-element start ``` -------------------------------- ### Run Kitchen Sink Example Source: https://github.com/shopify/remote-dom/blob/main/examples/kitchen-sink/README.md Command to start the kitchen sink example from the repository root using pnpm. ```bash pnpm --filter example-kitchen-sink start ``` -------------------------------- ### Initialize and Connect DOMRemoteReceiver Source: https://github.com/shopify/remote-dom/blob/main/examples/getting-started/app/index.html This snippet demonstrates how to initialize a `DOMRemoteReceiver` and connect it to a root element in the host environment. It also sets up an event listener to receive messages from an iframe and propagate mutations to the receiver. ```javascript import {DOMRemoteReceiver} from '@remote-dom/core/receivers'; const root = document.querySelector('#root'); const iframe = document.querySelector('#remote-iframe'); // A `DOMRemoteReceiver` will automatically synchronize changes // from the remote environment to the host environment as native // HTML elements. We connect it to the `root` element so that it // will insert any content from the remote environment there. const receiver = new DOMRemoteReceiver(); receiver.connect(root); window.addEventListener('message', ({source, data}) => { // Ensure the message is coming from our iframe if (source !== iframe.contentWindow) return; // Communicate the mutation to the `DOMRemoteReceiver` receiver.connection.mutate(data); }); ``` -------------------------------- ### Installation Source: https://github.com/shopify/remote-dom/blob/main/packages/signals/README.md Instructions for installing the @remote-dom/signals library using npm, pnpm, and yarn. ```sh npm install @remote-dom/signals --save pnpm install @remote-dom/signals --save yarn add @remote-dom/signals ``` -------------------------------- ### Install @remote-dom/core Source: https://github.com/shopify/remote-dom/blob/main/packages/core/README.md Provides installation instructions for the @remote-dom/core package using different package managers like npm, pnpm, and yarn. ```sh npm install @remote-dom/core --save # npm pnpm install @remote-dom/core --save # pnpm yarn add @remote-dom/core # yarn ``` -------------------------------- ### Basic Remote DOM Synchronization Source: https://github.com/shopify/remote-dom/blob/main/examples/getting-started/app/remote.html This snippet demonstrates the basic usage of Remote DOM. It synchronizes changes in a specified DOM element to the host environment using `setInterval` for updates and `RemoteMutationObserver` to capture and post mutations. ```javascript import {RemoteMutationObserver} from '@remote-dom/core/elements'; // We will synchronize changes in this element to the host environment. const root = document.querySelector('#root'); let count = 0; // Update text every second, to demonstrate that Remote DOM can handle // both initial HTML and updates that happen later. setInterval(() => { count += 1; render(); }, 1000); render(); function render() { root.textContent = `Rendered ${count} ${count === 1 ? 'second' : 'seconds'} ago`; } // Create a special `MutationObserver` that will map changes // in the HTML to Remote DOM-compatible mutations. const observer = new RemoteMutationObserver({ mutate(mutations) { window.parent.postMessage(mutations, '*'); }, }); observer.observe(root); ``` -------------------------------- ### Install @remote-dom/polyfill Source: https://github.com/shopify/remote-dom/blob/main/packages/polyfill/README.md Provides installation commands for the @remote-dom/polyfill package using npm, pnpm, and yarn. ```sh npm install @remote-dom/polyfill --save # npm pnpm install @remote-dom/polyfill --save # pnpm yarn add @remote-dom/polyfill # yarn ``` -------------------------------- ### Install @remote-dom/preact Source: https://github.com/shopify/remote-dom/blob/main/packages/preact/README.md Installs the necessary @remote-dom/core and @remote-dom/preact packages using npm, pnpm, or yarn. ```sh npm install @remote-dom/core @remote-dom/preact --save # npm pnpm install @remote-dom/core @remote-dom/preact --save # pnpm yarn add @remote-dom/core @remote-dom/preact # yarn ``` -------------------------------- ### Creating a RemoteReceiver Source: https://github.com/shopify/remote-dom/blob/main/packages/core/README.md Demonstrates how to create an empty RemoteReceiver instance using its constructor. This is the basic setup for using the RemoteReceiver. ```ts import {RemoteReceiver} from '@remote-dom/core/receivers'; const receiver = new RemoteReceiver(); ``` -------------------------------- ### Install @remote-dom/core Source: https://github.com/shopify/remote-dom/blob/main/README.md Installs the core library for Remote DOM functionality using yarn. ```bash yarn add @remote-dom/core ``` -------------------------------- ### Installation Source: https://github.com/shopify/remote-dom/blob/main/packages/react/README.md Installs the necessary @remote-dom packages for core functionality and React integration using npm, pnpm, or yarn. ```sh npm install @remote-dom/core @remote-dom/react --save # npm pnpm install @remote-dom/core @remote-dom/react --save # pnpm yarn add @remote-dom/core @remote-dom/react # yarn ``` -------------------------------- ### Install @remote-dom/core Source: https://github.com/shopify/remote-dom/blob/main/README.md Installs the core package for Remote DOM, which is necessary for establishing connections between host and remote environments. This package is essential for any project utilizing Remote DOM. ```bash # npm npm install @remote-dom/core --save # pnpm pnpm install @remote-dom/core --save ``` -------------------------------- ### Development Commands Source: https://github.com/shopify/remote-dom/blob/main/CONTRIBUTING.md Commands for setting up and running development tasks in the Remote DOM project, including installation, type checking, linting, testing, and building. ```bash pnpm install pnpm type-check pnpm lint pnpm test pnpm build ``` -------------------------------- ### Shopify Remote DOM Kitchen Sink Source: https://github.com/shopify/remote-dom/blob/main/examples/kitchen-sink/app/index.html A collection of examples showcasing the capabilities of the Shopify Remote DOM library. This includes various DOM manipulation techniques and remote rendering scenarios. ```javascript // Example 1: Basic DOM update remoteDOM.update( '#my-element', '

Hello, Remote DOM!

' ); // Example 2: Adding an event listener remotely remoteDOM.addEvent( '#my-button', 'click', () => { alert('Button clicked!'); } ); // Example 3: Rendering a component remotely remoteDOM.renderComponent( '#app-container', 'MyAwesomeComponent', { message: 'Welcome!' } ); // Example 4: Handling remote events remoteDOM.on('custom-event', (data) => { console.log('Received custom event:', data); }); // Example 5: Removing an element remotely remoteDOM.remove('#element-to-remove'); // Example 6: Replacing an element remotely remoteDOM.replace( '#old-element', '

This is the new content.

' ); // Example 7: Getting element attributes remotely const attributeValue = await remoteDOM.getAttribute('#my-element', 'data-id'); console.log('Attribute value:', attributeValue); // Example 8: Setting element attributes remotely remoteDOM.setAttribute('#my-element', 'data-status', 'active'); // Example 9: Traversing the DOM remotely const children = await remoteDOM.children('#parent-element'); console.log('Children:', children); // Example 10: Checking if an element exists remotely const exists = await remoteDOM.exists('#some-element'); console.log('Element exists:', exists); ``` -------------------------------- ### Remote Content Rendering Example Source: https://github.com/shopify/remote-dom/blob/main/README.md Demonstrates how to render dynamic content within the remote environment's root element using JavaScript. This content will be synchronized to the host page via the RemoteMutationObserver. ```html
``` -------------------------------- ### RemoteRootRenderer Setup with Preact Source: https://github.com/shopify/remote-dom/blob/main/packages/preact/README.md Shows how to set up the `RemoteRootRenderer` to render a tree of remote elements using Preact. It includes initializing a `SignalRemoteReceiver` and mapping remote elements to Preact components. ```javascript // If you don’t already have this import somewhere in your project, you need // to add it — this import adds the Preact hooks that auto-subscribe components // to signals. import '@preact/signals'; import {render} from 'preact'; import { createRemoteComponentRenderer, RemoteRootRenderer, SignalRemoteReceiver, } from '@remote-dom/preact/host'; // Create wrapper elements to render our actual UI components in response // to remote elements. See the `createRemoteComponentRenderer()` section above. const Card = createRemoteComponentRenderer(UICard); const receiver = new SignalRemoteReceiver(); // TODO: send the `receiver.connection` object to the remote environment, // so it can send us updates about the tree of remote elements. render( , document.querySelector('#root'), ); ``` -------------------------------- ### HTML Structure for Remote DOM Example Source: https://github.com/shopify/remote-dom/blob/main/README.md Basic HTML structure including a root element for Remote DOM rendering and an iframe for the remote content. ```html
``` -------------------------------- ### Customizing DOM Operations with Hooks Source: https://github.com/shopify/remote-dom/blob/main/packages/polyfill/README.md Shows how to customize DOM operations by overwriting properties on the `hooks` export from the @remote-dom/polyfill library. This example logs the creation of elements to the console. ```ts import {hooks} from '@remote-dom/polyfill'; hooks.createElement = (element) => { console.log('Creating element:', element); }; ``` -------------------------------- ### Host Setup: Integrating Iframe and Receiver Source: https://github.com/shopify/remote-dom/blob/main/README.md Integrates a hidden iframe as the remote environment and sets up a message listener on the host to forward mutations from the iframe to the DOMRemoteReceiver. This enables real-time DOM synchronization. ```html
``` -------------------------------- ### Host Setup: DOMRemoteReceiver Source: https://github.com/shopify/remote-dom/blob/main/README.md Sets up the DOMRemoteReceiver on the host page to receive and render DOM updates from a remote environment. It connects the receiver to a specified root element. ```html
``` -------------------------------- ### Update package dependencies for @remote-dom/react Source: https://github.com/shopify/remote-dom/blob/main/documentation/migrations/remote-ui-to-remote-dom.md Shows the necessary changes to `package.json` to uninstall `@remote-ui/react` and install `@remote-dom/react`, along with related React dependencies. ```diff { "dependencies": { - "@remote-ui/react": "^5.0.0", + "@remote-dom/react": "^1.0.0", } } { "dependencies": { "@remote-dom/react": "^1.0.0", "react": "^18.2.0", + "react-dom": "^18.2.0", - "react-reconciler": "*", } } ``` -------------------------------- ### Remote Setup: RemoteMutationObserver Source: https://github.com/shopify/remote-dom/blob/main/README.md Configures the RemoteMutationObserver in the remote environment (e.g., an iframe) to monitor changes within a specified root element and send these mutations to the parent window via `postMessage`. ```html
``` -------------------------------- ### Remote DOM Setup with UIButton Source: https://github.com/shopify/remote-dom/blob/main/examples/custom-element/app/index.html Initializes the Remote DOM receiver to only allow 'ui-button' elements and connects it to a root element. It then establishes a thread connection to an iframe to render the remote DOM tree, enabling communication for events like 'click'. ```javascript import {DOMRemoteReceiver} from '@remote-dom/core/receivers'; import {ThreadIframe} from '@quilted/threads'; const root = document.querySelector('#root'); const iframe = document.querySelector('#remote-iframe'); const receiver = new DOMRemoteReceiver({ elements: ['ui-button'], }); receiver.connect(root); const thread = new ThreadIframe(iframe); thread.imports.render(receiver.connection); ``` -------------------------------- ### Synchronize DOM Changes with RemoteMutationObserver Source: https://github.com/shopify/remote-dom/blob/main/examples/custom-element/app/remote.html Utilizes RemoteMutationObserver to synchronize DOM changes within a specified root element. This observer is configured to work with a RemoteConnection, enabling real-time updates to be sent to a host environment. ```javascript import {RemoteMutationObserver} from '@remote-dom/core/elements'; import {ThreadNestedIframe} from '@quilted/threads'; const root = document.querySelector('#root'); new ThreadNestedIframe({ exports: { async render(connection) { const observer = new RemoteMutationObserver(connection); observer.observe(root); }, }, }); ``` -------------------------------- ### Handle Button Click Events Source: https://github.com/shopify/remote-dom/blob/main/examples/custom-element/app/remote.html Adds an event listener to a 'ui-button' element to increment a counter, update the button's text content, and remove the 'primary' attribute after 5 clicks. This demonstrates dynamic UI updates based on user interaction. ```javascript let count = 0; const button = document.querySelector('ui-button'); button.addEventListener('click', () => { count += 1; button.textContent = `Clicked ${count} ${ count === 1 ? 'time' : 'times'}`; if (count === 5) { button.removeAttribute('primary'); } }); ``` -------------------------------- ### Deprecated Event Listener Synchronization Source: https://github.com/shopify/remote-dom/blob/main/packages/core/README.md Provides an example of the deprecated `event: true` configuration for remote properties, which was used to synchronize event listeners. It highlights the usage pattern but notes its deprecation in favor of `remoteEvents`. ```ts import {RemoteElement} from '@remote-dom/core/elements'; class MyElement extends RemoteElement { static get remoteProperties() { return { onPress: {event: true}, }; } } ``` -------------------------------- ### Update Remote Code with DOM Elements Source: https://github.com/shopify/remote-dom/blob/main/documentation/migrations/remote-ui-to-remote-dom.md Illustrates the shift from using `createRemoteRoot()` in remote-ui to native DOM APIs for managing remote elements. This example shows creating and appending a custom `ui-button` element to a `remote-root` element. ```javascript // Replace this: import {createRemoteRoot} from '@remote-ui/core'; export function receiveChannelFromHostEnvironment(channel) { const root = createRemoteRoot(channel); const button = root.createComponent( 'Button', { primary: true, onPress: () => console.log('Pressed!'), }, ['Press me!'], ); root.appendChild(button); } // With this: import {RemoteRootElement} from '@remote-dom/core/elements'; // Define our `Button` custom element, from earlier. customElements.define('ui-button', Button); // If you’re using an `