diff --git a/package-lock.json b/package-lock.json
index 0309243ac..4aaf28092 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"raw-loader": "4.0.2",
"react": "17.0.2",
"react-dom": "17.0.2",
+ "react-helmet": "6.1.0",
"react-redux": "7.2.9",
"react-router": "6.18.0",
"react-router-dom": "6.18.0",
@@ -17905,6 +17906,25 @@
"react": ">=0.14.0"
}
},
+ "node_modules/react-helmet": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
+ "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
+ "dependencies": {
+ "object-assign": "^4.1.1",
+ "prop-types": "^15.7.2",
+ "react-fast-compare": "^3.1.1",
+ "react-side-effect": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.3.0"
+ }
+ },
+ "node_modules/react-helmet/node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
+ },
"node_modules/react-intl": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.2.tgz",
@@ -18141,6 +18161,14 @@
"react-dom": ">=16.8"
}
},
+ "node_modules/react-side-effect": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz",
+ "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==",
+ "peerDependencies": {
+ "react": "^16.3.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-style-singleton": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
diff --git a/package.json b/package.json
index 10f035b73..001fcc3cf 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,7 @@
"raw-loader": "4.0.2",
"react": "17.0.2",
"react-dom": "17.0.2",
+ "react-helmet": "6.1.0",
"react-redux": "7.2.9",
"react-router": "6.18.0",
"react-router-dom": "6.18.0",
diff --git a/src/components/Head/Head.jsx b/src/components/Head/Head.jsx
new file mode 100644
index 000000000..2cda3b1db
--- /dev/null
+++ b/src/components/Head/Head.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+import { Helmet } from 'react-helmet';
+
+import { getConfig } from '@edx/frontend-platform';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+
+import messages from './messages';
+
+const Head = ({ intl }) => (
+
+
+ {intl.formatMessage(messages['discussions.page.title'], { siteName: getConfig().SITE_NAME })}
+
+
+
+);
+
+Head.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(Head);
diff --git a/src/components/Head/Head.test.jsx b/src/components/Head/Head.test.jsx
new file mode 100644
index 000000000..df1eea12e
--- /dev/null
+++ b/src/components/Head/Head.test.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+import { render } from '@testing-library/react';
+import { Helmet } from 'react-helmet';
+
+import { getConfig } from '@edx/frontend-platform';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
+
+import Head from './Head';
+
+describe('Head', () => {
+ const props = {};
+ it('should match render title tag and favicon with the site configuration values', () => {
+ render();
+ const helmet = Helmet.peek();
+ expect(helmet.title).toEqual(`Discussions | ${getConfig().SITE_NAME}`);
+ expect(helmet.linkTags[0].rel).toEqual('shortcut icon');
+ expect(helmet.linkTags[0].href).toEqual(getConfig().FAVICON_URL);
+ });
+});
diff --git a/src/components/Head/messages.js b/src/components/Head/messages.js
new file mode 100644
index 000000000..8c81b3c0d
--- /dev/null
+++ b/src/components/Head/messages.js
@@ -0,0 +1,11 @@
+import { defineMessages } from '@edx/frontend-platform/i18n';
+
+const messages = defineMessages({
+ 'discussions.page.title': {
+ id: 'discussions.page.title',
+ defaultMessage: 'Discussions | {siteName}',
+ description: 'Title tag',
+ },
+});
+
+export default messages;
diff --git a/src/index.jsx b/src/index.jsx
index 8c5737b01..9ad349991 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -10,16 +10,17 @@ import {
} from '@edx/frontend-platform';
import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
+import Head from './components/Head/Head';
import { DiscussionsHome } from './discussions';
import messages from './i18n';
import store from './store';
-import './assets/favicon.ico';
import './index.scss';
subscribe(APP_READY, () => {
ReactDOM.render(
+
,
document.getElementById('root'),