## Problem
After merging [#48456](https://github.com/supabase/supabase/pull/48456)
(shared components) and
[#48459](https://github.com/supabase/supabase/pull/48459) (per-page
content fixes), a follow-up diagnostic pass found 22 remaining
heading-order violations, logged as Pass 2 in the [triage
report](https://app.notion.com/p/supabase/Playwright-E2E-Triage-Reports-3ab5004b775f81e3bc60d058fa5a02c1).
None of them were caught by the earlier fixes because they came from
places that scan didn't check: shared partials, raw HTML heading tags
written directly in MDX, and a couple of shared/interactive components
rendering hardcoded heading levels.
## Solution
- `_partials/social_provider_setup.mdx`: `#### Local development` →
`###`, matching the `##` that always precedes it on all 14 social-login
pages.
- `guides/database/functions.mdx` and
`guides/integrations/vercel-marketplace.mdx`: replaced raw `<h4>`/`<h5>`
tags with correctly-nested real headings (`### Planets`/`### People`;
`#### Deploy a Next.js app...`) — no styling workarounds needed since
they nest naturally one level below their parent section.
- `auth/quickstarts/{nextjs,react-native,react,astrojs}.mdx`: these 4
pages had no heading at all before the embedded
`_partials/api_settings.mdx` partial's own `### Get API details`
heading, so added a `## Quickstart` heading above the walkthrough to
give it a valid parent.
- `packages/ui`'s `Accordion` component: Radix's
`AccordionPrimitive.Header` renders as an unconditional `<h3>`
regardless of where the accordion is used. That's shared across Studio,
www, and design-system, not just docs, and surfaced on docs'
vendor-agnostic telemetry page. Now rendered via `asChild` onto a plain
`div` instead, since a generic accordion has no way to know what heading
level (if any) is valid in a given page.
- SQL-to-REST translator tool (`/docs/guides/api/sql-to-rest`): its
`Assumptions`/`FAQs` section labels were hardcoded `<h3>` with no `h2`
anywhere on the page. Converted to styled spans rather than promoting to
a real `<h2>`, because real h1/h2/h3 tags in this codebase force a prose
font-size that utility classes can't override — promoting the tag would
have visibly changed its size.
- `RealtimeLimitsEstimator` (embedded on both `postgres-changes` and
`benchmarks`): its 3 section headings were hardcoded `<h4>`, but the two
embedding pages need different levels (h3 vs h4) for that spot to be
valid — no single correct heading level. Converted to styled spans, same
pattern used throughout this project for components embedded at varying
heading depths.
## Manual testing
1. Check out this branch and run `pnpm dev:docs`.
2. Visit `/docs/guides/auth/social-login/auth-github` (or any other
provider page) and confirm the "Local development" callout under "Find
your callback URL" still looks and reads the same.
3. Visit `/docs/guides/database/functions` → "Returning data sets" tab
and confirm the "Planets" / "People" table captions still look the same.
4. Visit `/docs/guides/integrations/vercel-marketplace` → "Quickstart" →
"Via template" and confirm the CTA card title still looks the same.
5. Visit `/docs/guides/auth/quickstarts/nextjs` (or
react-native/react/astrojs) and confirm a "Quickstart" heading now
appears above the walkthrough, and "Get API details" still renders
correctly further down.
6. Run `pnpm dev:design-system` and open
`/design-system/docs/components/accordion` — expand/collapse an item and
confirm it still animates and looks identical; inspect the DOM and
confirm the trigger's wrapper is a `div`, not an `h3`.
7. Visit `/docs/guides/api/sql-to-rest`, translate any query, and
confirm the "Assumptions"/"FAQs" section labels still look the same.
8. Visit `/docs/guides/realtime/postgres-changes` and
`/docs/guides/realtime/benchmarks`, scroll to the connection-limits
calculator, and confirm its section labels still look the same on both
pages.
9. (Optional, for a full re-check) Run `pnpm e2e:docs:a11y --all`
against a deployed preview of this branch — only `/docs/guides/cli`
(pre-existing 404, unrelated to headings) should fail; every other page
should pass.
Verified with a full Playwright run against a real preview deployment:
**756 passed, 1 failed** (`/docs/guides/cli`, the pre-existing unrelated
404). Zero heading-order violations remain.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Added clearly labeled Quickstart sections to Astro, Next.js, React
Native, and React authentication guides.
- Improved heading hierarchy and formatting across social provider
setup, database functions, and deployment documentation.
- Updated estimator and SQL-to-REST section presentation for more
consistent content structure.
- **Bug Fixes**
- Improved accordion trigger layout while preserving existing behavior,
styling, accessibility, and icon display.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* docs(auth): clarify local OAuth callback URLs for Azure, Google, and LinkedIn
* docs: add local OAuth callback instructions to shared social provider setup
* fix: rewrite relative URLs when syncing to GitHub discussion
Relative URLs back to supabse.com won't work in GitHub discussions, so
rewrite them back to absolute URLs starting with https://supabase.com
* fix: replace all supabase urls with relative urls
* chore: add linting for relative urls
* chore: bump linter version
* Prettier
---------
Co-authored-by: Chris Chinchilla <chris.ward@supabase.io>
Partials are currently defined via MDX includes. This PR switches to pre-compile-time partials, which have a new syntax:
```
<$Partial path="path/to/file.mdx" />
```
## Rationale
This produces two improvements:
1. Partial substitution can occur in pipelines that don't use MDX compilation. For example, we can now do partial substitution before building the search index, so partial content will also be indexed.
2. After the App Router migration, the MDXProviders should've been deprecated, but were kept around for the sole reason of making partials work, and leading to us shipping unnecessary client-side code. We get a minor decrease in overall client bundle size (5.74 MB to 5.6 MB) by getting rid of the Providers.
## Breaking changes
Besides the change to partial syntax, the arguments are also less powerful than before because we are doing string substitution and don't have the full power of JS. Defining string variables is still possible (documented in the Contributing guide), and since that's all we actually do in practice, this shouldn't be too cumbersome. There is always the escape hatch of making a custom component for more complex content reuse cases.