diff --git a/db/migrations/5.2.10_add_link_to_cw_structural_elements.php b/db/migrations/5.2.10_add_link_to_cw_structural_elements.php
new file mode 100644
index 0000000000000000000000000000000000000000..81ffaf7392e1831388e4d9c24b5a680f0d8a5c2f
--- /dev/null
+++ b/db/migrations/5.2.10_add_link_to_cw_structural_elements.php
@@ -0,0 +1,27 @@
+<?php
+
+final class AddLinkToCwStructuralElements extends Migration
+{
+    public function description()
+    {
+        return 'Adds columns for link funtions to cw_structural_elements table';
+    }
+
+    public function up()
+    {
+        DBManager::get()->exec("
+            ALTER TABLE `cw_structural_elements`
+                ADD COLUMN `is_link` tinyint(1) NOT NULL AFTER `parent_id`,
+                ADD COLUMN `target_id` int(11) DEFAULT NULL AFTER `is_link`
+        ");
+    }
+
+    public function down()
+    {
+        DBManager::get()->exec("
+            ALTER TABLE `cw_structural_elements`
+                DROP COLUMN `is_link`,
+                DROP COLUMN `target_id`
+        ");
+    }
+}
diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php
index 408e57286fc0f06b450ba800f44a56bfa8303426..4db0b6999629cbb313f14a20b38755c0103b03f0 100644
--- a/lib/classes/JsonApi/RouteMap.php
+++ b/lib/classes/JsonApi/RouteMap.php
@@ -396,6 +396,7 @@ class RouteMap
 
         // not a JSON route
         $group->post('/courseware-structural-elements/{id}/copy', Routes\Courseware\StructuralElementsCopy::class);
+        $group->post('/courseware-structural-elements/{id}/link', Routes\Courseware\StructuralElementsLink::class);
 
         $group->get('/courseware-structural-elements/{id}/comments', Routes\Courseware\StructuralElementCommentsOfStructuralElementsIndex::class);
         $group->post('/courseware-structural-element-comments', Routes\Courseware\StructuralElementCommentsCreate::class);
diff --git a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsLink.php b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsLink.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e83514f33240698c12402a41b035c62291e71ff
--- /dev/null
+++ b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsLink.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace JsonApi\Routes\Courseware;
+
+use JsonApi\NonJsonApiController;
+use Courseware\StructuralElement;
+use JsonApi\Errors\AuthorizationFailedException;
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
+
+/**
+ * Link an courseware structural element to another courseware structural element
+ *
+ * @author  Ron Lucke <lucke@elan-ev.de>
+ * @license GPL2 or any later version
+ *
+ * @since   Stud.IP 5.2
+ */
+
+class StructuralElementsLink extends NonJsonApiController
+{
+    public function __invoke(Request $request, Response $response, array $args)
+    {
+        $data = $request->getParsedBody()['data'];
+
+        $targetElement = StructuralElement::find($args['id']);
+        $parent = StructuralElement::find($data['parent_id']);
+        $user = $this->getUser($request);
+
+        if (!Authority::canCreateStructuralElement($user, $parent) || !Authority::canUpdateStructuralElement($user, $targetElement)) {
+            throw new AuthorizationFailedException();
+        }
+
+        $newElement = $this->linkElement($user, $targetElement, $parent);
+
+        return $this->redirectToStructuralElement($response, $newElement);
+    }
+
+    private function linkElement(\User $user, StructuralElement $targetElement, StructuralElement $parent)
+    {
+        $newElement = $targetElement->link($user, $parent);
+
+        return $newElement;
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.Superglobals)
+     */
+    private function redirectToStructuralElement(Response $response, StructuralElement $resource): Response
+    {
+        $pathinfo = $this->getSchema($resource)
+            ->getSelfLink($resource)
+            ->getStringRepresentation($this->container->get('json-api-integration-urlPrefix'));
+        $old = \URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']);
+        $url = \URLHelper::getURL($pathinfo, [], true);
+        \URLHelper::setBaseURL($old);
+
+        return $response->withHeader('Location', $url)->withStatus(303);
+    }
+}
\ No newline at end of file
diff --git a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
index 1c527e45712eaffd93ab39963b4b3250e441fc2d..f4c0766ecbe3b6e11364999b67677d60b112b43c 100755
--- a/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
+++ b/lib/classes/JsonApi/Routes/Courseware/StructuralElementsShow.php
@@ -29,6 +29,7 @@ class StructuralElementsShow extends JsonApiController
         'editor',
         'owner',
         'parent',
+        'target'
     ];
 
     /**
diff --git a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
index 49bd4cdc81d9aea73a521dbcb6fda93257ed3643..b50b17979ef4a8b4534f5a83ba47bbe64db741d2 100755
--- a/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
+++ b/lib/classes/JsonApi/Schemas/Courseware/StructuralElement.php
@@ -51,7 +51,8 @@ class StructuralElement extends SchemaProvider
             'write-approval' => $resource['write_approval']->getIterator(),
             'copy-approval' => $resource['copy_approval']->getIterator(),
             'can-edit' => $resource->canEdit($user),
-
+            'is-link' => (int) $resource['is_link'],
+            'target-id' => (int)  $resource['target_id'],
             'external-relations' => $resource['external_relations']->getIterator(),
             'mkdate' => date('c', $resource['mkdate']),
             'chdate' => date('c', $resource['chdate']),
diff --git a/lib/models/Courseware/StructuralElement.php b/lib/models/Courseware/StructuralElement.php
index ac6116f205edd02d9554d7aecd328b4d88a88157..7a127dbe18efe2b3c3bf38845e4b44a68b9b61e2 100755
--- a/lib/models/Courseware/StructuralElement.php
+++ b/lib/models/Courseware/StructuralElement.php
@@ -16,6 +16,8 @@ use User;
  *
  * @property int                            $id                 database column
  * @property int                            $parent_id          database column
+ * @property int                            $is_link            database column
+ * @property int                            $target_id          database column
  * @property string                         $range_id           database column
  * @property string                         $range_type         database column
  * @property string                         $owner_id           database column
@@ -269,8 +271,16 @@ class StructuralElement extends \SimpleORMap
         switch ($this->range_type) {
             case 'user':
                 // Kontext "user": Nutzende können nur ihre eigenen Strukturknoten sehen.
-                return $this->range_id === $user->id;
+                if  ($this->range_id === $user->id) {
+                    return true;
+                }
 
+                $link = StructuralElement::findOneBySQL('target_id = ?', [$this->id]);
+                if ($link) {
+                    return true;
+                }
+
+                return false;
             case 'course':
                 if (!$GLOBALS['perm']->have_studip_perm('user', $this->range_id, $user->id)) {
                     return false;
@@ -776,6 +786,39 @@ SQL;
         }
     }
 
+    public function link(User $user, StructuralElement $parent): StructuralElement
+    {
+        $element = self::build([
+            'parent_id' => $parent->id,
+            'is_link' => 1,
+            'target_id' => $this->id,
+            'range_id' => $parent->range_id,
+            'range_type' => $parent->range_type,
+            'owner_id' => $user->id,
+            'editor_id' => $user->id,
+            'edit_blocker_id' => null,
+            'title' => $this->title,
+            'purpose' => $this->purpose,
+            'position' => $parent->countChildren(),
+            'payload' => $this->payload,
+        ]);
+
+        $element->store();
+
+        $this->linkChildren($user, $element);
+
+        return $element;
+    }
+
+    private function linkChildren(User $user, StructuralElement $newElement): void
+    {
+        $children = self::findBySQL('parent_id = ?', [$this->id]);
+
+        foreach ($children as $child) {
+            $child->link($user, $newElement);
+        }
+    }
+
     public function pdfExport($user, bool $with_children = false)
     {
         $doc = new \ExportPDF('P', 'mm', 'A4', true, 'UTF-8', false);
diff --git a/resources/assets/stylesheets/scss/courseware.scss b/resources/assets/stylesheets/scss/courseware.scss
index 666d2e6208b1688a467d262e935d494c853d310b..4db8ab07d109179734cacb99f44834ef8f726fc1 100755
--- a/resources/assets/stylesheets/scss/courseware.scss
+++ b/resources/assets/stylesheets/scss/courseware.scss
@@ -2591,10 +2591,9 @@ m a n a g e r
 .cw-course-manager {
     display: flex;
     flex-wrap: wrap;
-    max-width: 1120px;
+    max-width: 1600px;
 
     .cw-course-manager-tabs {
-        max-width: 560px;
         width: calc(50% - 10px);
         margin-right: 20px;
 
diff --git a/resources/vue/components/courseware/CoursewareCourseManager.vue b/resources/vue/components/courseware/CoursewareCourseManager.vue
index 7d6ab4fea56c5752bcbf4819dca0be429309afcd..ad9ae98119c37fe473a2428bdb396f485e50558e 100755
--- a/resources/vue/components/courseware/CoursewareCourseManager.vue
+++ b/resources/vue/components/courseware/CoursewareCourseManager.vue
@@ -92,7 +92,11 @@
                     <courseware-manager-copy-selector @loadSelf="reloadElements" @reloadElement="reloadElements" />
                 </courseware-tab>
 
-                <courseware-tab :name="$gettext('Importieren')"  :index="3">
+                <courseware-tab :name="$gettext('Verknüpfen')" :index="3">
+                    <courseware-manager-link-selector @loadSelf="reloadElements" @reloadElement="reloadElements" />
+                </courseware-tab>
+
+                <courseware-tab :name="$gettext('Importieren')" :index="4">
                     <courseware-manager-import />
                 </courseware-tab>
                 <courseware-tab v-if="context.type === 'courses'" :name="$gettext('Aufgabe verteilen')"  :index="4">
@@ -109,6 +113,7 @@ import CoursewareTab from './CoursewareTab.vue';
 import CoursewareCollapsibleBox from './CoursewareCollapsibleBox.vue';
 import CoursewareManagerElement from './CoursewareManagerElement.vue';
 import CoursewareManagerCopySelector from './CoursewareManagerCopySelector.vue';
+import CoursewareManagerLinkSelector from './CoursewareManagerLinkSelector.vue';
 import CoursewareManagerTaskDistributor from './CoursewareManagerTaskDistributor.vue';
 import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
 import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
@@ -124,6 +129,7 @@ export default {
         CoursewareCollapsibleBox,
         CoursewareManagerElement,
         CoursewareManagerCopySelector,
+        CoursewareManagerLinkSelector,
         CoursewareCompanionOverlay,
         CoursewareCompanionBox,
         CoursewareManagerTaskDistributor,
diff --git a/resources/vue/components/courseware/CoursewareManagerElement.vue b/resources/vue/components/courseware/CoursewareManagerElement.vue
index 7dfe67b8836fb89667b74932fc8a7b448ba3a169..3e8a460b12755c4a23a29780de156e46c1e645c4 100755
--- a/resources/vue/components/courseware/CoursewareManagerElement.vue
+++ b/resources/vue/components/courseware/CoursewareManagerElement.vue
@@ -29,6 +29,7 @@
                 </header>
             </div>
             <courseware-collapsible-box
+            v-if="!elementsOnly"
                 :open="true"
                 :title="$gettext('Abschnitt')"
                 class="cw-manager-element-containers"
@@ -137,7 +138,7 @@ export default {
     props: {
         type: {
             validator(value) {
-                return ['current', 'self', 'remote', 'own','import'].includes(value);
+                return ['current', 'self', 'remote', 'own', 'import', 'link'].includes(value);
             },
         },
         remoteCoursewareRangeId: String,
@@ -147,6 +148,9 @@ export default {
         },
         moveSelfChildPossible: {
             default: true
+        },
+        elementsOnly: {
+            default: false
         }
     },
     data() {
@@ -162,9 +166,11 @@ export default {
             discardStateArrayContainers: [],
             insertingInProgress: false,
             copyingFailed: false,
+            linkingFailed: false,
             text: {
                 inProgress: this.$gettext('Vorgang läuft. Bitte warten Sie einen Moment.'),
                 copyProcessFailed: [],
+                linkProcessFailed: [],
             },
         };
     },
@@ -314,6 +320,7 @@ export default {
             updateStructuralElement: 'updateStructuralElement',
             deleteStructuralElement: 'deleteStructuralElement',
             copyStructuralElement: 'copyStructuralElement',
+            linkStructuralElement: 'linkStructuralElement',
             loadStructuralElement: 'loadStructuralElement',
             loadContainer: 'loadContainer',
             updateContainer: 'updateContainer',
@@ -335,7 +342,7 @@ export default {
         },
 
          validateSource(source) {
-            return (source === 'self' || source === 'remote' || source === 'own');
+            return ['self', 'remote', 'own', 'link'].includes(source);
         },
 
         afterInsertCompletion() {
@@ -357,6 +364,11 @@ export default {
             this.insertingInProgress = false;
         },
 
+        showFailedLinkProcessCompanion() {
+            this.linkingFailed = true;
+            this.insertingInProgress = false;
+        },
+
         async insertElement(data) {
             let source = data.source;
             let element = data.element;
@@ -380,7 +392,8 @@ export default {
                     await this.unlockObject({ id: element.id, type: 'courseware-structural-elements' });
                     this.loadStructuralElement(this.currentElement.id);
                     this.$emit('reloadElement');
-                } else if(source === 'remote' || source === 'own') {
+                }
+                if (source === 'remote' || source === 'own') {
                     //create Element
                     let parentId = this.filingData.parentItem.id;
                     await this.copyStructuralElement({
@@ -394,6 +407,18 @@ export default {
                     });
                     this.$emit('loadSelf', parentId);
                 }
+                if (source === 'link') {
+                    let parentId = this.filingData.parentItem.id;
+                    await this.linkStructuralElement({
+                        parentId: parentId,
+                        elementId: element.id,
+                    }).catch((error) => {
+                        let message = this.$gettextInterpolate('%{ pageTitle } konnte nicht verknüpft werden.', {pageTitle: element.attributes.title});
+                        this.text.linkProcessFailed.push(message);
+                        this.showFailedLinkProcessCompanion();
+                    });
+                    this.$emit('loadSelf', parentId);
+                }
                 this.afterInsertCompletion();
             }
         },
@@ -583,6 +608,8 @@ export default {
                 }
                 this.copyingFailed = false;
                 this.text.copyProcessFailed = [];
+                this.linkingFailed = false;
+                this.text.linkProcessFailed = [];
             } else {
                 this.elementInserterActive = false;
                 this.containerInserterActive = false;
@@ -595,7 +622,7 @@ export default {
     },
     watch: {
         filingData(newValue) {
-            if (!['self', 'remote', 'own', 'import'].includes(this.type)) {
+            if (!['self', 'remote', 'own', 'import', 'link'].includes(this.type)) {
                 return false;
             }
             this.updateFilingData(newValue);
diff --git a/resources/vue/components/courseware/CoursewareManagerLinkSelector.vue b/resources/vue/components/courseware/CoursewareManagerLinkSelector.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1f4774ff05af1661714595fda43fa83880d4ca89
--- /dev/null
+++ b/resources/vue/components/courseware/CoursewareManagerLinkSelector.vue
@@ -0,0 +1,78 @@
+<template>
+    <div class="cw-manager-link-selector">
+        <courseware-manager-element
+            v-if="ownId !== null"
+            type="link"
+            :currentElement="ownElement"
+            :elementsOnly="true"
+            @selectElement="setOwnId"
+            @loadSelf="loadSelf"
+        />
+    </div>
+</template>
+
+<script>
+import CoursewareManagerElement from './CoursewareManagerElement.vue';
+import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
+import { mapActions, mapGetters } from 'vuex';
+
+export default {
+    name: 'courseware-manager-link-selector',
+    components: {
+        CoursewareManagerElement,
+        CoursewareCompanionBox,
+    },
+
+    data() {
+        return {
+            ownCoursewareInstance: {},
+            ownId: null,
+            ownElement: {},
+        }
+    },
+
+    computed: {
+        ...mapGetters({
+            courseware: 'courseware',
+            structuralElementById: 'courseware-structural-elements/byId',
+            userId: 'userId',
+        }),
+    },
+
+    methods: {
+        ...mapActions({
+            loadAnotherCourseware: 'courseware-structure/loadAnotherCourseware',
+            loadStructuralElementById: 'courseware-structural-elements/loadById',
+        }),
+        async loadOwnCourseware() {
+            this.ownCoursewareInstance = await this.loadAnotherCourseware({ id: this.userId, type: 'users' });
+            if (this.ownCoursewareInstance !== null) {
+                await this.setOwnId(this.ownCoursewareInstance.relationships.root.data.id);
+            } else {
+                this.ownId = '';
+            }
+        },
+        async setOwnId(target) {
+            this.ownId = target;
+            const options = {
+                include: 'children'
+            };
+            await this.loadStructuralElementById({ id: this.ownId, options });
+            this.initOwn();
+        },
+        initOwn() {
+            this.ownElement = this.structuralElementById({ id: this.ownId });
+        },
+        reloadElement() {
+            this.$emit('reloadElement');
+        },
+        loadSelf(data) {
+            this.$emit('loadSelf', data);
+        },
+    },
+
+    async mounted() {
+        await this.loadOwnCourseware();
+    },
+}
+</script>
\ No newline at end of file
diff --git a/resources/vue/components/courseware/CoursewareStructuralElement.vue b/resources/vue/components/courseware/CoursewareStructuralElement.vue
index 009c34d12981b016be821e91a2d6a4ee3966c647..36381bf82d45566776298639d52c3cee14e224c0 100755
--- a/resources/vue/components/courseware/CoursewareStructuralElement.vue
+++ b/resources/vue/components/courseware/CoursewareStructuralElement.vue
@@ -12,11 +12,11 @@
                             <router-link v-if="prevElement" :to="'/structural_element/' + prevElement.id">
                                 <div class="cw-ribbon-button cw-ribbon-button-prev" :title="textRibbon.perv" />
                             </router-link>
-                            <div v-else class="cw-ribbon-button cw-ribbon-button-prev-disabled" :title="$gettext('keine vorherige Seite')"/>
+                            <div v-else class="cw-ribbon-button cw-ribbon-button-prev-disabled" :title="$gettext('Keine vorherige Seite')"/>
                             <router-link v-if="nextElement" :to="'/structural_element/' + nextElement.id">
                                 <div class="cw-ribbon-button cw-ribbon-button-next" :title="textRibbon.next" />
                             </router-link>
-                            <div v-else class="cw-ribbon-button cw-ribbon-button-next-disabled" :title="$gettext('keine nächste Seite')"/>
+                            <div v-else class="cw-ribbon-button cw-ribbon-button-next-disabled" :title="$gettext('Keine nächste Seite')"/>
                         </template>
                         <template #breadcrumbList>
                             <li
@@ -66,7 +66,7 @@
                     </courseware-ribbon>
 
                     <div
-                        v-if="canVisit && !sortMode"
+                        v-if="canVisit && !sortMode && !isLink"
                         class="cw-container-wrapper"
                         :class="{
                             'cw-container-wrapper-consume': consumeMode,
@@ -97,6 +97,35 @@
                             class="cw-container-item"
                         />
                     </div>
+                    <div
+                        v-if="isLink"
+                        class="container-wrapper"
+                        :class="{
+                            'cw-container-wrapper-consume': consumeMode,
+                            'cw-container-wrapper-discuss': discussView,
+                        }"
+                    >
+                        <courseware-structural-element-discussion
+                            v-if="discussView"
+                            :structuralElement="structuralElement"
+                            :canEdit="canEdit"
+                        />
+                        <courseware-companion-box
+                            v-if="editView"
+                            :msgCompanion="$gettextInterpolate('Dieser Inhalt ist aus den persönlichen Lerninhalten von %{ ownerName } verlinkt und kann nur dort bearbeitet werden.', { ownerName: ownerName })"
+                            mood="pointing"
+                        />
+                        <component
+                            v-for="container in linkedContainers"
+                            :key="container.id"
+                            :is="containerComponent(container)"
+                            :container="container"
+                            :canEdit="false"
+                            :canAddElements="false"
+                            :isTeacher="userIsTeacher"
+                            class="cw-container-item"
+                        />
+                    </div>
                     <div v-if="canVisit && canEdit && sortMode" class="cw-container-wrapper-sort-mode">
                         <draggable
                             class="cw-structural-element-list-sort-mode"
@@ -1058,6 +1087,9 @@ export default {
         discussView() {
             return this.viewMode === 'discuss';
         },
+        editView() {
+            return this.viewMode === 'edit';
+        },
         pdfExportURL() {
             if (this.context.type === 'users') {
                 return STUDIP.URLHelper.getURL(
@@ -1130,6 +1162,45 @@ export default {
                 (!this.isRoot && this.canEdit) || !this.canEdit || (!this.noContainers && this.isRoot && this.canEdit)
             );
         },
+
+        isLink() {
+            if (this.structuralElement) {
+                return this.structuralElement.attributes['is-link'] === 1;
+            }
+
+            return false;
+        },
+
+        linkedElement() {
+            if (this.isLink) {
+                return this.structuralElementById({ id: this.structuralElement.attributes['target-id']});
+            }
+
+            return null;
+        },
+
+        linkedContainers() {
+            let containers = [];
+            let relatedContainers = this.linkedElement?.relationships?.containers?.data;
+
+            if (relatedContainers) {
+                for (const container of relatedContainers) {
+                    containers.push(this.containerById({ id: container.id}));
+                }
+            }
+
+            return containers;
+        },
+        owner() {
+            const user = this.$store.getters['users/related']({
+                parent: { type: this.structuralElement.type, id: this.structuralElement.id },
+                relationship: 'owner'
+            });
+            return user ? user : null;
+        },
+        ownerName() {
+            return this.owner ? this.owner.attributes['formatted-name'] : '?';
+        },
     },
 
     methods: {
@@ -1157,6 +1228,7 @@ export default {
             setStructuralElementSortMode: 'setStructuralElementSortMode',
             sortContainersInStructualElements: 'sortContainersInStructualElements',
             loadTask: 'loadTask',
+            loadStructuralElement: 'loadStructuralElement',
         }),
 
         initCurrent() {
@@ -1423,6 +1495,10 @@ export default {
                     taskId: this.structuralElement.relationships.task.data.id,
                 });
             }
+
+            if (this.isLink) {
+                this.loadStructuralElement(this.structuralElement.attributes['target-id']);
+            }
         },
         containers() {
             if (!this.sortMode) {
diff --git a/resources/vue/store/courseware/courseware.module.js b/resources/vue/store/courseware/courseware.module.js
index bf443700f8c1e47671a1820ca6d51a5391e2fda0..d8ae6d77e03c83f1df2ef95e7e73860faf553d12 100755
--- a/resources/vue/store/courseware/courseware.module.js
+++ b/resources/vue/store/courseware/courseware.module.js
@@ -400,6 +400,19 @@ export const actions = {
         return dispatch('courseware-structure/loadDescendants', { root: newElement });
     },
 
+    async linkStructuralElement({ dispatch, getters, rootGetters }, { parentId, elementId }) {
+        const link = { data: { parent_id: parentId } };
+
+        const result = await state.httpClient.post(`courseware-structural-elements/${elementId}/link`, link);
+        const id = result.data.data.id;
+        await dispatch('loadStructuralElement', id);
+
+        const newElement = rootGetters['courseware-structural-elements/byId']({ id });
+
+        return dispatch('courseware-structure/loadDescendants', { root: newElement });
+
+    },
+
     async createBlockInContainer({ dispatch }, { container, blockType }) {
         const block = {
             attributes: {