feat: show page name in document title using React Helmet (#3229)

* feat: show page name in document title using React Helmet

* fix: add translation support for page titles

* feat: title is updated

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Mustajab Ikram 2023-08-02 15:14:15 +05:30 committed by GitHub
parent 562621a117
commit f1fff4ca0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 13 deletions

View File

@ -76,6 +76,7 @@
"react-drag-listview": "2.0.0",
"react-force-graph": "^1.41.0",
"react-grid-layout": "^1.3.4",
"react-helmet-async": "1.3.0",
"react-i18next": "^11.16.1",
"react-intersection-observer": "9.4.1",
"react-query": "^3.34.19",
@ -140,6 +141,7 @@
"@types/react-addons-update": "0.14.21",
"@types/react-dom": "18.0.10",
"@types/react-grid-layout": "^1.1.2",
"@types/react-helmet-async": "1.0.3",
"@types/react-redux": "^7.1.11",
"@types/react-resizable": "3.0.3",
"@types/react-router-dom": "^5.1.6",

View File

@ -0,0 +1,36 @@
{
"SIGN_UP": "SigNoz | Sign Up",
"LOGIN": "SigNoz | Login",
"SERVICE_METRICS": "SigNoz | Service Metrics",
"SERVICE_MAP": "SigNoz | Service Map",
"TRACE": "SigNoz | Trace",
"TRACE_DETAIL": "SigNoz | Trace Detail",
"TRACES_EXPLORER": "SigNoz | Traces Explorer",
"SETTINGS": "SigNoz | Settings",
"INSTRUMENTATION": "SigNoz | Get Started",
"USAGE_EXPLORER": "SigNoz | Usage Explorer",
"APPLICATION": "SigNoz | Home",
"ALL_DASHBOARD": "SigNoz | All Dashboards",
"DASHBOARD": "SigNoz | Dashboard",
"DASHBOARD_WIDGET": "SigNoz | Dashboard Widget",
"EDIT_ALERTS": "SigNoz | Edit Alerts",
"LIST_ALL_ALERT": "SigNoz | All Alerts",
"ALERTS_NEW": "SigNoz | New Alert",
"ALL_CHANNELS": "SigNoz | All Channels",
"CHANNELS_NEW": "SigNoz | New Channel",
"CHANNELS_EDIT": "SigNoz | Edit Channel",
"ALL_ERROR": "SigNoz | All Errors",
"ERROR_DETAIL": "SigNoz | Error Detail",
"VERSION": "SigNoz | Version",
"MY_SETTINGS": "SigNoz | My Settings",
"ORG_SETTINGS": "SigNoz | Organization Settings",
"SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong",
"UN_AUTHORIZED": "SigNoz | Unauthorized",
"NOT_FOUND": "SigNoz | Page Not Found",
"LOGS": "SigNoz | Logs",
"LOGS_EXPLORER": "SigNoz | Logs Explorer",
"HOME_PAGE": "Open source Observability Platform | SigNoz",
"PASSWORD_RESET": "SigNoz | Password Reset",
"LIST_LICENSES": "SigNoz | List of Licenses",
"DEFAULT": "Open source Observability Platform | SigNoz"
}

View File

@ -0,0 +1,36 @@
{
"SIGN_UP": "SigNoz | Sign Up",
"LOGIN": "SigNoz | Login",
"SERVICE_METRICS": "SigNoz | Service Metrics",
"SERVICE_MAP": "SigNoz | Service Map",
"TRACE": "SigNoz | Trace",
"TRACE_DETAIL": "SigNoz | Trace Detail",
"TRACES_EXPLORER": "SigNoz | Traces Explorer",
"SETTINGS": "SigNoz | Settings",
"INSTRUMENTATION": "SigNoz | Get Started",
"USAGE_EXPLORER": "SigNoz | Usage Explorer",
"APPLICATION": "SigNoz | Home",
"ALL_DASHBOARD": "SigNoz | All Dashboards",
"DASHBOARD": "SigNoz | Dashboard",
"DASHBOARD_WIDGET": "SigNoz | Dashboard Widget",
"EDIT_ALERTS": "SigNoz | Edit Alerts",
"LIST_ALL_ALERT": "SigNoz | All Alerts",
"ALERTS_NEW": "SigNoz | New Alert",
"ALL_CHANNELS": "SigNoz | All Channels",
"CHANNELS_NEW": "SigNoz | New Channel",
"CHANNELS_EDIT": "SigNoz | Edit Channel",
"ALL_ERROR": "SigNoz | All Errors",
"ERROR_DETAIL": "SigNoz | Error Detail",
"VERSION": "SigNoz | Version",
"MY_SETTINGS": "SigNoz | My Settings",
"ORG_SETTINGS": "SigNoz | Organization Settings",
"SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong",
"UN_AUTHORIZED": "SigNoz | Unauthorized",
"NOT_FOUND": "SigNoz | Page Not Found",
"LOGS": "SigNoz | Logs",
"LOGS_EXPLORER": "SigNoz | Logs Explorer",
"HOME_PAGE": "Open source Observability Platform | SigNoz",
"PASSWORD_RESET": "SigNoz | Password Reset",
"LIST_LICENSES": "SigNoz | List of Licenses",
"DEFAULT": "Open source Observability Platform | SigNoz"
}

View File

@ -6,7 +6,8 @@ import Header from 'container/Header';
import SideNav from 'container/SideNav';
import TopNav from 'container/TopNav';
import { useNotifications } from 'hooks/useNotifications';
import { ReactNode, useEffect, useRef } from 'react';
import { ReactNode, useEffect, useMemo, useRef } from 'react';
import { Helmet } from 'react-helmet-async';
import { useTranslation } from 'react-i18next';
import { useQueries } from 'react-query';
import { useDispatch, useSelector } from 'react-redux';
@ -25,13 +26,14 @@ import {
import AppReducer from 'types/reducer/app';
import { ChildrenContainer, Layout } from './styles';
import { getRouteKey } from './utils';
function AppLayout(props: AppLayoutProps): JSX.Element {
const { isLoggedIn, user } = useSelector<AppState, AppReducer>(
(state) => state.app,
);
const { pathname } = useLocation();
const { t } = useTranslation();
const { t } = useTranslation(['titles']);
const [
getUserVersionResponse,
@ -226,8 +228,15 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
const isToDisplayLayout = isLoggedIn;
const routeKey = useMemo(() => getRouteKey(pathname), [pathname]);
const pageTitle = t(routeKey);
return (
<Layout>
<Helmet>
<title>{pageTitle}</title>
</Helmet>
{isToDisplayLayout && <Header />}
<Layout>
{isToDisplayLayout && <SideNav />}

View File

@ -0,0 +1,9 @@
import ROUTES from 'constants/routes';
export function getRouteKey(pathname: string): string {
const [routeKey] = Object.entries(ROUTES).find(
([, value]) => value === pathname,
) || ['DEFAULT'];
return routeKey;
}

View File

@ -4,6 +4,7 @@ import './ReactI18';
import AppRoutes from 'AppRoutes';
import { ThemeProvider } from 'hooks/useDarkMode';
import { createRoot } from 'react-dom/client';
import { HelmetProvider } from 'react-helmet-async';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { Provider } from 'react-redux';
@ -28,6 +29,7 @@ if (container) {
const root = createRoot(container);
root.render(
<HelmetProvider>
<ThemeProvider>
<QueryClientProvider client={queryClient}>
<Provider store={store}>
@ -37,6 +39,7 @@ if (container) {
<ReactQueryDevtools initialIsOpen />
)}
</QueryClientProvider>
</ThemeProvider>,
</ThemeProvider>
</HelmetProvider>,
);
}

View File

@ -2350,6 +2350,13 @@
dependencies:
"@types/react" "*"
"@types/react-helmet-async@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/react-helmet-async/-/react-helmet-async-1.0.3.tgz#89d581d6cb129e5357d39d7d1b41313b20523989"
integrity sha512-DqbSuZPSHiH1l3XI/y8LbhrAGNh+Bpc9QY4MsYRM1yD4+qhax8bN4DInUMpv/tNyIdjsa+1V8XXmbRx8W5dB0w==
dependencies:
react-helmet-async "*"
"@types/react-redux@^7.1.11", "@types/react-redux@^7.1.20":
version "7.1.25"
resolved "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz"
@ -7038,6 +7045,13 @@ interpret@^2.2.0:
resolved "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz"
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
@ -8528,7 +8542,7 @@ loglevelnext@^3.0.1:
resolved "https://registry.npmjs.org/loglevelnext/-/loglevelnext-3.0.1.tgz"
integrity sha512-JpjaJhIN1reaSb26SIxDGtE0uc67gPl19OMVHrr+Ggt6b/Vy60jmCtKgQBrygAH0bhRA2nkxgDvM+8QvR8r0YA==
loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -10612,6 +10626,11 @@ react-draggable@^4.0.0, react-draggable@^4.0.3:
clsx "^1.1.1"
prop-types "^15.8.1"
react-fast-compare@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49"
integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==
react-force-graph@^1.41.0:
version "1.42.2"
resolved "https://registry.npmjs.org/react-force-graph/-/react-force-graph-1.42.2.tgz"
@ -10635,6 +10654,17 @@ react-grid-layout@^1.3.4:
react-draggable "^4.0.0"
react-resizable "^3.0.4"
react-helmet-async@*, react-helmet-async@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e"
integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==
dependencies:
"@babel/runtime" "^7.12.5"
invariant "^2.2.4"
prop-types "^15.7.2"
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"
react-hooks-testing-library@0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/react-hooks-testing-library/-/react-hooks-testing-library-0.6.0.tgz"