diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index 8a89fb1324cc5e6186cf32813a5577844c5a9f91..ffc38e07f9fa5a5109d53e0005c2ce3c8209c91b 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -4,7 +4,7 @@ import {compose} from 'redux';
 import {connect} from 'react-redux';
 import ReactModal from 'react-modal';
 import VM from 'scratch-vm';
-import {injectIntl, intlShape} from 'react-intl';
+import {defineMessages, injectIntl, intlShape} from 'react-intl';
 
 import ErrorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
 import {openExtensionLibrary} from '../reducers/modals';
@@ -25,14 +25,22 @@ import {
 } from '../reducers/modals';
 
 import FontLoaderHOC from '../lib/font-loader-hoc.jsx';
+import LocalizationHOC from '../lib/localization-hoc.jsx';
 import ProjectFetcherHOC from '../lib/project-fetcher-hoc.jsx';
 import ProjectSaverHOC from '../lib/project-saver-hoc.jsx';
 import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
 import vmManagerHOC from '../lib/vm-manager-hoc.jsx';
-import {defaultProjectTitleMessages} from '../reducers/project-title';
 
 import GUIComponent from '../components/gui/gui.jsx';
 
+const messages = defineMessages({
+    defaultProjectTitle: {
+        id: 'gui.gui.defaultProjectTitle',
+        description: 'Default title for project',
+        defaultMessage: 'Scratch Project'
+    }
+});
+
 class GUI extends React.Component {
     componentDidMount () {
         this.setReduxTitle(this.props.projectTitle);
@@ -48,7 +56,7 @@ class GUI extends React.Component {
     setReduxTitle (newTitle) {
         if (newTitle === null || typeof newTitle === 'undefined') {
             this.props.onUpdateReduxProjectTitle(
-                this.props.intl.formatMessage(defaultProjectTitleMessages.defaultProjectTitle)
+                this.props.intl.formatMessage(messages.defaultProjectTitle)
             );
         } else {
             this.props.onUpdateReduxProjectTitle(newTitle);
@@ -163,6 +171,7 @@ const ConnectedGUI = injectIntl(connect(
 // the hierarchy of HOC constructor calls clearer here; it has nothing to do with redux's
 // ability to compose reducers.
 const WrappedGui = compose(
+    LocalizationHOC,
     ErrorBoundaryHOC('Top Level App'),
     FontLoaderHOC,
     ProjectFetcherHOC,
diff --git a/src/lib/app-state-hoc.jsx b/src/lib/app-state-hoc.jsx
index 93d97180ef38526ac05feaf019338aa32ed4496b..3c9eb9266d115b38d2eb0e791131c001ed078de1 100644
--- a/src/lib/app-state-hoc.jsx
+++ b/src/lib/app-state-hoc.jsx
@@ -2,7 +2,6 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import {Provider} from 'react-redux';
 import {createStore, combineReducers, compose} from 'redux';
-import ConnectedIntlProvider from './connected-intl-provider.jsx';
 
 import localesReducer, {initLocale, localesInitialState} from '../reducers/locales';
 
@@ -108,9 +107,7 @@ const AppStateHOC = function (WrappedComponent, localesOnly) {
             } = this.props;
             return (
                 <Provider store={this.store}>
-                    <ConnectedIntlProvider>
-                        <WrappedComponent {...componentProps} />
-                    </ConnectedIntlProvider>
+                    <WrappedComponent {...componentProps} />
                 </Provider>
             );
         }
diff --git a/src/lib/localization-hoc.jsx b/src/lib/localization-hoc.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..2df5158e838d95f3ad7c649178f7843a2690d253
--- /dev/null
+++ b/src/lib/localization-hoc.jsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {connect} from 'react-redux';
+
+import ConnectedIntlProvider from './connected-intl-provider.jsx';
+
+/*
+ * Higher Order Component to provide localiztion state. Creates a nested IntlProvider
+ * to handle Gui intl context. The component accepts an onSetLanguage callback that is
+ * called when the locale chagnes.
+ * @param {React.Component} WrappedComponent - component to provide state for
+ * @returns {React.Component} component with intl state provided from redux
+ */
+const LocalizationHOC = function (WrappedComponent) {
+    class LocalizationWrapper extends React.Component {
+        componentDidUpdate (prevProps) {
+            if (prevProps.locale !== this.props.locale) {
+                this.props.onSetLanguage(this.props.locale);
+            }
+        }
+        render () {
+            const {
+                locale, // eslint-disable-line no-unused-vars
+                onSetLanguage, // eslint-disable-line no-unused-vars
+                ...componentProps
+            } = this.props;
+            return (
+                <ConnectedIntlProvider>
+                    <WrappedComponent {...componentProps} />
+                </ConnectedIntlProvider>
+            );
+        }
+    }
+    LocalizationWrapper.propTypes = {
+        locale: PropTypes.string,
+        onSetLanguage: PropTypes.func
+    };
+
+    LocalizationWrapper.defaultProps = {
+        onSetLanguage: () => {}
+    };
+
+    const mapStateToProps = state => ({
+        locale: state.locales.locale
+    });
+
+    const mapDispatchToProps = () => ({});
+
+    return connect(
+        mapStateToProps,
+        mapDispatchToProps
+    )(LocalizationWrapper);
+};
+
+export default LocalizationHOC;
diff --git a/src/lib/titled-hoc.jsx b/src/lib/titled-hoc.jsx
index 2cc3e59209ead4289927f52d591096a615baf7bf..fea6a9388a812868114f9440ab5bafada9f85c8e 100644
--- a/src/lib/titled-hoc.jsx
+++ b/src/lib/titled-hoc.jsx
@@ -1,7 +1,5 @@
 import React from 'react';
 import bindAll from 'lodash.bindall';
-import {intlShape, injectIntl} from 'react-intl';
-import {defaultProjectTitleMessages} from '../reducers/project-title';
 
 /* Higher Order Component to get and set the project title
  * @param {React.Component} WrappedComponent component to receive project title related props
@@ -15,34 +13,24 @@ const TitledHOC = function (WrappedComponent) {
                 'handleUpdateProjectTitle'
             ]);
             this.state = {
-                projectTitle: this.props.intl.formatMessage(defaultProjectTitleMessages.defaultProjectTitle)
+                projectTitle: null
             };
         }
         handleUpdateProjectTitle (newTitle) {
             this.setState({projectTitle: newTitle});
         }
         render () {
-            const {
-                /* eslint-disable no-unused-vars */
-                intl,
-                /* eslint-enable no-unused-vars */
-                ...componentProps
-            } = this.props;
             return (
                 <WrappedComponent
                     projectTitle={this.state.projectTitle}
                     onUpdateProjectTitle={this.handleUpdateProjectTitle}
-                    {...componentProps}
+                    {...this.props}
                 />
             );
         }
     }
 
-    TitledComponent.propTypes = {
-        intl: intlShape.isRequired
-    };
-
-    return injectIntl(TitledComponent);
+    return TitledComponent;
 };
 
 export {
diff --git a/src/reducers/project-title.js b/src/reducers/project-title.js
index 389687ceb10b23c8f59964abdf8b78bb48c2fb6f..09bf6c4eab417e626b8a719326ac685c25d46cdd 100644
--- a/src/reducers/project-title.js
+++ b/src/reducers/project-title.js
@@ -1,19 +1,9 @@
-import {defineMessages} from 'react-intl';
-
 const SET_PROJECT_TITLE = 'projectTitle/SET_PROJECT_TITLE';
 
 // we are initializing to a blank string instead of an actual title,
 // because it would be hard to localize here
 const initialState = '';
 
-const defaultProjectTitleMessages = defineMessages({
-    defaultProjectTitle: {
-        id: 'gui.gui.defaultProjectTitle',
-        description: 'Default title for project',
-        defaultMessage: 'Scratch Project'
-    }
-});
-
 const reducer = function (state, action) {
     if (typeof state === 'undefined') state = initialState;
     switch (action.type) {
@@ -31,6 +21,5 @@ const setProjectTitle = title => ({
 export {
     reducer as default,
     initialState as projectTitleInitialState,
-    defaultProjectTitleMessages,
     setProjectTitle
 };