diff --git a/packages/app-shell/src/app-shell.js b/packages/app-shell/src/app-shell.js
index fb573076a6088adace45958d2cc889cd80651ee0..5dadf1ad9090f3d2e44406fa4653226e0a48e211 100644
--- a/packages/app-shell/src/app-shell.js
+++ b/packages/app-shell/src/app-shell.js
@@ -2,7 +2,7 @@ import {createInstance} from './i18n.js';
 import {html, css} from 'lit';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import {LanguageSelect} from '@dbp-toolkit/language-select';
-import {Icon} from '@dbp-toolkit/common';
+import {Icon, getShadowRootDocument} from '@dbp-toolkit/common';
 import {AuthKeycloak} from '@dbp-toolkit/auth';
 import {AuthMenuButton} from './auth-menu-button.js';
 import {Notification} from '@dbp-toolkit/notification';
@@ -829,13 +829,7 @@ export class AppShell extends ScopedElementsMixin(DBPLitElement) {
             this.defineScopedElement(activity.element, customElements.get(activity.element));
         });
 
-        // In case of "Scoped Custom Element Registries" polyfill we create a scoped element
-        let elm;
-        if (this.shadowRoot.createElement !== undefined) {
-            elm = this.shadowRoot.createElement(activity.element);
-        } else {
-            elm = document.createElement(activity.element);
-        }
+        let elm = getShadowRootDocument(this).createElement(activity.element);
 
         this._onActivityAdded(elm);
         this._lastElm = elm;
diff --git a/packages/common/src/utils.js b/packages/common/src/utils.js
index a2a2deb3fb70cb4eace08403baeddc1f74430ac5..7d4b7b9b8ebdeac4df140055cbb9db56a6161786 100644
--- a/packages/common/src/utils.js
+++ b/packages/common/src/utils.js
@@ -15,3 +15,23 @@ export const combineURLs = (baseURL, addedURL) => {
     }
     return new URL(addedURL.replace(/^\/+/, ''), baseURL).href;
 };
+
+/**
+ * Returns a Document like thing that can be used to create elements.
+ *
+ * It provides createElement()/createElementNS()/importNode().
+ * The Document type annotation, while not correct, is used here for simplicity.
+ *
+ * https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md#scoped-element-creation-apis
+ *
+ * @param {HTMLElement} element
+ * @returns {Document|null}
+ */
+export function getShadowRootDocument(element) {
+    // In case the polyfill is loaded return the shadowRoot
+    // otherwise fall back to the global document
+    if (ShadowRoot.prototype.createElement !== undefined) {
+        return element.shadowRoot;
+    }
+    return document;
+}
diff --git a/packages/common/test/unit.js b/packages/common/test/unit.js
index 7bf4ac4d4e1926cbb8cf727e25edecafb3712543..64c44c270fcb40817f3dd4be38b3eb3b42b4c1dc 100644
--- a/packages/common/test/unit.js
+++ b/packages/common/test/unit.js
@@ -1,7 +1,7 @@
 import {expect, assert} from '@esm-bundle/chai';
 import * as utils from '../utils';
 import * as styles from '../styles';
-import {combineURLs} from '../';
+import {combineURLs, getShadowRootDocument} from '../';
 import '../jsonld.js';
 
 suite('utils', () => {
@@ -34,6 +34,16 @@ suite('utils', () => {
         assert.isTrue(res);
     });
 
+    test('getShadowRootDocument', () => {
+        class SomeElement3 extends HTMLElement {}
+        let res = utils.defineCustomElement('test-some-element-3', SomeElement3);
+        assert.isTrue(res);
+        let elm = new SomeElement3();
+        elm.attachShadow({mode: 'open'});
+        let doc = getShadowRootDocument(elm);
+        assert.isFunction(doc.createElement);
+    });
+
     test('getAssetURL', () => {
         // Backwards compat
         assert.equal(new URL(utils.getAssetURL('foo/bar')).pathname, '/foo/bar');
diff --git a/packages/file-handling/src/nextcloud-file-picker.js b/packages/file-handling/src/nextcloud-file-picker.js
index 8736bc44a8219b642a64e1f25a53bdb93bdceb20..13610f683efe021d91686fcd8226e80bc85a644f 100644
--- a/packages/file-handling/src/nextcloud-file-picker.js
+++ b/packages/file-handling/src/nextcloud-file-picker.js
@@ -2,7 +2,7 @@ import {createInstance} from './i18n';
 import {css, html} from 'lit';
 import {ScopedElementsMixin} from '@open-wc/scoped-elements';
 import DBPLitElement from '@dbp-toolkit/common/dbp-lit-element';
-import {Icon, MiniSpinner} from '@dbp-toolkit/common';
+import {Icon, MiniSpinner, getShadowRootDocument} from '@dbp-toolkit/common';
 import * as commonUtils from '@dbp-toolkit/common/utils';
 import * as commonStyles from '@dbp-toolkit/common/styles';
 import {createClient, parseXML} from 'webdav/web';
@@ -217,7 +217,7 @@ export class NextcloudFilePicker extends ScopedElementsMixin(DBPLitElement) {
                                 cell.getValue() === 'directory'
                                     ? `<${icon_tag} name="folder" class="nextcloud-picker-icon"></${icon_tag}>`
                                     : icon;
-                            let div = this.shadowRoot.createElement('div');
+                            let div = getShadowRootDocument(this).createElement('div');
                             div.innerHTML = html;
                             return div;
                         },