72 lines
2.3 KiB
Plaintext
72 lines
2.3 KiB
Plaintext
---
|
|
title: Title portals
|
|
description: Mount page titles into an application shell while retaining an SSR fallback.
|
|
order: 20
|
|
toc:
|
|
- id: info-resolver
|
|
title: Page information resolver
|
|
- id: managed-target
|
|
title: Managed title target
|
|
- id: fallback
|
|
title: Fallback
|
|
- id: nested-managers
|
|
title: Nested managers
|
|
---
|
|
|
|
## Page information resolver {#info-resolver}
|
|
|
|
`PagesManager.getPageInfo` connects route or layout metadata to page components. It receives the optional `Partial<PageInfo>` from `PageContainer` and returns a normalized `PageInfo`, or `undefined` when no managed information is available:
|
|
|
|
```tsx
|
|
<PagesManager
|
|
getPageInfo={(info) => ({
|
|
breadcrumb: info?.breadcrumb ?? routeMetadata.breadcrumb,
|
|
description: info?.description ?? routeMetadata.description,
|
|
subtitle: info?.subtitle ?? routeMetadata.subtitle,
|
|
title: info?.title ?? routeMetadata.title,
|
|
})}
|
|
>
|
|
<Outlet />
|
|
</PagesManager>
|
|
```
|
|
|
|
If the resolver returns `undefined`, `PageContainer` still merges its local partial information with inherited page information.
|
|
|
|
## Managed title target {#managed-target}
|
|
|
|
A layout can give `PagesManager` a DOM container while a page places its title in the external Header through `PageTitlePortal`:
|
|
|
|
```tsx
|
|
function ApplicationLayout() {
|
|
const [titleContainer, setTitleContainer] =
|
|
React.useState<HTMLElement | null>(null)
|
|
|
|
return (
|
|
<PagesManager titleContainer={titleContainer}>
|
|
<header>
|
|
<div ref={setTitleContainer} />
|
|
</header>
|
|
<Outlet />
|
|
</PagesManager>
|
|
)
|
|
}
|
|
|
|
function ProductsPage() {
|
|
return (
|
|
<PageTitlePortal>
|
|
<PageTitle>Products</PageTitle>
|
|
</PageTitlePortal>
|
|
)
|
|
}
|
|
```
|
|
|
|
`titleContainer` accepts an `Element` or `DocumentFragment`. A `PageTitlePortal` may override the manager with its own `container` prop.
|
|
|
|
## Fallback {#fallback}
|
|
|
|
Without an available target, the Portal renders `children` in place by default, so server rendering and the first client render retain the page title. Supply `fallback` to replace the inline content, including `null` to hide it.
|
|
|
|
## Nested managers {#nested-managers}
|
|
|
|
A nested `PagesManager` inherits its parent's `getPageInfo` and title target when they are omitted. Pass `null` as `titleContainer` explicitly to stop title-target inheritance and keep titles in that subtree inline.
|