diff --git a/cms/templates/content_libraries/xblock_iframe.html b/cms/templates/content_libraries/xblock_iframe.html
index e8eb4c96ead0..b6e455f78515 100644
--- a/cms/templates/content_libraries/xblock_iframe.html
+++ b/cms/templates/content_libraries/xblock_iframe.html
@@ -6,7 +6,12 @@
-
+ {% if is_development %}
+
+
+ {% else %}
+
+ {% endif %}
diff --git a/lms/templates/xblock_v2/xblock_iframe.html b/lms/templates/xblock_v2/xblock_iframe.html
new file mode 120000
index 000000000000..7264c253466d
--- /dev/null
+++ b/lms/templates/xblock_v2/xblock_iframe.html
@@ -0,0 +1 @@
+../../../cms/templates/content_libraries/xblock_iframe.html
\ No newline at end of file
diff --git a/openedx/core/djangoapps/xblock/rest_api/urls.py b/openedx/core/djangoapps/xblock/rest_api/urls.py
index 034d490aa3a8..dec2fc562fee 100644
--- a/openedx/core/djangoapps/xblock/rest_api/urls.py
+++ b/openedx/core/djangoapps/xblock/rest_api/urls.py
@@ -29,4 +29,9 @@
),
])),
])),
+ path('xblocks/v2//', include([
+ # render one of this XBlock's views (e.g. student_view) for embedding in an iframe
+ # NOTE: this endpoint is **unstable** and subject to changes after Sumac
+ re_path(r'^embed/(?P[\w\-]+)/$', views.embed_block_view),
+ ])),
]
diff --git a/openedx/core/djangoapps/xblock/rest_api/views.py b/openedx/core/djangoapps/xblock/rest_api/views.py
index 9972e7463b23..7934e24bd2db 100644
--- a/openedx/core/djangoapps/xblock/rest_api/views.py
+++ b/openedx/core/djangoapps/xblock/rest_api/views.py
@@ -1,12 +1,16 @@
"""
Views that implement a RESTful API for interacting with XBlocks.
"""
+import itertools
+import json
from common.djangoapps.util.json_request import JsonResponse
from corsheaders.signals import check_request_enabled
+from django.conf import settings
from django.contrib.auth import get_user_model
from django.db.transaction import atomic
from django.http import Http404
+from django.shortcuts import render
from django.utils.translation import gettext as _
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt
@@ -21,6 +25,7 @@
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import UsageKey
+import openedx.core.djangoapps.site_configuration.helpers as configuration_helpers
from openedx.core.djangoapps.xblock.learning_context.manager import get_learning_context_impl
from openedx.core.lib.api.view_utils import view_auth_classes
from ..api import (
@@ -87,6 +92,47 @@ def render_block_view(request, usage_key_str, view_name):
return Response(response_data)
+@api_view(['GET'])
+@view_auth_classes(is_authenticated=False)
+@permission_classes((permissions.AllowAny, )) # Permissions are handled at a lower level, by the learning context
+@xframe_options_exempt
+def embed_block_view(request, usage_key_str, view_name):
+ """
+ Render the given XBlock in an