import * as React from 'react'
const EMBED_ORIGIN = 'https://my-quilt-catalog'
const PARENT_ORIGIN = window.location.origin
const EVENT_SOURCE = 'quilt-embed'
const mkNonce = () => `${Math.random()}`.slice(2)
const iframeRef = React.useRef(null)
const [nonce, setNonce] = React.useState(mkNonce)
// nonce is used to identify "our" Embed instance and make sure we're receiving messages from the same instance
// origin must be sent as a query parameter to enable cross-origin message passing from Embed to the parent
const src = `${EMBED_ORIGIN}/__embed?nonce=${nonce}&origin=${encodeURIComponent(PARENT_ORIGIN)}`
const postMessage = React.useCallback(
// function for sending messages to the Embed (it will only handle messages sent by the window that opened it aka parent)
if (!iframeRef.current) return
// origin must be sent as a second parameter to enable cross-origin message passing
iframeRef.current.contentWindow.postMessage(msg, EMBED_ORIGIN)
const initialize = React.useCallback(() => {
// see the `init` command reference in the API section below for details
bucket: 'your-bucket-here',
path: 'path-to-object-or-prefix',
// deep linking can be implemented by storing Embed's route and then initializing it with this stored route
route: location.search.route || undefined,
// e.g. { provider, token } for SSO or { password, username } (which doesn't seem like a right choice in most cases)
// getting credentials is your app's responsibility
credentials: { provider: 'okta', token: 'my token' },
fontFamily: '"Comic Sans MS", "Comic Sans", cursive',
href: 'https://my-app/s3-browser?route=<%= encodeURIComponent(url) %>',
// notification shown after copying href to the clipboard (if `emit` is not set to "override")
// arbitrary CSS files can be injected to further customize look and feel and/or layout
'https://my-cdn.com/my-custom-styles-1.css',
'https://my-other-host.com/my-custom-styles-2.css',
const navigate = React.useCallback((route) => {
// command the Embed to navigate to an arbitrary route
postMessage({ type: 'navigate', route })
const reloadIframe = React.useCallback(() => {
// reload the iframe by generating a new nonce (and therefore changing `src` computed value)
const handleMessage = React.useCallback(
// ignore messages from other windows
e.source !== iframeRef.current.contentWindow ||
// ensure origin is what we expect it to be (user has not navigated away)
e.origin !== EMBED_ORIGIN ||
// ensure the message has expected format (.source set to 'quilt-embed')
e.data.source !== EVENT_SOURCE ||
// ensure this is "our" instance by comparing nonce passed to the iframe
// via query string to the nonce passed back by the iframe
// handle messages from the Embed
console.error(e.data.message, e.data)
// store Embed state (route), e.g. update our URL to store the embed route in a query paramter or smth
console.log('embed navigating to', e.data.route)
// construct a custom link using e.data and copy it to clipboard or perform any other relevant action
console.log('s3 object link clicked', e.data)
[iframeRef, nonce, initialize],
// subscribe to messages from Embed
window.addEventListener('message', handleMessage)
window.removeEventListener('message', handleMessage)
// other things like styling and stuff