Sibling routes

When two playgrounds are open in the same browser, each can fetch and import the other's exported files, using the same URLs the files will have after deployment. Nothing has to be deployed first.

How sibling routes work

Every playground serves its exported files to its own output. Sibling routes extend that: a playground that shares a host with another open playground also receives that playground's exports, mounted under the other playground's route path. A file the other playground exports at /.js appears in your output at /document/.js when the other playground's route is example/document.

Note: Sibling routes are a playground feature. They work on live editor state, not on deployed state, and RTEdge.net has no counterpart: once deployed, the routes are ordinary deployments and plain URLs reach them.

Requirements

Two playgrounds are siblings when all of this holds:

A playground without routes has no siblings. Set routes in the Code dialog (Set Routes…, Alt+R / ⌥+R), or assign Code.D from io.eval.js or the console:

js
Code.D = ['example/document']   // in the first playground
Code.D = ['example/color']      // in the second playground

Mounting

A sibling's export /<name> is served in your output at /<sibling route path>/<name>. The path comes from the route in the sibling's Code.D: example/document mounts at /document/<name>, and a route at the host root mounts at /.

This works for relative and absolute same-origin URLs in output documents, such as fetch(), import(), <script src>, <link href> and iframes, and for fetch() inside your playground worker.

Your own routes are in the same index, so your output can also reach its own exports under its route path. With Code.D = ['example/color'], /color/x.js serves your own /x.js, as the deployed URL would.

Example

Two playgrounds, one exporting a module and one importing it:

First playground: example/document

html
<script type=module o:=.js>
  export const hello = name => `Hello, ${name}!`
</script>

Set Code.D = ['example/document']. The module is exported as /.js.

Second playground: example/color

html
<output id=out></output>
<script type=module>
  const { hello } = await import('../document/.js')
  out.value = hello('sibling')
</script>

Set Code.D = ['example/color'] in a second playground while the first one is open. ../document/.js resolves to /document/.js in the output, which the first playground serves. After you deploy both, example.rt.ht/color/ imports example.rt.ht/document/.js through the same relative path.

Rules

When siblings see changes

A playground publishes the exports of its last full output initialization, not the live text of its editor. It publishes them at each full output initialization, each time its routes change, and when another playground on a shared host announces itself. A sibling that receives a snapshot passes it to its output as soon as that output has initialized.

See Live sync and reloads for the full list of reload triggers.

After deployment

On RTEdge.net each route is its own deployment, and a route answers only for its own directory level. /document/.js belongs to example/document; /document/sub/x.js would belong to a different route, example/document/sub. The sibling mount in the playground follows the same shape, so a relative import that works in two open playgrounds keeps working between the two deployed routes. See Deploying and Exporting files.

Availability

FeaturePlaygroundRTEdge.netNotes
Sibling routesYesNot applicableAfter deployment the routes are separate deployments reached by ordinary URLs.
Exports of the live playgroundYesNoSiblings see the snapshot of the last full output initialization.

See also