Skip to main content

Overview

Static sitemaps work for simple sites, but if your app has dynamic content (blog posts, products, user profiles), you need a sitemap that updates automatically. This guide shows you how to create a dynamic sitemap using Supabase Edge Functions in your Lovable project — no manual coding required. Just paste one of the prompts below into Lovable and customize the placeholders.

When You Need a Dynamic Sitemap

  • Blog or content site with new posts
  • E-commerce with product pages
  • Directory or listing site
  • Any app where pages are created from database records

Prerequisites

  • A Lovable project connected to Supabase

Step 1: Choose the Right Prompt

Pick the prompt that best matches your site, then customize the placeholders (marked with [BRACKETS]) before pasting it into Lovable.

Static-Only Sitemap (no database content)

Use this if your site has no database-driven pages — just fixed routes like /about, /pricing, etc.
Create a static sitemap.xml file for my site that has no database-dependent pages. Include:

1. A sitemap.xml file at the public root directory containing:
   - All public pages with their full canonical URLs using [YOUR_DOMAIN]
   - Appropriate lastmod dates (use today's date or actual last modified)
   - changefreq values (daily for homepage, weekly for main pages, monthly for static content)
   - priority values (1.0 for homepage, 0.8 for main sections, 0.6 for subpages)

2. These pages:
   - Homepage (/)
   - [List all your static pages, e.g., /about, /pricing, /contact, /features, /blog]

3. Proper XML structure with:
   - XML declaration
   - urlset with xmlns namespace
   - Properly escaped URLs

Make sure the sitemap validates against the sitemap protocol specification.
Use this if your site has static pages and some dynamic content from Supabase (under 1,000 items per entity).
Create a sitemap system for my site that has both static pages and some dynamic
content from Supabase, but not enough to require pagination (under 1000 items
per entity).

1. Create an edge function at /functions/v1/sitemap that:
   - Fetches all dynamic entities from Supabase in a single query per entity
   - Combines with hardcoded static page URLs
   - Returns complete sitemap XML
   - Caches the response for 1 hour
   - Uses canonical domain: [YOUR_DOMAIN]

2. Include static pages:
   - [List your static pages, e.g., /, /about, /pricing, /contact]

3. Include dynamic entities:
   - [List your dynamic routes, e.g., blog posts at /blog/[slug]]

4. For each URL include:
   - loc (full canonical URL)
   - lastmod (from database updated_at or static date)
   - changefreq (based on content type)
   - priority (based on page importance)

5. Create a static sitemap.xml in public/ using <sitemapindex> that references the edge function URL
Use this if you have 1,000+ records across your entity types (up to 50,000 total URLs).
Create a single Supabase edge function at /functions/v1/sitemap that returns
a complete sitemap with all URLs (up to 50,000). Requirements:

1. The edge function should:
   - Query all dynamic entities from Supabase
   - Combine with hardcoded static page URLs
   - Return a single <urlset> XML document with all URLs
   - Include proper lastmod dates from updated_at columns
   - Set appropriate changefreq and priority values
   - Cache the response for 1 hour
   - Return proper XML content-type header
   - Use the canonical domain: [YOUR_DOMAIN]

2. Include static pages:
   - [List your static pages, e.g., /, /about, /pricing, /contact]

3. Include these dynamic entity types:
   - [List your entities, e.g., /blog/[slug], /products/[id], /users/[username]]

4. Ensure the total URL count stays under 50,000 (the sitemap protocol limit)

5. Create a static sitemap.xml in public/ using <sitemapindex> that references the edge function URL
Use this if your total URL count exceeds 50,000 and you need paginated sub-sitemaps.
Create a Supabase edge function at /functions/v1/sitemap that returns a
<sitemapindex> XML document listing paginated sub-sitemap URLs. Requirements:

1. The /functions/v1/sitemap edge function should:
   - Query entity counts from Supabase to determine pagination
   - Return a <sitemapindex> listing sub-sitemap URLs like:
     /functions/v1/sitemap-posts?page=1, /functions/v1/sitemap-posts?page=2, etc.
   - Include one entry per entity type per page (1000 URLs per page)
   - Cache the response for 1 hour
   - Return proper XML content-type header

2. For each entity type, create a separate edge function (e.g., /functions/v1/sitemap-posts) that:
   - Accepts a ?page=N query parameter
   - Queries Supabase for that batch of 1000 records
   - Returns a <urlset> XML document with those URLs
   - Includes proper lastmod dates from updated_at columns
   - Sets appropriate changefreq and priority values
   - Uses the canonical domain: [YOUR_DOMAIN]

3. Include these entity types:
   - [List your entities, e.g., /blog/[slug], /products/[id], /users/[username]]

4. Create a static sitemap.xml in public/ using <sitemapindex> that references
   the /functions/v1/sitemap edge function URL
Google only follows one level of nesting in sitemap indexes. Since your static sitemap.xml is a <sitemapindex> pointing to another <sitemapindex> (the edge function), Google won’t discover the paginated sub-sitemaps. You must proxy /sitemap.xml to your /functions/v1/sitemap edge function using Hado SEO’s routing rules (see Step 3 below) so that Google sees the paginated sub-sitemaps directly.
Replace all [BRACKETS] with your actual values before pasting into Lovable. For example, replace [YOUR_DOMAIN] with https://myapp.com and list your real pages and entity types.

Step 2: Verify the Edge Function

After Lovable generates and deploys the code, verify it’s working:
  1. Open your app’s sitemap.xml and confirm all static URLs or edge function URLs are listed
  2. Visit each edge function URL in the sitemap index — each one should return valid XML with your pages

Step 3: Proxy the Sitemap Through Your Domain

Search engines prefer sitemaps served from your own domain. Use Hado SEO’s routing rules to proxy /sitemap.xml to your Supabase Edge Function — no code changes needed.
1

Open Routing Rules

In your Hado SEO Dashboard, select your domain and go to the Routing Rules tab.
2

Add a proxy rule

Click Add Rule and configure:
FieldValue
Rule TypeProxy
Source Path/sitemap.xml
Target URLhttps://YOUR_PROJECT_REF.supabase.co/functions/v1/sitemap
Priority10
3

Verify

Visit https://yourdomain.com/sitemap.xml in your browser. You should see the XML output from your Supabase function, served from your own domain.
Routing rules are processed by Hado SEO’s proxy before your app is hit. The request is forwarded to your Supabase function and the response is returned under your domain — visitors and search engines see yourdomain.com/sitemap.xml. Learn more in the Routing Rules documentation.

Step 4: Test Your Sitemap

Browser Test

Visit your sitemap URL. You should see properly formatted XML.

Google Search Console

  1. Go to Google Search Console
  2. Navigate to Sitemaps
  3. Submit your sitemap URL
  4. Check for any errors

Sitemap Best Practices

Google limits sitemaps to 50,000 URLs or 50MB. For larger sites, use the Backend Function Sitemap prompt above, which generates a sitemap index with paginated sub-sitemaps.
Only update lastmod when content actually changes. Google may ignore sitemaps that update lastmod without real changes.
Don’t include:
  • Pages blocked by robots.txt
  • Pages with noindex meta tag
  • Redirect URLs
  • Login-required pages
Encode special characters in URLs:
  • & becomes &amp;
  • < becomes &lt;
  • > becomes &gt;
  • " becomes &quot;
  • ' becomes &apos;

Next Steps