Files
e0280cb650 docs: restructure observability navigation and overview (#49505)
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## Stack

Draft stack extracted from `docs/monitoring`. Merge bottom-up. The
troubleshooting *catalog* rewrite (`content/troubleshooting` and the
Diagnosing UI) stays out of scope.

1. #49503 move inspect and advisors
2. #49501 split Studio logs from ClickHouse queries
3. #49500 treat reports as signal dashboards
4. #49502 add Observe the data hub
5. #49506 add agent setup components
6. #49504 add hire-an-agent templates
7. **#49505** restructure observability nav, overview, Detecting, and
flatten Observe the data ← **this PR**

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Docs update. Top layer in the observability stack.

## What is the current behavior?

The section is still titled Monitoring and Debugging, with a Debugging /
Monitoring split that does not match the new pages. The debugging guide
is still the master layer-isolation + symptom table. Observe the data is
split into “what data” vs “where to observe it,” which duplicates the
source pages.

## What is the new behavior?

- Section title is Observability
- Overview groups Observe the data, Detect and resolve, Hire an agent,
and Export
- **Observe the data is flattened by source.** Logs, Metrics API,
Database, Advisors, and Reports each list where to read that source.
There is no separate MCP/API/CLI/Studio nav group.
- **Observe vs Detecting:** Observe is the catalog (what exists, how to
access it). Detecting is how to *use* those sources to pick up a Health
/ Security / Performance / Usage signal. Named errors skip to
Diagnosing.
- Studio Logs sits under Logs. Reports sits beside the other sources.
- Troubleshooting stays in the global menu and also appears as
Diagnosing under Detect and resolve

## Additional context

This is the last PR in the stack. Together the seven PRs reconstruct the
`docs/monitoring` observability IA and guide content, without shipping
the troubleshooting catalog overhaul.
<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-a3cb5ece-925b-4046-b58a-5d69e9a9d794&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Saxon Fletcher <SaxonF@users.noreply.github.com>
Co-authored-by: Nik Richers <nik@validmind.ai>
2026-09-04 13:38:39 +10:00
..
2026-07-01 12:59:00 +02:00
2026-08-27 12:45:28 +01:00

supabase.com

Overview

Refer to the Development Guide to learn how to run this site locally.

To get started copy the example env file using cp .env.local.example .env.local.

Best practices

Images

  • Resize images: All new images should be resized to only the maximum resolution needed when rendering on the frontend. Don't upload images larger than what will be displayed.
  • Compress images: All new images should be compressed before committing. Use tools like Clop or ImageOptim to reduce file size without noticeable quality loss.
  • Image locations: Store blog post images in apps/www/public/images/blog/. Event images go in apps/www/public/images/events/. Customer logos go in apps/www/public/images/customers/logos/on-light/ and on-dark/ (see Customer Stories below).

OG image generation

Open Graph (OG) images for social sharing are handled differently across content types:

  • Blog posts: Use static images via imgSocial and imgThumb fields (see Blog posts section below)
  • Events: Use dynamic generation via Edge Function (with optional og_image override)
  • Customer stories: Use dynamic generation via Edge Function (no static option)

The og-images Edge Function (supabase/functions/og-images/) automatically generates OG images for events and customer stories. It's deployed via .github/workflows/og_images.yml when changes are made to the function code.

Development: In local development, the function runs at http://127.0.0.1:54321/functions/v1/og-images. Ensure Supabase is running locally (supabase start).

Content frontmatter image fields

Different content types use different image field conventions:

Blog posts

Blog posts support two image fields in their frontmatter:

  • imgSocial: Used for Open Graph and social media sharing (X, LinkedIn, etc.). These images should include text overlays since they appear standalone in social feeds without accompanying text.
  • imgThumb: Used for internal thumbnails displayed on the blog listing pages and featured posts. These images don't need text overlays since they're always displayed alongside the post title and description.

This naming convention was introduced to replace the previously confusing thumb and og fields, which were often mixed up. The new names clearly indicate:

  • imgSocial: Purpose-built for social media sharing (needs text overlays)
  • imgThumb: Optimized for site display (clean, no text overlays)

This separation allows you to optimize images for their specific use case while maintaining a clear, unambiguous naming convention.

Image path format

Always use relative paths (just the filename or subfolder/filename). The /images/blog/ prefix is added automatically by the code.

  • ✅ Correct: imgSocial: my-post/og.png or imgSocial: og.png
  • ❌ Wrong: imgSocial: /images/blog/my-post/og.png (creates double prefix)

Image fallback behavior

For site display (what visitors see):

  • Priority 1: imgThumb
  • Priority 2: imgSocial (if imgThumb is missing)
  • Priority 3: /images/blog/blog-placeholder.png (if both missing)

For social sharing (Open Graph meta tags):

  • Priority 1: imgSocial
  • Priority 2: imgThumb (if imgSocial is missing)
  • Priority 3: No fallback (undefined)

What happens if fields are not provided?

  • If only imgThumb is provided: Site displays the image correctly, social sharing uses imgThumb as fallback
  • If only imgSocial is provided: Social sharing uses it, site display uses it as fallback
  • If neither is provided: Site shows placeholder image, social sharing has no image
  • Best practice: Provide both fields for optimal display and social sharing

Example

---
title: 'My Blog Post'
imgSocial: 2025-01-01-my-post/og.png # Relative path - with text overlay for social sharing
imgThumb: 2025-01-01-my-post/thumb.png # Relative path - without text, clean image
---

The images would be stored at:

  • apps/www/public/images/blog/2025-01-01-my-post/og.png
  • apps/www/public/images/blog/2025-01-01-my-post/thumb.png

Or if using the same image for both:

---
title: 'My Blog Post'
imgSocial: my-image.png # Stored at: apps/www/public/images/blog/my-image.png
imgThumb: my-image.png
---

Events

Events use different image fields to avoid confusion with their display patterns:

  • thumb: Used for event grid item thumbnails (small cards in listing)
  • cover_url: Used for the featured event banner (large display on events page)
  • og_image (optional): Used to override the dynamically generated OG image for social sharing

OG image generation

Events automatically generate Open Graph images using the og-images Supabase Edge Function. The function creates images dynamically based on:

  • Event type (conference, hackathon, etc.)
  • Title (or meta_title if provided)
  • Description (or meta_description if provided)
  • Date (formatted as "DD MMM YYYY" using the event's timezone)
  • Duration (if provided)

If you need a custom OG image that differs from the auto-generated one, you can provide an og_image field in the frontmatter. This will override the dynamic generation.

Example:

---
title: 'Supabase Meetup'
thumb: /images/events/2025-01-meetup/thumbnail.png
cover_url: https://external-cdn.com/event-banner.jpg
og_image: /images/events/2025-01-meetup/custom-og.png # Optional override
---

Note: The og_image field is optional. If not provided, OG images are generated automatically via the Edge Function.

End-to-end checks

Content pages are loaded and scanned with axe-core by the Playwright suite in e2e/www. Pull requests test the pages your change affects. Today the suite enforces one accessibility rule, page-has-heading-one.

To test the pages your current branch changes:

PLAYWRIGHT_BASE_URL=https://supabase.com pnpm e2e:www

That resolves which pages to test from your branch, but reads them from production, so it won't see your edits and will 404 on a page you just added. Point PLAYWRIGHT_BASE_URL at your pull request's preview to test your own content.

See e2e/www/README.md for coverage and limits.

Go pages (/go/*)

/go/ is a system for building standalone campaign landing pages (lead generation, legal, thank-you flows). The name is intentionally generic — these pages are typically linked from ads, emails, or partner campaigns and are not part of the main site navigation.

Pages are defined as TypeScript objects (not MDX files) and validated against Zod schemas at build time.

Parts

Location Purpose
apps/www/_go/ Page definitions. Each file exports a page object. index.tsx registers all pages.
apps/www/app/go/[slug]/page.tsx App Router route — renders the page for a given slug, handles 404s and metadata.
apps/www/components/Go/GoPageRenderer.tsx www-specific wrapper — adds the Supabase logo header and footer, registers custom section renderers.
packages/marketing/src/go/ Framework-agnostic core: schemas, section components, templates, form server action.
packages/marketing/src/crm/ CRM client abstraction (HubSpot + Customer.io) used by the form server action.

Page structure

Each page specifies a template which determines its top-level layout:

  • lead-gen — hero + arbitrary sections (form, metrics, feature grid, tweets, social proof, etc.)
  • thank-you — hero + sections + confetti animation
  • legal — hero + table-of-contents sidebar + markdown body

Pages are arrays of typed section objects. The SectionRenderer in packages/marketing dispatches each section to the right component based on its type field.

Custom renderers

The marketing package doesn't know about topTweets data or the Pages Router basePath, so the tweets section type has no default renderer. GoPageRenderer.tsx in www registers TweetsSection as a custom renderer for that type. This is the extension point for any section that requires www-specific dependencies.

Adding a new page

  1. Create a new file in apps/www/_go/<category>/my-page.tsx exporting a page object.
  2. Register it in apps/www/_go/index.tsx.
  3. The page will be available at /go/<slug> automatically via static generation.

Customer Stories (Case Studies)

Customer stories are defined in MDX files (apps/www/_customers/*.mdx) and use a different approach:

  • No og_image field: Customer stories do NOT use static OG images
  • Dynamic OG generation: All customer story OG images are automatically generated using the og-images Supabase Edge Function
  • The function creates images based on the customer slug and title (or meta_title if provided)

Do not include an og_image field in customer story frontmatter. It will be ignored. OG images are always generated dynamically.

Logos

Customer logos are monochrome and transparent. Prefer SVG; PNG is also fine. Put each theme variant in the folder named for the background it sits on:

Folder Mark Frontmatter Shown in
/images/customers/logos/on-light/ Dark/black logo Light mode
/images/customers/logos/on-dark/ Light/white logo_inverse Dark mode

Do not use coloured brand marks. Preview /customers in both themes before merging.

Icon-only assets (homepage chips, etc.) stay at /images/customers/logos/{slug}-icon.svg.

Customer story OG images are generated by the og-images Edge Function, which fetches https://supabase.com/images/customers/logos/on-dark/{slug}.png. Satori cannot rasterise SVG, so stories still need an on-dark/{slug}.png even if the site uses SVG.

Example (in apps/www/_customers/company-abc.mdx):

---
name: Company ABC
title: Company ABC built their platform with Supabase
# DO NOT include og_image - it's generated automatically
logo: /images/customers/logos/on-light/company-abc.svg
logo_inverse: /images/customers/logos/on-dark/company-abc.svg
---

Legacy Case Studies (in data/CustomerStories.ts):

  • imgUrl: Path to the case study image in the source data
  • This gets mapped to imgThumb when rendered via BlogGridItem component
  • Case studies only need one image for site display (no separate social sharing image)

Example (in data/CustomerStories.ts):

{
  type: 'Customer Story',
  title: 'Company ABC built their platform with Supabase',
  description: '...',
  organization: 'Company ABC',
  imgUrl: 'images/customers/logos/on-light/company-abc.svg', // Full path from public/
  logo: '/images/customers/logos/on-light/company-abc.svg',
  logo_inverse: '/images/customers/logos/on-dark/company-abc.svg',
  url: '/customers/company-abc',
}