import {createContext, useContext, useEffect, useMemo} from 'react'; type Props = { children?: React.ReactNode; /** * Should the ` - Sentry` suffix be excluded? */ noSuffix?: boolean; /** * The organization slug to show in the title */ orgSlug?: string; /** * The project slug to show in the title. */ projectSlug?: string; /** * This string will be shown at the very front of the title */ title?: string; }; const DEFAULT_PAGE_TITLE = 'Sentry'; const DocumentTitleContext = createContext(DEFAULT_PAGE_TITLE); /** * Assigns the document title. The deepest nested version of this title will be * the one which is assigned. */ function SentryDocumentTitle({ title = '', orgSlug, projectSlug, noSuffix, children, }: Props) { const parentTitle = useContext(DocumentTitleContext); const pageTitle = useMemo(() => { if (orgSlug && projectSlug) { return `${title} - ${orgSlug} - ${projectSlug}`; } if (orgSlug) { return `${title} - ${orgSlug}`; } if (projectSlug) { return `${title} - ${projectSlug}`; } return title; }, [orgSlug, projectSlug, title]); const documentTitle = useMemo(() => { if (noSuffix) { return pageTitle; } if (pageTitle !== '') { return `${pageTitle} - Sentry`; } return DEFAULT_PAGE_TITLE; }, [noSuffix, pageTitle]); // NOTE: We do this OUTSIDE of a use effect so that the update order is // correct, otherwsie the inner most SentryDocumentTitle will have it's // useEffect called first followed by the parents, which will cause the wrong // title be set. if (document.title !== documentTitle) { document.title = documentTitle; } useEffect(() => { return () => { document.title = parentTitle; }; }, [parentTitle]); return ( {children} ); } export default SentryDocumentTitle;