## What kind of change does this PR introduce?
bug fix for accessibility, fixes
[docs-1280](https://linear.app/supabase/issue/DOCS-1280/projectconfigvariables-label-the-readonly-inputs-and-name)
## What is the current behavior?
the project url and api key fields in `ProjectConfigVariables` have no
associated label, so a screen reader announces an edit field with no
indication of which value it holds
## What is the new behavior?
- associates a `<label>` with each readonly input, so the fields
announce as "project url" and "publishable key"
- names each copy button after the value it copies
- drops `role="combobox"` from the trigger, keeping the `aria-haspopup`,
`aria-expanded` and `aria-controls` radix already supplies
- names the trigger from its content instead of `aria-label`, so it
announces the current selection
- names the shared `CommandInput` reset button and hides its icons
## test
- `pnpm dev:docs`
- `/docs/guides/getting-started/quickstarts/nextjs` (`url` +
`publishable`)
- `/docs/guides/auth/server-side/creating-a-client`, branch selector,
needs a branching-enabled project
- `/docs/guides/observability/log-drains`
- `api_settings` in any getting-started quickstart
## Additional context
reverses part of #49952 as that pr added `aria-label` to satisfy
`button-name`, but did replace the accessible name rather than adding to
it _ the sr-only prefix added here keeps the rule passing and announces
the selection
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Accessibility**
* Improved screen reader support for variable configuration controls,
including clearer labels and copy-status announcements.
* Enhanced combobox and search interactions with accessible labeling,
empty-result announcements, and clearer reset-button names.
* Decorative icons and visual-only messages are now hidden from
assistive technologies.
* **Tests**
* Added accessibility coverage for search input icons and the
clear-search control.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Closes DOCS-1261
_WAVE plugin shows headers creating jumps in hierarchy. Preview on the
left:_
<img width="1022" height="417" alt="Screenshot 2026-07-29 at 2 42 07 PM"
src="https://github.com/user-attachments/assets/f5e3bd09-8dbf-45e3-8a7f-70d7334fd25b"
/>
<img width="408" height="663" alt="Screenshot 2026-07-29 at 2 44 33 PM"
src="https://github.com/user-attachments/assets/6b952a81-40e5-4a9d-b08a-190c71575cac"
/>
## Problem
Four shared components in `apps/docs` render a hardcoded heading tag no
matter where they're used:
- `NamedCodeBlock` renders a code block's filename as an `<h6>`
- `ProjectConfigVariables` renders a variable label as an `<h6>`
- `StepHikeCompact.Details` renders a step title as an `<h3>`
- `IconPanel` renders its title as an `<h5>`
Since these are fixed, they often land in the wrong spot in a page's
heading order (like an h6 right after an h2), which breaks navigation
for screen reader users. This showed up in the [header hierarchy triage
report](https://app.notion.com/p/supabase/Playwright-E2E-Triage-Reports-3ab5004b775f81e3bc60d058fa5a02c1)
— fixing these 4 components alone resolves 72 of the 159 heading-order
violations found.
## Solution
Swapped the heading tag in each component for a `<span>` with the same
classes. None of these are really "headings" for the content that
follows, so they shouldn't be in the tag tree at all.
The one wrinkle: this codebase applies heading font weight/family
through a global CSS rule keyed off the tag name (h1-h6), not something
the tag gives you for free. So each span now sets that styling
explicitly, plus a margin to match what was there before. Nothing else
changed — same classes, same layout.
## Manual testing
Staging preview:
https://docs-git-ui-header-hierarchy-supabase.vercel.app
Check that each one still looks right:
-
[NamedCodeBlock](https://docs-git-ui-header-hierarchy-supabase.vercel.app/docs/guides/self-hosting/docker)
— filenames above the code blocks
-
[ProjectConfigVariables](https://docs-git-ui-header-hierarchy-supabase.vercel.app/docs/guides/auth/quickstarts/react-native)
— the "Project URL" / "Publishable key" labels (this page also has a
`NamedCodeBlock` inside the numbered steps)
-
[StepHikeCompact](https://docs-git-ui-header-hierarchy-supabase.vercel.app/docs/guides/database/beekeeper-studio)
— the step titles ("Create a new connection", etc.)
-
[IconPanel](https://docs-git-ui-header-hierarchy-supabase.vercel.app/docs/guides/resources)
— the "Auth0" / "Firebase Auth" panel titles under "Migrate to Supabase"
I also ran typecheck, lint, and the docs test suite locally — all green.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated headings and labels across documentation and UI components for
more consistent typography.
* Improved spacing, font weight, and block-level layout for project
variables, step details, code tabs, and icon panels.
* Preserved existing text content and conditional display behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
strictNullChecks was off for docs, which lets errors slip through and
leads to incorrect required/optional typing on Zod-inferred types. This
PR enables strictNullChecks and fixes all the existing violations.
* docs: user nav dropdown
* www: user dropdown nav
* update menus
* chore: add complete local storage allowlist
* move all local-storage to common
* reload after logOut
* add local storage key changes from #35175
* fix errors
* add more keys
* fix merge bugs
---------
Co-authored-by: Alaister Young <a@alaisteryoung.com>
* feat(docs): fetch conn string
Add option to ProjectConfigVariables to fetch the Supavisor session mode connection string, for setting up MCP server
* docs(mcp): reminder to replace password placeholder in connection string
* fix: display helpful message if project paused
---------
Co-authored-by: Greg Richardson <greg.nmr@gmail.com>
The endpoint may successfully return data that isn't valid as a project API endpoint/anon key. I added a check to make sure the endpoint exists and the anon key isn't a known error string before displaying it.