Borrow an element from another page
The logo stamp on the playhtml.fun homepage is a shared element. This page shows the same stamp. Spin it here and it spins on the homepage too, for everyone.
Test it with another person
- Keep this page open in your normal window.
- Copy the private-window link, then paste it into a private or incognito window.
- Interact in either window and watch the other one update.
Copy the code
Both versions use the same shared data and behavior. The live playground runs the Vanilla HTML version.
Save this as index.html, or open it in the playground to
test and change it.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Borrow an element from another page</title>
<style>
:root {
color: #1c1c1c;
background: #f4efe5;
font-family: ui-sans-serif, system-ui, sans-serif;
}
* { box-sizing: border-box; }
body { display: grid; min-height: 100vh; margin: 0; padding: 1.5rem; place-items: center; }
main {
display: grid;
gap: 0.75rem;
justify-items: center;
text-align: center;
}
.stamp { width: 120px; cursor: grab; }
p { margin: 0; max-width: 18rem; font-size: 0.85rem; line-height: 1.5; }
</style>
</head>
<body>
<main id="stamp-demo">
<!-- The source stamp lives on the playhtml.fun homepage with `shared`.
This copy reads and writes the same rotation. -->
<img
class="stamp"
src="https://playhtml.fun/playhtml-logo.png"
alt="The playhtml logo stamp"
data-source="playhtml.fun#stamp"
can-spin
/>
<p>Drag to spin it. It's the same stamp as on the playhtml.fun homepage.</p>
</main>
<script type="module">
import { playhtml } from "https://unpkg.com/playhtml@latest";
await playhtml.init({ developmentMode: true });
</script>
</body>
</html>
Start with a React + TypeScript project, install the packages below,
then replace src/App.tsx with the component.
npm install playhtml @playhtml/react import { CanSpinElement, PlayProvider } from "@playhtml/react";
// The source stamp lives on the playhtml.fun homepage with `shared`. This
// copy reads and writes the same rotation.
function SharedStamp() {
return (
<>
<CanSpinElement dataSource="playhtml.fun#stamp">
<img className="stamp" src="https://playhtml.fun/playhtml-logo.png" alt="The playhtml logo stamp" />
</CanSpinElement>
<p>Drag to spin it. It's the same stamp as on the playhtml.fun homepage.</p>
</>
);
}
export default function App() {
return (
<PlayProvider initOptions={{ developmentMode: true }}>
<main>
<SharedStamp />
</main>
<style>{`
:root { color: #1c1c1c; background: #f4efe5; font-family: system-ui, sans-serif; }
* { box-sizing: border-box; }
body { margin: 0; }
#root { display: grid; min-height: 100vh; padding: 1.5rem; place-items: center; }
main {
display: grid;
gap: 0.75rem;
justify-items: center;
text-align: center;
}
.stamp { width: 120px; cursor: grab; }
p { margin: 0; max-width: 18rem; font-size: 0.85rem; line-height: 1.5; }
`}</style>
</PlayProvider>
);
} Point at the source
Section titled “Point at the source”The homepage marks its stamp with shared:
<!-- on playhtml.fun -->
<img id="stamp" src="playhtml-logo.png" can-spin shared />
Any other page, on any site, reads and writes the same rotation with
data-source and the same capability. Its markup and styles can be different:
<!-- anywhere else -->
<img class="stamp" src="playhtml-logo.png" data-source="playhtml.fun#stamp" can-spin />
See Shared elements for read-only sources and
the full data-source syntax.