11import type { Control , ControlMode } from './core/useACL' ;
22import type { IndexRouteObject , NonIndexRouteObject , RouteMatch } from 'react-router-dom' ;
33
4- import { nth } from 'lodash' ;
5- import React from 'react' ;
4+ import { isFunction , isUndefined , nth } from 'lodash' ;
5+ import React , { useEffect } from 'react' ;
66import { useTranslation } from 'react-i18next' ;
77import { matchRoutes , Navigate , renderMatches , useLocation } from 'react-router-dom' ;
88
99import { useACLGuard , useTokenGuard } from './Routes.guard' ;
1010import { AppFCPLoader } from './components' ;
1111import { ROUTES_ACL } from './config/acl' ;
12- import { LOGIN_PATH } from './config/other' ;
13- import { usePageTitle } from './hooks' ;
12+ import { APP_NAME , LOGIN_PATH } from './config/other' ;
1413import AppHomeRoute from './routes/Home' ;
1514import AppExceptionRoute from './routes/exception/Exception' ;
1615import AppLayout from './routes/layout/Layout' ;
@@ -25,8 +24,20 @@ const ROUTES = {
2524 '/test/http' : React . lazy ( ( ) => import ( './routes/test/http/Http' ) ) ,
2625} ;
2726
27+ const TITLE_CONFIG : {
28+ default : string ;
29+ separator : string ;
30+ prefix ?: string ;
31+ suffix ?: string ;
32+ } = {
33+ default : APP_NAME ,
34+ separator : ' - ' ,
35+ suffix : APP_NAME ,
36+ } ;
37+
2838export interface RouteStateContextData {
2939 matchRoutes : RouteMatch < string , RouteItem > [ ] | null ;
40+ title ?: string ;
3041}
3142export const RouteStateContext = React . createContext < RouteStateContextData > ( {
3243 matchRoutes : null ,
@@ -35,7 +46,7 @@ export const RouteStateContext = React.createContext<RouteStateContextData>({
3546export type CanActivateFn = ( route : RouteItem ) => true | React . ReactElement ;
3647
3748export interface RouteData {
38- title ?: string ;
49+ title ?: string | ( ( params : any ) => string ) ;
3950 acl ?:
4051 | {
4152 control : Control | Control [ ] ;
@@ -173,6 +184,9 @@ export const AppRoutes = React.memo(() => {
173184 {
174185 path : '/exception/:status' ,
175186 element : < AppExceptionRoute /> ,
187+ data : {
188+ title : ( params ) => params . status ,
189+ } ,
176190 } ,
177191 {
178192 path : '*' ,
@@ -206,13 +220,37 @@ export const AppRoutes = React.memo(() => {
206220 return renderMatches ( matches ) ;
207221 } ) ( ) ;
208222
209- const { title } = nth ( matches , - 1 ) ?. route . data ?? { } ;
210- usePageTitle ( title ) ;
223+ const title = ( ( ) => {
224+ if ( matches ) {
225+ const match = nth ( matches , - 1 ) ! ;
226+ const { title } = match . route . data ?? { } ;
227+ return isFunction ( title ) ? title ( match . params ) : title ;
228+ }
229+ return undefined ;
230+ } ) ( ) ;
231+ useEffect ( ( ) => {
232+ if ( isUndefined ( title ) ) {
233+ document . title = TITLE_CONFIG . default ;
234+ } else {
235+ const arr = [ title ] ;
236+ if ( TITLE_CONFIG . prefix ) {
237+ arr . unshift ( TITLE_CONFIG . prefix ) ;
238+ }
239+ if ( TITLE_CONFIG . suffix ) {
240+ arr . push ( TITLE_CONFIG . suffix ) ;
241+ }
242+ document . title = arr . join ( TITLE_CONFIG . separator ?? ' - ' ) ;
243+ }
244+ return ( ) => {
245+ document . title = TITLE_CONFIG . default ;
246+ } ;
247+ } ) ;
211248
212249 return (
213250 < RouteStateContext . Provider
214251 value = { {
215252 matchRoutes : matches ,
253+ title,
216254 } }
217255 >
218256 { element }
0 commit comments