feat(studio): page titles for logs and observability (#43535)

Stacked PR 3/5 for page title improvements. Includes Logs and
Observability layout title adoption, unified logs title cleanup, and
small route title fixes.

_Base:
[dnywh/feat/page-titles](https://github.com/supabase/supabase/pull/43538)_

---

## What kind of change does this PR introduce?

- Resolves FE-1960
- Resolves FE-1983
- Resolves DEPR-207

## What is the current behavior?

Page titles between surfaces are inconsistent and vague. Sometimes they
say the product name:

```
My Project | My Org | Supabase
```

...even when on a specific surface like Database > Tables.

Other times they show the entity name but skip over the project or org
name :

```
Edge Functions | Supabase
```

## What is the new behavior?

Logs and Observability adopts the layout title format introduced in
https://github.com/supabase/supabase/pull/43538:

```
users | Table Editor | My Project | My Org | Supabase
hello-world | Logs | Edge Functions | My Project | My Org | Supabase
Backups | Database | My Project | My Org | Supabase
Authentication | My Project | My Org | Supabase
```

That format is:

entity, section, surface, project, org, brand.

Also includes unified logs title cleanup, and small route title fixes.

## Additional context

Related stacked PRs also based on the the original
[dnywh/feat/page-titles](https://github.com/supabase/supabase/pull/43538)
branch:

- https://github.com/supabase/supabase/pull/43534
- https://github.com/supabase/supabase/pull/43536
- https://github.com/supabase/supabase/pull/43537

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Danny WhiteandJoshen Lim authored and GitHub committed 2026-03-12 14:08:15 +11:00
1 parent 0fdfd8aaff
commit a753a599ea
12 files changed
+25 -19

No files matched your search

@@ -1,15 +1,14 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { PropsWithChildren } from 'react'
import NoPermission from 'components/ui/NoPermission'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { withAuth } from 'hooks/misc/withAuth'
import { PropsWithChildren } from 'react'
import { ProjectLayout } from '../ProjectLayout'
import { LogsSidebarMenuV2 } from './LogsSidebarMenuV2'
interface LogsLayoutProps {
title?: string
title: string
}
const LogsLayout = ({ title, children }: PropsWithChildren<LogsLayoutProps>) => {
@@ -20,12 +19,14 @@ const LogsLayout = ({ title, children }: PropsWithChildren<LogsLayoutProps>) =>
if (!canUseLogsExplorer) {
if (isLoading) {
return <ProjectLayout isLoading></ProjectLayout>
return (
<ProjectLayout isLoading product="Logs & Analytics" browserTitle={{ section: title }} />
)
}
if (!isLoading && !canUseLogsExplorer) {
return (
<ProjectLayout>
<ProjectLayout product="Logs & Analytics" browserTitle={{ section: title }}>
<NoPermission isFullPage resourceText="access your project's logs" />
</ProjectLayout>
)
@@ -33,7 +34,11 @@ const LogsLayout = ({ title, children }: PropsWithChildren<LogsLayoutProps>) =>
}
return (
<ProjectLayout title={title} product="Logs & Analytics" productMenu={<LogsSidebarMenuV2 />}>
<ProjectLayout
product="Logs & Analytics"
browserTitle={{ section: title }}
productMenu={<LogsSidebarMenuV2 />}
>
{children}
</ProjectLayout>
)
@@ -14,7 +14,7 @@ import { ProjectLayout } from '../ProjectLayout'
import ObservabilityMenu from './ObservabilityMenu'
interface ObservabilityLayoutProps {
title?: string
title: string
}
const ObservabilityLayoutContent = ({
@@ -85,8 +85,8 @@ const ObservabilityLayoutContent = ({
if (reportsAll) {
return (
<ProjectLayout
title={title}
product="Observability"
browserTitle={{ section: title }}
productMenu={<ObservabilityMenu />}
isBlocking={false}
>
@@ -476,7 +476,7 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
LogsExplorerPage.getLayout = (page) => (
<DefaultLayout>
<LogsLayout>{page}</LogsLayout>
<LogsLayout title="Explorer">{page}</LogsLayout>
</DefaultLayout>
)
@@ -61,7 +61,7 @@ export const LogsSavedPage: NextPageWithLayout = () => {
LogsSavedPage.getLayout = (page) => (
<DefaultLayout>
<LogsLayout>{page}</LogsLayout>
<LogsLayout title="Recent">{page}</LogsLayout>
</DefaultLayout>
)
@@ -68,7 +68,7 @@ export const LogsSavedPage: NextPageWithLayout = () => {
LogsSavedPage.getLayout = (page) => (
<DefaultLayout>
<LogsLayout>{page}</LogsLayout>
<LogsLayout title="Saved">{page}</LogsLayout>
</DefaultLayout>
)
@@ -43,7 +43,7 @@ export const LogsTemplatesPage: NextPageWithLayout = () => {
LogsTemplatesPage.getLayout = (page) => (
<DefaultLayout>
<LogsLayout>{page}</LogsLayout>
<LogsLayout title="Templates">{page}</LogsLayout>
</DefaultLayout>
)
@@ -24,7 +24,8 @@ export const LogPage: NextPageWithLayout = () => {
if (isUnifiedLogsEnabled) {
return (
<DefaultLayout>
<ProjectLayout>
{/* Omit the generic product segment here; project/org context already makes the route clear. */}
<ProjectLayout title="Unified Logs">
<UnifiedLogs />
</ProjectLayout>
</DefaultLayout>
@@ -11,7 +11,7 @@ export const LogPage: NextPageWithLayout = () => {
LogPage.getLayout = (page) => (
<DefaultLayout>
<LogsLayout title="Database">{page}</LogsLayout>
<LogsLayout title="Postgres Version Upgrade">{page}</LogsLayout>
</DefaultLayout>
)
@@ -14,7 +14,7 @@ const PageLayout: NextPageWithLayout = () => (
PageLayout.getLayout = (page) => (
<DefaultLayout>
<ObservabilityLayout>{page}</ObservabilityLayout>
<ObservabilityLayout title="Report">{page}</ObservabilityLayout>
</DefaultLayout>
)
@@ -96,7 +96,7 @@ export const UserReportPage: NextPageWithLayout = () => {
UserReportPage.getLayout = (page) => (
<DefaultLayout>
<ObservabilityLayout>{page}</ObservabilityLayout>
<ObservabilityLayout title="Overview">{page}</ObservabilityLayout>
</DefaultLayout>
)
@@ -127,7 +127,7 @@ const QueryPerformanceReport: NextPageWithLayout = () => {
QueryPerformanceReport.getLayout = (page) => (
<DefaultLayout>
<ObservabilityLayout title="Query performance">{page}</ObservabilityLayout>
<ObservabilityLayout title="Query Performance">{page}</ObservabilityLayout>
</DefaultLayout>
)
@@ -196,7 +196,7 @@ export const StorageReport: NextPageWithLayout = () => {
StorageReport.getLayout = (page) => (
<DefaultLayout>
<ObservabilityLayout>{page}</ObservabilityLayout>
<ObservabilityLayout title="Storage">{page}</ObservabilityLayout>
</DefaultLayout>
)