Page title generator on browser tab rebuilded.
This commit is contained in:
@@ -22,6 +22,7 @@ export type PageMetadata = {
|
||||
locale?: string
|
||||
title: string
|
||||
}
|
||||
/** robots directives — set to noindex/follow for legal/thin/search pages. */
|
||||
robots?: {
|
||||
follow: boolean
|
||||
index: boolean
|
||||
@@ -43,6 +44,13 @@ type BuildMetadataArgs = {
|
||||
meta?: null | SeoMeta
|
||||
/** Page title or site name first. Defaults to 'page-first'. */
|
||||
order?: TitleOrder
|
||||
/**
|
||||
* The document's own title (e.g. page.title = 'Sprzątanie biur'). Used as the
|
||||
* page-title source when meta.title is empty — the browser tab and search
|
||||
* result should show the page name, not go blank, when an editor didn't fill
|
||||
* the SEO title. Priority: titleOverride > meta.title > pageTitle.
|
||||
*/
|
||||
pageTitle?: null | string
|
||||
/**
|
||||
* Localized segment the document lives under (an archive page's slugs).
|
||||
* Feeds both canonical and hreflang, so /pl/artykuly/moj-post and
|
||||
@@ -82,16 +90,21 @@ export function buildMetadata({
|
||||
locale,
|
||||
meta,
|
||||
order,
|
||||
pageTitle,
|
||||
prefix,
|
||||
query,
|
||||
separator,
|
||||
siteName,
|
||||
slugs,
|
||||
}: BuildMetadataArgs): PageMetadata {
|
||||
// titleOverride wins outright: an editor who filled it in wants that exact
|
||||
// string in the tab, not a composition.
|
||||
// Title source priority: titleOverride (exact, wins outright) > meta.title
|
||||
// (SEO title an editor set) > pageTitle (the document's own name). This means
|
||||
// a page with no SEO title still shows its name (e.g. 'Sprzątanie biur')
|
||||
// composed with the site name, instead of just the site name or a blank.
|
||||
const override = meta?.titleOverride?.trim()
|
||||
const title = override || composeTitle({ order, pageTitle: meta?.title, separator, siteName })
|
||||
const resolvedPageTitle = meta?.title?.trim() || pageTitle?.trim() || undefined
|
||||
const title =
|
||||
override || composeTitle({ order, pageTitle: resolvedPageTitle, separator, siteName })
|
||||
const description = meta?.description?.trim() || undefined
|
||||
const origin = baseUrl?.replace(/\/$/, '') ?? ''
|
||||
|
||||
@@ -116,12 +129,14 @@ export function buildMetadata({
|
||||
...(canonical && { canonical }),
|
||||
...(Object.keys(languages).length > 0 && { languages }),
|
||||
},
|
||||
...(meta?.noindex ? { robots: { follow: true, index: false } } : {}),
|
||||
openGraph: {
|
||||
title,
|
||||
...(description && { description }),
|
||||
...(images && { images }),
|
||||
locale,
|
||||
},
|
||||
// noindex → tell search engines to exclude the page but still follow links
|
||||
// (authority flows through). For legal/thin/search-result pages.
|
||||
...(meta?.noindex ? { robots: { follow: true, index: false } } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ type PageMetadataContext = {
|
||||
type DocShape = {
|
||||
id: number | string
|
||||
meta?: null | SeoMeta
|
||||
/** The document's own title (page name), used as the fallback page title. */
|
||||
title?: null | string
|
||||
}
|
||||
|
||||
/** plugin-seo stores the OG image as an upload relationship. */
|
||||
@@ -151,6 +153,7 @@ export function createPageMetadata(args: CreatePageMetadataArgs) {
|
||||
...base,
|
||||
imageUrl: resolveOgImage(doc),
|
||||
meta: doc.meta,
|
||||
pageTitle: doc.title,
|
||||
prefix,
|
||||
query,
|
||||
slugs,
|
||||
|
||||
Reference in New Issue
Block a user