14:04WeWeb + Supabase: Collection pages, dynamic collections, and SEO metadata binding

Hi WeWeb team,

I’m building a club website with WeWeb + Supabase and have two use cases involving dynamic content, SEO metadata, and collection pages. I’ve found this area quite confusing and your documentation doesn’t seem to cover the Supabase plugin scenario in detail. I’d love some feedback on whether my approach is correct or if there’s a better way.


Use case 1: Flying Sites (working, but want to confirm it’s correct)

I have a Sites listing page and a SiteDetail collection page. Sites change very rarely (~10 sites, maybe one added per year). It’s important to SEO and to have a fixed url.

My setup:

  • SiteDetail is a collection page driven by a single static REST API collection pulling from a Supabase view (site_with_detail)
  • All page content AND SEO metadata (title tag, meta description, OG fields) are bound to context.page.data from the static collection
  • The Sites listing page also uses this same static collection to render the grid
  • No dynamic collection is used anywhere for sites

This works correctly — metadata binds fine, navigation works, pages pre-render. Is this the right approach? Are there any downsides I’m missing? My concern is that updates won’t propagate unless i redeploy - is that correct?


Use case 2: Learning Articles (problematic)

I have a Learning listing page (all articles) and a LearningArticle page. Articles are added more frequently and I want new articles to appear immediately without a redeploy. I also have filtering on the listing grid. A fixed URL is crucial, SEO is helpful but not available (I think) with the approach below.

What I tried first:

  • LearningArticle as a collection page with a static REST API collection (for SEO metadata + slug enumeration) and a separate dynamic Supabase collection (for page content, filtered by slug)
  • Listing page linked to LearningArticle via “Link to collection page”

The problem: clicking an article on the listing page opened the wrong article. The listing grid uses the dynamic collection (so new articles appear immediately), but “link to collection page” matches by position against the static collection — and when the listing has filters applied, the position in the dynamic list no longer matches the position in the static list. This seems like a fundamental mismatch.

What I’ve ended up with:

  • LearningArticle as a normal page (not a collection page) with a slug passed as a query parameter from the listing
  • A single dynamic Supabase collection on LearningArticle filtered by pageParameters['slug']
  • Static title and no bound metadata, because the metadata binding panel only shows static collections

This works for navigation and content, but I’ve lost SEO metadata binding on individual article pages.


Your documentation shows an approach using an API call alternative backend which doesnt work with Supabase (I think) because supabase is fixed to dynamic in weweb. I think i am effectively doing the same with the REST API call.

My questions:

  1. Is there a supported pattern for having a collection page where the listing uses a dynamic collection (so new items appear immediately and filtering works), while the collection page itself still gets pre-rendered with correct SEO metadata?

  2. Is there a way to bind page metadata (title tag, meta description) to a dynamic collection or page parameter on a collection page? The binding picker in the metadata panel only shows static collections.

  3. For Use Case 1 (sites), is it correct/safe to use the same static collection for both the listing page and as the collection page driver — or is there a reason to separate them?

This feels like a pretty standard CMS-style pattern (listing page → detail page with SEO) and I’m surprised there isn’t clearer guidance for it. Any help appreciated!

Thanks

Hi Fraser,

Joyce from the WeWeb Team actually mentioned this exact problem to me a few days ago. She pointed out that metadata on dynamic pages is one of the biggest pain points for self-hosting users right now, and after reading your post, I can see why.

I ended up building a small open-source tool that solves this. It’s called @mel000000/weweb-dynamic-metadata , basically a build-time script that generates unique metadata files for each dynamic page by pulling data directly from Supabase.

For your article use case, it would let you keep using dynamic collections (so new articles appear instantly and filtering works), but still get proper SEO metadata on each article page. The script runs during build, creates a central metadata file, and injects it into your pages - so crawlers see unique titles, descriptions, etc. for every article.

Setup is pretty simple:

npm install --save-dev @mel000000/weweb-dynamic-metadata

Then create a config file that points to your Supabase table:

export default { 
supabase: {
    url: process.env.SUPABASE_URL,
    anonKey: process.env.SUPABASE_ANON_KEY
  },
  pages: [
    {
      route: "/learning/:id",
      table: "articles",
      metadata: {
        title: "title",
        content: "excerpt"
      }
    }
  ]
}

You then just have to let it run after your builds.

For your sites use case you’re right that static collections work but require redeploys when data changes. The same tool would automate that by fetching the latest data from Supabase during each build.

The project is on GitHub if you want to take a look: github.com/Mel000000/weweb-dynamic-metadata

Curious if this matches what you’re looking for. Happy to help if you run into any issues setting it up.

2 Likes