diff --git a/__tests__/src/components/WindowTopBarTitle.test.js b/__tests__/src/components/WindowTopBarTitle.test.js
index fb7b84d0affc414efaae0bfdfe37188171d8df1f..f3b01c10e2b080db1f03ce955ee04ebf250e02f8 100644
--- a/__tests__/src/components/WindowTopBarTitle.test.js
+++ b/__tests__/src/components/WindowTopBarTitle.test.js
@@ -1,7 +1,6 @@
 import React from 'react';
 import { shallow } from 'enzyme';
-
-import Typography from '@material-ui/core/Typography';
+import Skeleton from '@material-ui/lab/Skeleton';
 
 import { WindowTopBarTitle } from '../../../src/components/WindowTopBarTitle';
 
@@ -20,16 +19,26 @@ function createWrapper(props) {
 describe('WindowTopBarTitle', () => {
   it('renders all needed elements', () => {
     const wrapper = createWrapper();
-    expect(wrapper.find(Typography).length).toBe(1);
+    expect(wrapper.find('TitleTypography').length).toBe(1);
   });
 
   it('passes correct props to <Typography/>', () => {
     const wrapper = createWrapper();
-    expect(wrapper.find(Typography).first().render().text()).toBe('awesome manifest');
+    expect(wrapper.find('TitleTypography').first().render().text()).toBe('awesome manifest');
+  });
+
+  it('renders a Skeleton when loading', () => {
+    const wrapper = createWrapper({ isFetching: true });
+    expect(wrapper.find('TitleTypography').dive().find(Skeleton).length).toBe(1);
+  });
+
+  it('renders an error', () => {
+    const wrapper = createWrapper({ error: 'some error message' });
+    expect(wrapper.find('TitleTypography').render().text()).toBe('some error message');
   });
 
   it('title is configurable', () => {
-    expect(createWrapper({ hideWindowTitle: true }).find(Typography).length).toEqual(0);
+    expect(createWrapper({ hideWindowTitle: true }).find('TitleTypography').length).toEqual(0);
     expect(createWrapper({ hideWindowTitle: true }).find('div').length).toEqual(1);
   });
 });
diff --git a/__tests__/src/selectors/manifests.test.js b/__tests__/src/selectors/manifests.test.js
index 15cda397e94ed6ef81d603eff1ec68e71340f191..f59ed884f65486ccd5efaccdcb8e8ad00205d200 100644
--- a/__tests__/src/selectors/manifests.test.js
+++ b/__tests__/src/selectors/manifests.test.js
@@ -13,6 +13,7 @@ import {
   getManifestLocale,
   getDestructuredMetadata,
   getManifest,
+  getManifestStatus,
   getManifestLogo,
   getManifestCanvases,
   getManifestDescription,
@@ -54,7 +55,6 @@ describe('getManifest()', () => {
     expect(received).toEqual(expected);
   });
 
-
   it('should return the manifest of a certain window', () => {
     const received = getManifest(state, { windowId: 'a' });
     const expected = { id: 'x' };
@@ -77,6 +77,26 @@ describe('getManifest()', () => {
   });
 });
 
+describe('getManifestStatus', () => {
+  const state = {
+    manifests: {
+      x: { id: 'x' },
+    },
+  };
+
+  it('returns the manifest of a certain id', () => {
+    const received = getManifestStatus(state, { manifestId: 'x' });
+    const expected = { id: 'x' };
+    expect(received).toEqual(expected);
+  });
+
+  it('returns a placeholder', () => {
+    const received = getManifestStatus(state, { manifestId: 'y' });
+    const expected = { missing: true };
+    expect(received).toEqual(expected);
+  });
+});
+
 describe('getManifestoInstance', () => {
   it('creates a manifesto instance', () => {
     const state = { manifests: { x: { json: manifestFixture019 } } };
diff --git a/src/components/WindowTopBarTitle.js b/src/components/WindowTopBarTitle.js
index 29f042b3c469dc6b2b777d7d749039ad7a5ad052..ed36e8aff8847d47fe33e70b65f489d6a7bb01e2 100644
--- a/src/components/WindowTopBarTitle.js
+++ b/src/components/WindowTopBarTitle.js
@@ -1,6 +1,8 @@
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
 import Typography from '@material-ui/core/Typography';
+import Skeleton from '@material-ui/lab/Skeleton';
+import ErrorIcon from '@material-ui/icons/ErrorOutlineSharp';
 
 /**
  * WindowTopBarTitle
@@ -12,16 +14,39 @@ export class WindowTopBarTitle extends Component {
    */
   render() {
     const {
-      classes, hideWindowTitle, manifestTitle,
+      classes, error, hideWindowTitle, isFetching, manifestTitle,
     } = this.props;
+
+    /** */
+    const TitleTypography = props => (
+      <Typography variant="h2" noWrap color="inherit" className={classes.title} {...props}>
+        {props.children}
+      </Typography>
+    );
+
     let title = null;
-    if (hideWindowTitle) {
+    if (isFetching) {
+      title = (
+        <TitleTypography>
+          <Skeleton variant="text" />
+        </TitleTypography>
+      );
+    } else if (error) {
+      title = (
+        <>
+          <ErrorIcon color="error" />
+          <TitleTypography color="textSecondary">
+            {error}
+          </TitleTypography>
+        </>
+      );
+    } else if (hideWindowTitle) {
       title = (<div className={classes.title} />);
     } else {
       title = (
-        <Typography variant="h2" noWrap color="inherit" className={classes.title}>
+        <TitleTypography>
           {manifestTitle}
-        </Typography>
+        </TitleTypography>
       );
     }
     return title;
@@ -30,11 +55,15 @@ export class WindowTopBarTitle extends Component {
 
 WindowTopBarTitle.propTypes = {
   classes: PropTypes.objectOf(PropTypes.string).isRequired,
+  error: PropTypes.string,
   hideWindowTitle: PropTypes.bool,
+  isFetching: PropTypes.bool,
   manifestTitle: PropTypes.string,
 };
 
 WindowTopBarTitle.defaultProps = {
+  error: null,
   hideWindowTitle: false,
+  isFetching: false,
   manifestTitle: '',
 };
diff --git a/src/containers/WindowTopBar.js b/src/containers/WindowTopBar.js
index a48b7a7f00f7869a318e091ccc93c6d5429013b4..967f91e185773ffb063ed43fdc414edccc127aeb 100644
--- a/src/containers/WindowTopBar.js
+++ b/src/containers/WindowTopBar.js
@@ -4,7 +4,7 @@ import { withTranslation } from 'react-i18next';
 import { withStyles } from '@material-ui/core';
 import { withPlugins } from '../extend/withPlugins';
 import * as actions from '../state/actions';
-import { getManifestTitle, getWindow } from '../state/selectors';
+import { getWindow } from '../state/selectors';
 import { WindowTopBar } from '../components/WindowTopBar';
 
 /** mapStateToProps */
@@ -15,7 +15,6 @@ const mapStateToProps = (state, { windowId }) => ({
   allowTopMenuButton: state.config.window.allowTopMenuButton,
   allowWindowSideBar: state.config.window.allowWindowSideBar,
   focused: state.workspace.focusedWindowId === windowId,
-  manifestTitle: getManifestTitle(state, { windowId }),
   maximized: (getWindow(state, { windowId }) || {}).maximized,
 });
 
diff --git a/src/containers/WindowTopBarTitle.js b/src/containers/WindowTopBarTitle.js
index e17fecfa9c73df6d925a927280bb29c328ed7a7d..e1c65661119c323eabbd78cb9ef1fe2c792bec71 100644
--- a/src/containers/WindowTopBarTitle.js
+++ b/src/containers/WindowTopBarTitle.js
@@ -3,12 +3,14 @@ import { connect } from 'react-redux';
 import { withTranslation } from 'react-i18next';
 import { withStyles } from '@material-ui/core';
 import { withPlugins } from '../extend/withPlugins';
-import { getManifestTitle } from '../state/selectors';
+import { getManifestStatus, getManifestTitle } from '../state/selectors';
 import { WindowTopBarTitle } from '../components/WindowTopBarTitle';
 
 /** mapStateToProps */
 const mapStateToProps = (state, { windowId }) => ({
+  error: getManifestStatus(state, { windowId }).error,
   hideWindowTitle: state.config.window.hideWindowTitle,
+  isFetching: getManifestStatus(state, { windowId }).isFetching,
   manifestTitle: getManifestTitle(state, { windowId }),
 });
 
diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js
index 39e45811c90197da3a68c9a96c111f732f8d08b0..373aef7ce42b453c4a8fc7e86008cbb733e1b8cd 100644
--- a/src/state/selectors/manifests.js
+++ b/src/state/selectors/manifests.js
@@ -19,6 +19,12 @@ export function getManifest(state, { manifestId, windowId }) {
   ];
 }
 
+/** Convenience selector to get a manifest (or placeholder) */
+export const getManifestStatus = createSelector(
+  [getManifest],
+  manifest => manifest || { missing: true },
+);
+
 /** Instantiate a manifesto instance */
 export const getManifestoInstance = createCachedSelector(
   getManifest,