# Able to duplicate single instance child XBlocks within a Nested XBlock in Studio

**URL:** <https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025>\
**Category:** Development\
**Tags:** studio, redwood, xblock\
**Created:** [February 17, 2025, 3:25pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025 "2025-02-17T15:25:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![emartus](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/emartus/32/5604_2.png) [@emartus](https://discuss.openedx.org/u/emartus)\
**Post date:** [February 17, 2025, 3:25pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025/1 "2025-02-17T15:25:44Z")

</div>

Hello, we have created a Nested XBlock and configured some of the available child XBlock types with `single_instance=True` as shown below.

```auto
class CaseReportXBlock(StudioContainerWithNestedXBlocksMixin, XBlock):
    display_name = String(
        display_name="Display Name",
        help="The display name for this component.",
        scope=Scope.content,
        default="Case Report",
    )

    completion_mode = XBlockCompletionMode.AGGREGATOR
    show_in_read_only_mode = True
    icon_class = "other"

    @property
    def allowed_nested_blocks(self):
        from ..case_file import AmbraCaseFileXBlock, CaseFileXBlock, CaseHistoryXBlock
        from ..case_report import CaseReportSubmissionXBlock

        return [
            NestedXBlockSpec(
                CaseHistoryXBlock,
                label="Case History",
                category="case_history",
                single_instance=True,
            ),
            NestedXBlockSpec(
                CaseFileXBlock,
                label="Case File (URL)",
                category="case_file",
            ),
            NestedXBlockSpec(
                AmbraCaseFileXBlock,
                label="Case File (Ambra)",
                category="ambra",
            ),
            NestedXBlockSpec(
                CaseReportSubmissionXBlock,
                label="Case Report Submission",
                category="case_report_submission",
                single_instance=True,
            ),
        ]

```

Using `single_instance=True`, we are able to successfully disable the buttons for the XBlock types in the “Add New Component” section, however this does not disable the ability to duplicate already existing XBlocks providing a way around the “single instance” configuration as shown in the screenshot below.

 ![image](https://us1.discourse-cdn.com/flex020/uploads/openedx/original/2X/d/d8a333f04a7e5a00012e51d011cb7ced089a370b.png)

Based on my initial investigation, whether or not an XBlock can be duplicated is controlled by the `can_add` context in this template [edx-platform/cms/templates/studio\_xblock\_wrapper.html at 5071f28e20055f7039326cd0d2e2f8ca933217ed · openedx/edx-platform · GitHub](https://github.com/openedx/edx-platform/blob/5071f28e20055f7039326cd0d2e2f8ca933217ed/cms/templates/studio_xblock_wrapper.html#L161-L172), which is appears to be added to the context here [edx-platform/cms/djangoapps/contentstore/views/preview.py at 5071f28e20055f7039326cd0d2e2f8ca933217ed · openedx/edx-platform · GitHub](https://github.com/openedx/edx-platform/blob/5071f28e20055f7039326cd0d2e2f8ca933217ed/cms/djangoapps/contentstore/views/preview.py#L323).

Setting `can_add` to false does successfully remove the duplicate option, but it also removes the delete option from the menu (this also comes from `studio_xblock_wrapper.html`). While not ideal, this is something we could likely find a work around for. However, it is not clear how to set this `can_add` context for a given XBlock within the nested spec since depending on the XBlock type we may want to allow for multiple/duplication if it’s a direct child of a Vertical XBlock for instance.

I had some luck overriding the `render` method of a child XBlock to update the context, however that unexpectedly prevented duplication for all children within the nested XBlock and the parent nested XBlock as well instead of just the XBlock type I modified.

It’s worth noting that we are on the Redwood 3 release and are still using old Studio, we have not made the move to the Content Authoring MFE.

If anyone has experience with nested XBlocks and has suggestions, they would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![braden](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/braden/32/46_2.png) [@braden](https://discuss.openedx.org/u/braden)\
**Post date:** [February 19, 2025, 8:00pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025/2 "2025-02-19T20:00:51Z")

</div>

We made `StudioContainerWithNestedXBlocksMixin` 10 years ago for the “Problem Builder” block, and it received some minor maintenance 6 years ago during a Django upgrade, but otherwise nobody has really touched that code in a long time and I didn’t realize it was even being used by any other XBlocks. That’s also why the UI looks terrible. What’s more, I’m sorry to be the bearer of bad news, but “nested XBlocks” have a number of performance problems so our plan for some time has been to eventually remove support for nested XBlocks completely. This post made me realize that we haven’t yet clearly indicated that in the code/documentation, so we should do that ASAP (CC @kmccormick).

The issue you’re having is simply a bug, and your initial investigation is roughly on track. I don’t think there’s any way to work around it without actually modifying the platform code to fix the bug, by introducing some more detailed “can duplicate” context that’s specific to each block or something along those lines. However, given the plans to deprecate all this functionality entirely, it may not be worth investing in that.

You can of course continue along this path and find a way to either fix the bug or hack around it, and you should have something that works for now - but realize that it will most likely need a significant refactor in a year or two. So if you have the capacity, I’d recommend finding a way to achieve the same thing without using nested XBlocks, e.g. by storing the “case history”, “case files”, and “case reports” as XBlock fields on the main XBlock or using a Django model if necessary.

Some people in the community are also working on [react-based XBlock UIs](https://github.com/open-craft/xblock-react) and an overhaul of the XBlock API to address some of the longstanding pain points with XBlock development such as this.

---

<div class="post-metadata">

**Author:** ![emartus](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/emartus/32/5604_2.png) [@emartus](https://discuss.openedx.org/u/emartus)\
**Post date:** [February 19, 2025, 8:29pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025/3 "2025-02-19T20:29:31Z")

</div>

@braden Thank you for your reply, I’ll follow up with my team to find a path forward for our use cases. It’s good to have the heads up on the planned deprecation.

---

<div class="post-metadata">

**Author:** ![emartus](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/emartus/32/5604_2.png) [@emartus](https://discuss.openedx.org/u/emartus)\
**Post date:** [February 19, 2025, 8:39pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025/4 "2025-02-19T20:39:16Z")

</div>

@braden Follow up question from my team: will the deprecation plan include a migration strategy?

---

<div class="post-metadata">

**Author:** ![braden](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/braden/32/46_2.png) [@braden](https://discuss.openedx.org/u/braden)\
**Post date:** [February 19, 2025, 9:39pm UTC](https://discuss.openedx.org/t/able-to-duplicate-single-instance-child-xblocks-within-a-nested-xblock-in-studio/15025/5 "2025-02-19T21:39:39Z")

</div>

Well, we thought problem builder was the only XBlock using this capability, and we have started the process of planning a migration strategy for it: [Future Directions for Problem Builder](https://discuss.openedx.org/t/future-directions-for-problem-builder/10337)

We can certainly make recommendations but they would likely be what I just said above: moving from multiple child blocks to one XBlock with a more complex data structure to represent it. We also hope to have an improved XBlock v2 API that offers more simplicity and flexibility to XBlock authors, but haven’t made much progress on that yet.

There are also some built-in XBlocks like A/B testing, randomization, etc. that use XBlock children but aren’t using `StudioContainerWithNestedXBlocksMixin` and there is a migration plan being developed for them - moving their logic into a new “selector” API at the unit level.
