diff --git a/packages/web-app-files/src/components/AppBar/AppBar.vue b/packages/web-app-files/src/components/AppBar/AppBar.vue
index 1e145988b87..9c8c3f5012d 100644
--- a/packages/web-app-files/src/components/AppBar/AppBar.vue
+++ b/packages/web-app-files/src/components/AppBar/AppBar.vue
@@ -125,7 +125,7 @@
           <size-info v-if="hasBulkActions && selectedFiles.length > 0" class="oc-mr oc-visible@l" />
           <batch-actions v-if="hasBulkActions" />
         </div>
-        <view-options />
+        <view-options v-if="!hideViewOptions" />
       </div>
     </div>
   </div>
@@ -244,18 +244,32 @@ export default {
     hasBulkActions() {
       return this.$route.meta.hasBulkActions === true
     },
+    hideViewOptions() {
+      return this.$route.meta.hideViewOptions === true
+    },
     pageTitle() {
       const title = this.$route.meta.title
       return this.$gettext(title)
     },
 
     breadcrumbs() {
-      if (!(this.isPublicLocation || this.isPersonalLocation)) {
+      const isProjectSpaces =
+        isLocationSpacesActive(this.$router, 'files-spaces-projects') ||
+        isLocationSpacesActive(this.$router, 'files-spaces-project')
+
+      if (!(this.isPublicLocation || this.isPersonalLocation || isProjectSpaces)) {
         return []
       }
 
       const { params: routeParams, path: routePath } = this.$route
-      const { item: requestedItemPath = '' } = routeParams
+
+      let requestedItemPath = ''
+      if (isProjectSpaces) {
+        requestedItemPath = routeParams.spaceId || ''
+      } else {
+        requestedItemPath = routeParams.item || ''
+      }
+
       const basePaths =
         '/' +
         decodeURIComponent(routePath)
@@ -275,10 +289,17 @@ export default {
 
           if (i === rawItems.length - 1) {
             this.isPublicLocation && acc.shift()
-            acc.length &&
-              (acc[0].text = this.isPersonalLocation
-                ? this.$gettext('All files')
-                : this.$gettext('Public link'))
+
+            if (acc.length) {
+              if (this.isPersonalLocation) {
+                acc[0].text = this.$gettext('All files')
+              } else if (isProjectSpaces) {
+                acc[0].text = this.$gettext('Spaces')
+              } else {
+                acc[0].text = this.$gettext('Public link')
+              }
+            }
+
             acc.length && delete acc[acc.length - 1].to
           } else {
             delete acc[i].onClick
diff --git a/packages/web-app-files/src/router/spaces.ts b/packages/web-app-files/src/router/spaces.ts
index ba7cc24d99e..980a1936f62 100644
--- a/packages/web-app-files/src/router/spaces.ts
+++ b/packages/web-app-files/src/router/spaces.ts
@@ -39,7 +39,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
         meta: {
           hideFilelistActions: true,
           hasBulkActions: true,
-          hideAppBar: true,
+          hideViewOptions: true,
           title: $gettext('Spaces')
         }
       },
@@ -50,7 +50,6 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
         meta: {
           hideFilelistActions: true,
           hasBulkActions: true,
-          hideAppBar: true,
           title: $gettext('Space')
         }
       },
diff --git a/packages/web-app-files/src/views/spaces/Project.vue b/packages/web-app-files/src/views/spaces/Project.vue
index b9bee270d10..07af32a703f 100644
--- a/packages/web-app-files/src/views/spaces/Project.vue
+++ b/packages/web-app-files/src/views/spaces/Project.vue
@@ -4,7 +4,7 @@
     <template v-else>
       <not-found-message v-if="!space.id" class="files-not-found oc-height-1-1" />
       <div v-else class="oc-grid oc-grid-match oc-child-width-1-3@s">
-        <div class="oc-mt-s">
+        <div>
           <img
             class="space-overview-image"
             alt=""
@@ -14,7 +14,7 @@
         <div>
           <h3 class="oc-mb-s">{{ space.name }}</h3>
           <span v-if="space.description">{{ space.description }}</span>
-          <div v-if="markdownContent">
+          <div>
             <div ref="markdownContainer" class="markdown-container" v-html="markdownContent"></div>
             <div v-if="showMarkdownCollapse" class="markdown-collapse oc-text-center oc-mt-s">
               <oc-button appearance="raw" @click="toggleCollapseMarkdown">
@@ -25,15 +25,10 @@
           </div>
         </div>
       </div>
-      <no-content-message
-        v-if="isEmpty"
-        id="files-personal-empty"
-        class="files-empty"
-        icon="folder"
-      >
+      <no-content-message v-if="isEmpty" id="files-spaces-empty" class="files-empty" icon="folder">
         <template #message>
           <p class="oc-text-muted">
-            <span v-translate>No resource found</span>
+            <span v-translate>No resources found</span>
           </p>
         </template>
       </no-content-message>
@@ -48,10 +43,12 @@ import ListLoader from '../../components/FilesList/ListLoader.vue'
 import { ref } from '@vue/composition-api'
 import { client } from 'web-client'
 import { useTask } from 'vue-concurrency'
-import { useStore, useRouter } from '../../composables'
+import { useStore, useRouter } from 'web-pkg/src/composables'
 import marked from 'marked'
 import { arrayBuffToB64 } from '../../helpers/commonUtil'
 import axios from 'axios'
+import MixinAccessibleBreadcrumb from '../../mixins/accessibleBreadcrumb'
+import { bus } from 'web-pkg/src/instance'
 
 export default {
   components: {
@@ -59,6 +56,7 @@ export default {
     ListLoader,
     NotFoundMessage
   },
+  mixins: [MixinAccessibleBreadcrumb],
   setup() {
     const router = useRouter()
     const store = useStore()
@@ -85,7 +83,16 @@ export default {
           Authorization: `Bearer ${ref.getToken}`
         }
       })
+
+      if (ref.markdownResizeObserver) {
+        ref.markdownResizeObserver.unobserve(ref.$refs.markdownContainer)
+      }
+
       markdownContent.value = marked.parse(response.data)
+
+      if (markdownContent.value) {
+        ref.markdownResizeObserver.observe(ref.$refs.markdownContainer)
+      }
     })
     const loadImageTask = useTask(function* (signal, ref) {
       const imageEntry = space.value?.special?.find((el) => el?.specialFolder?.name === 'image')
@@ -104,7 +111,11 @@ export default {
       imageContent.value = arrayBuffToB64(response.data)
     })
 
-    loadSpaceTask.perform()
+    const loadResourcesTask = useTask(function* (signal, ref) {
+      yield loadSpaceTask.perform(ref)
+      loadReadmeTask.perform(ref)
+      loadImageTask.perform(ref)
+    })
 
     return {
       space,
@@ -112,7 +123,8 @@ export default {
       loadImageTask,
       loadReadmeTask,
       markdownContent,
-      imageContent
+      imageContent,
+      loadResourcesTask
     }
   },
   data: function () {
@@ -120,7 +132,7 @@ export default {
       markdownCollapsed: true,
       markdownContainerCollapsedClass: 'collapsed',
       showMarkdownCollapse: false,
-      markdownResizeObserver: null,
+      markdownResizeObserver: new ResizeObserver(this.onMarkdownResize),
       isEmpty: true
     }
   },
@@ -135,15 +147,16 @@ export default {
     }
   },
   async mounted() {
-    await this.loadSpaceTask.last
-    await this.loadReadmeTask.perform(this)
-    await this.loadImageTask.perform(this)
+    await this.loadResourcesTask.perform(this)
+
     document.title = `${this.space.name} - ${this.$route.meta.title}`
+    this.$route.params.name = this.space.name
 
-    if (this.markdownContent) {
-      this.markdownResizeObserver = new ResizeObserver(this.onMarkdownResize)
-      this.markdownResizeObserver.observe(this.$refs.markdownContainer)
-    }
+    const loadSpaceEventToken = bus.subscribe('app.files.list.load', (path) => {
+      this.loadResourcesTask.perform(this)
+    })
+
+    this.$on('beforeDestroy', () => bus.unsubscribe('app.files.list.load', loadSpaceEventToken))
   },
   beforeDestroy() {
     this.markdownResizeObserver.unobserve(this.$refs.markdownContainer)
@@ -154,6 +167,10 @@ export default {
       return this.$refs.markdownContainer.classList.toggle(this.markdownContainerCollapsedClass)
     },
     onMarkdownResize() {
+      if (!this.$refs.markdownContainer) {
+        return
+      }
+
       this.$refs.markdownContainer.classList.remove(this.markdownContainerCollapsedClass)
       const markdownContainerHeight = this.$refs.markdownContainer.offsetHeight
 
@@ -174,7 +191,7 @@ export default {
 <style lang="scss">
 .space-overview {
   &-image {
-    border-radius: 5px;
+    border-radius: 10px;
     max-height: 250px;
   }
 
diff --git a/packages/web-app-files/src/views/spaces/Projects.vue b/packages/web-app-files/src/views/spaces/Projects.vue
index aedb2e13e40..75271598dec 100644
--- a/packages/web-app-files/src/views/spaces/Projects.vue
+++ b/packages/web-app-files/src/views/spaces/Projects.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="oc-p-s">
-    <h2 v-text="$gettext('Spaces')" />
+    <h2 class="oc-mt-rm" v-text="$gettext('Spaces')" />
     <span v-text="$gettext('Access all project related files in one place.')" />
     <a href="#" v-text="$gettext('Learn more about spaces.')" />
     <h3 v-text="$gettext('Your spaces')" />
@@ -31,7 +31,7 @@
           <div v-for="space in spaces" :key="space.id" class="oc-mb-m">
             <span class="spaces-list-card oc-border oc-card oc-card-default">
               <span class="oc-card-media-top oc-border-b">
-                <router-link v-if="!loadImagesTask.isRunning" :to="getSpaceProjectRoute(space.id)">
+                <router-link v-if="!loadImagesTask.isRunning" :to="getSpaceProjectRoute(space)">
                   <img
                     v-if="imageContentObject[space.id]"
                     class="space-image"
@@ -43,7 +43,7 @@
               </span>
               <span class="oc-card-body">
                 <router-link
-                  :to="getSpaceProjectRoute(space.id)"
+                  :to="getSpaceProjectRoute(space)"
                   class="oc-card-title"
                   v-text="space.name"
                 />
@@ -66,6 +66,8 @@ import { useTask } from 'vue-concurrency'
 import { createLocationSpaces } from '../../router'
 import axios from 'axios'
 import { arrayBuffToB64 } from '../../helpers/commonUtil'
+import { bus } from 'web-pkg/src/instance'
+import { mapMutations } from 'vuex'
 
 export default {
   components: {
@@ -85,8 +87,6 @@ export default {
         .sort((a, b) => a.name.localeCompare(b.name))
     })
 
-    loadSpacesTask.perform()
-
     const loadImageTask = useTask(function* (signal, { spaceId, webDavUrl, token }) {
       const response = yield axios.get(webDavUrl, {
         headers: {
@@ -103,7 +103,7 @@ export default {
         const imageEntry = space?.special?.find((el) => el?.specialFolder?.name === 'image')
 
         if (!imageEntry) {
-          return
+          continue
         }
 
         yield loadImageTask.perform({
@@ -114,21 +114,36 @@ export default {
       }
     })
 
+    const loadResourcesTask = useTask(function* (signal, ref) {
+      ref.SET_CURRENT_FOLDER(null)
+
+      yield ref.loadSpacesTask.perform(ref)
+      yield ref.loadImagesTask.perform(ref)
+    })
+
     return {
       spaces,
       loadSpacesTask,
       loadImagesTask,
+      loadResourcesTask,
       imageContentObject
     }
   },
-  async mounted() {
-    await this.loadSpacesTask.last
-    await this.loadImagesTask.perform(this)
+  mounted() {
+    this.loadResourcesTask.perform(this)
+
+    const loadSpacesEventToken = bus.subscribe('app.files.list.load', (path) => {
+      this.loadResourcesTask.perform(this)
+    })
+
+    this.$on('beforeDestroy', () => bus.unsubscribe('app.files.list.load', loadSpacesEventToken))
   },
   methods: {
-    getSpaceProjectRoute(spaceId) {
+    ...mapMutations('Files', ['SET_CURRENT_FOLDER']),
+
+    getSpaceProjectRoute({ id, name }) {
       return createLocationSpaces('files-spaces-project', {
-        params: { spaceId }
+        params: { spaceId: id, name }
       })
     }
   }
@@ -149,11 +164,18 @@ export default {
     display: inline-block;
     width: 100%;
     background-color: var(--oc-color-background-muted);
-    max-height: 150px;
+    height: 200px;
+  }
+  .oc-card-media-top a {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 100%;
   }
   .space-image {
-    max-width: 100%;
-    height: auto;
+    width: 100%;
+    height: 200px;
+    object-fit: cover;
   }
 }
 </style>