Files
supabase/packages/common/marketplace-client.ts
d23f86021a feat(www): Partner Catalog update (#46757)
## Info architecture change around "Partners"

The www "integrations" now become more partner-driven.
`/partners/integrations` -> now Partner Catalog under
`/partners/catalog` (old links redirect to new paths)

Moved them close together in the nav dropdown and in the footer
<img width="494" height="336" alt="Screenshot 2026-07-09 at 11 06 41"
src="https://github.com/user-attachments/assets/a875fef0-0ab8-47ca-8756-d658b27c4892"
/>
<img width="1149" height="665" alt="Screenshot 2026-07-09 at 11 09 48"
src="https://github.com/user-attachments/assets/9631bb72-fe25-4fb4-b1af-9f14a37d02e7"
/>

## /partners 

This page remains untouched in this PR, updates to layout, content and
intake form are delegated to #47874

## /partners/catalog

Listed in the
[catalog](https://zone-www-dot-com-git-feat-www-partners-pages-supabase.vercel.app/partners/catalog)
are now partners. Some partners match with a listing.

<img width="1207" height="866" alt="Screenshot 2026-07-09 at 11 14 17"
src="https://github.com/user-attachments/assets/b65216be-976f-4ef5-91f8-1ad49da87b45"
/>

## /partners/catalog/[partner]

Each partner can have one or more "listings" which are either 
- simple guides
- foreign data wrappers
- dashboard integrations

Integrations available in the dashboard now all have a prominent
"Install integration" cta to open it in the dashboard [integrations
page](https://supabase.com/dashboard/project/_/integrations).

<img width="1269" height="776" alt="Screenshot 2026-07-09 at 11 16 51"
src="https://github.com/user-attachments/assets/3c7bb715-ffce-4d0a-905f-9a660c3b1f5a"
/>

## Docs

Update docs →
[Preview](https://docs-git-feat-www-partners-pages-supabase.vercel.app/docs/guides/integrations)
- remove "Supabase marketplace"
- use "Dashboard Integrations and Partner Catalog
- update integrations in sidenav to link to updated /partners/catalog/**
listings

<img width="1520" height="696" alt="Screenshot 2026-07-15 at 12 54 47"
src="https://github.com/user-attachments/assets/9f5a2794-4536-4299-97df-9732d3d75b4c"
/>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Partner Catalog experience with search, category filters,
official-partner toggle, responsive filtering (sidebar + bottom sheet),
grid/list views, and featured partners.
* Added Partner Catalog detail pages with tabbed listings, MDX-rendered
content, image gallery with zoom overlay, and “add/install” actions.
* **Improvements**
* Updated “Become a Partner” layout and form support for prefilled
values and checkbox-group fields (including validation).
* Updated navigation/footer/docs and partner tile links to use Partner
Catalog routes; expanded redirects from legacy integrations paths.
  * Added public agent-skills discovery manifest.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alan Daniel <stylesshjs@gmail.com>
Co-authored-by: Alex Hall <alex.hall@supabase.io>
Co-authored-by: Miranda Limonczenko <miranda.limonczenko@supabase.io>
2026-07-15 11:10:51 +00:00

102 lines
3.5 KiB
TypeScript

import { createClient } from '@supabase/supabase-js'
import { MergeDeep } from 'type-fest'
import type { Database as DatabaseGenerated } from './marketplace.types'
export type Category = {
id: string
name: string
slug: string
description: string
}
export type Database = MergeDeep<
DatabaseGenerated,
{
public: {
Views: {
catalog_listings: {
Row: {
// add a type for the JSON structure
categories: Category[]
// These all come from non-nullable columns but all view columns are inferred as nullable.
// See https://github.com/orgs/supabase/discussions/14151
featured: boolean
partner_name: string
built_by: string
slug: string
title: string
description: string
content: string
website_url: string
documentation_url: string
listing_logo: string
published_in_marketplace: boolean
}
}
marketplace_listings: {
Row: {
// add a type for the JSON structure
categories: Category[]
// These all come from non-nullable columns but all view columns are inferred as nullable.
// See https://github.com/orgs/supabase/discussions/14151
featured: boolean
partner_name: string
built_by: string
slug: string
title: string
description: string
content: string
website_url: string
documentation_url: string
listing_logo: string
}
}
}
}
}
>
export type CatalogListing = Database['public']['Views']['catalog_listings']['Row']
export type MarketplaceListing = Database['public']['Views']['marketplace_listings']['Row']
export type Partner = Database['public']['Views']['partners']['Row']
// 'supabase' never gets its own catalog partner page — getPartnerFromMarketplace in
// apps/www/lib/marketplaceDb.ts always 404s on this slug.
export const SUPABASE_PARTNER_SLUG = 'supabase'
// Supabase-owned listings that are remapped to appear as independent partners in the Partner
// Catalog, under a clean, partner-like URL slug (e.g. listing 'bigquery-wrapper' renders at
// /partners/catalog/bigquery). Key = listing DB slug; value = { display name, clean URL slug
// for the catalog page }. Shared so apps/www and apps/docs never drift out of sync.
export const SUPABASE_LISTING_OVERRIDES: Record<string, { name: string; slug: string }> = {
'bigquery-wrapper': { name: 'BigQuery', slug: 'bigquery' },
'firebase-wrapper': { name: 'Firebase', slug: 'firebase' },
'stripe-wrapper': { name: 'Stripe', slug: 'stripe' },
vercel: { name: 'Vercel', slug: 'vercel' },
cyberduck: { name: 'Cyberduck', slug: 'cyberduck' },
}
export const createMarketplaceClient = () => {
const API_URL = process.env.NEXT_PUBLIC_MARKETPLACE_API_URL || ''
const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_MARKETPLACE_PUBLISHABLE_KEY || ''
return createClient<Database>(API_URL, PUBLISHABLE_KEY, {
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
storage: {
getItem: (_key: string) => null,
setItem: (_key: string, _value: string) => {},
removeItem: (_key: string) => {},
},
},
})
}
export const fullImageUrl = (imagePath: string) => {
const API_URL = process.env.NEXT_PUBLIC_MARKETPLACE_API_URL || ''
return `${API_URL}${imagePath}`
}