diff --git a/core/src/components/PublicPageMenu/PublicPageMenuCustomEntry.vue b/core/src/components/PublicPageMenu/PublicPageMenuCustomEntry.vue
new file mode 100644
index 00000000000..f3c57a12042
--- /dev/null
+++ b/core/src/components/PublicPageMenu/PublicPageMenuCustomEntry.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
diff --git a/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue b/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue
new file mode 100644
index 00000000000..a5a1913ac2b
--- /dev/null
+++ b/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/src/components/PublicPageMenu/PublicPageMenuExternalDialog.vue b/core/src/components/PublicPageMenu/PublicPageMenuExternalDialog.vue
new file mode 100644
index 00000000000..992ea631600
--- /dev/null
+++ b/core/src/components/PublicPageMenu/PublicPageMenuExternalDialog.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+ {{ t('core', 'Create share') }}
+
+
+
+
+
+
diff --git a/core/src/components/PublicPageMenu/PublicPageMenuExternalEntry.vue b/core/src/components/PublicPageMenu/PublicPageMenuExternalEntry.vue
new file mode 100644
index 00000000000..a4451a38bbe
--- /dev/null
+++ b/core/src/components/PublicPageMenu/PublicPageMenuExternalEntry.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
diff --git a/core/src/components/PublicPageMenu/PublicPageMenuLinkEntry.vue b/core/src/components/PublicPageMenu/PublicPageMenuLinkEntry.vue
new file mode 100644
index 00000000000..54645e9ce48
--- /dev/null
+++ b/core/src/components/PublicPageMenu/PublicPageMenuLinkEntry.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
diff --git a/core/src/public-page-menu.ts b/core/src/public-page-menu.ts
new file mode 100644
index 00000000000..b290d1d03e9
--- /dev/null
+++ b/core/src/public-page-menu.ts
@@ -0,0 +1,15 @@
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import { getCSPNonce } from '@nextcloud/auth'
+import Vue from 'vue'
+
+import PublicPageMenu from './views/PublicPageMenu.vue'
+
+__webpack_nonce__ = getCSPNonce()
+
+const View = Vue.extend(PublicPageMenu)
+const instance = new View()
+instance.$mount('#public-page-menu')
diff --git a/core/src/views/PublicPageMenu.vue b/core/src/views/PublicPageMenu.vue
new file mode 100644
index 00000000000..a9ff78a7c5f
--- /dev/null
+++ b/core/src/views/PublicPageMenu.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
diff --git a/webpack.modules.js b/webpack.modules.js
index 1f29707611b..577f6f4a852 100644
--- a/webpack.modules.js
+++ b/webpack.modules.js
@@ -19,6 +19,7 @@ module.exports = {
main: path.join(__dirname, 'core/src', 'main.js'),
maintenance: path.join(__dirname, 'core/src', 'maintenance.js'),
profile: path.join(__dirname, 'core/src', 'profile.ts'),
+ 'public-page-menu': path.resolve(__dirname, 'core/src', 'public-page-menu.ts'),
recommendedapps: path.join(__dirname, 'core/src', 'recommendedapps.js'),
systemtags: path.resolve(__dirname, 'core/src', 'systemtags/merged-systemtags.js'),
'unified-search': path.join(__dirname, 'core/src', 'unified-search.ts'),