2 Bokeh.embed.embed_item share same CDS

I want to use Bokeh.embed.embed_item(item, div_id); to put one root in one div and second rot to another div. If i do it naively twose roots ale in separate documents and can not share column data souce.

You can use embed_items (plural) for this. It’s not something that has been advertised much, but it is what e.g. components on the Python side relies on under the hood, like this:

      const docs_json = { DOCUMENT DATA HERE };
      const render_items = [{
        "docid":"6833819f-9b5b-4904-821e-3f5eec77de9b",
        "elementid":"9574d123-9332-4b5f-96cc-6323bef37f40",
        "modelid":"7b328b27-9b14-4f7b-a5d8-0138bc7b0f59"
      }];

      Bokeh.embed.embed_items(docs_json, render_items);

Thank @Bryan for reply.

I want to add elements one by one like this:

from random import random

from bokeh.layouts import row
from bokeh.models import CrosshairTool, Span
from bokeh.plotting import figure
from bokeh.io import curdoc
import json

x = [random() * 10 for _ in range(200)]
y = [random() * 10 for _ in range(200)]

width = Span(dimension="width", line_dash="dashed", line_width=2)
height = Span(dimension="height", line_dash="dotted", line_width=2)

p1 = figure(height=400, width=400, x_range=(0, 10), y_range=(0, 10),
            tools="hover", toolbar_location=None)
p1.add_tools(CrosshairTool(overlay=[width, height]))
p1.circle(x, y, radius=0.2, alpha=0.3, hover_alpha=1.0)

p2 = figure(height=400, width=250, x_range=(0, 10), y_range=(0, 10),
            tools="hover", toolbar_location=None)
p2.add_tools(CrosshairTool(overlay=[width, height]))
p2.circle(x, y, radius=0.2, alpha=0.3, hover_alpha=1.0)

# ---------------------------------------------------------------------------- #
#                         Code above is from example                           #
# ---------------------------------------------------------------------------- #

p1.name = "p1"
p2.name = "p2"
curdoc().add_root(row(p1, p2))
jdoc = curdoc().to_json(deferred=False)
jdoc = json.dumps({"docId": jdoc})

with open('test.html', 'w') as f:
    f.write(f"""
    <html>
        <head>
        <script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.6.0.js"></script>
        <script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.6.0.js"></script>
        <script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.6.0.js"></script>

        <script type="application/json" id="jdoc">
            {jdoc}
        </script>

        </head>

        <body>
            <div id="p1"></div>
            <script>
                jdoc = document.getElementById('jdoc').textContent;
                items = [{{"docid": "docId","elementid": "p1","modelid": "p1"}}];
                Bokeh.embed.embed_items(jdoc, items);

                // Add p2 to the DOM
                var div = document.createElement("div");
                div.id = "p2";
                document.body.appendChild(div);
                
                // I want to embed p2 in after div p2 is added to the DOM
                items = [{{"docid": "docId","elementid": "p2","modelid": "p2"}}];
                Bokeh.embed.embed_items(jdoc, items);

            </script>
        </body>
    </html>
    """)

I’m not aware of any way to do that (there might be, but if so I don’t know it).